📄 mips.md
字号:
(define_insn "*macc2" [(set (match_operand:SI 0 "register_operand" "=l") (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "register_operand" "d")) (match_dup 0))) (set (match_operand:SI 3 "register_operand" "=d") (plus:SI (mult:SI (match_dup 1) (match_dup 2)) (match_dup 0))) (clobber (match_scratch:SI 4 "=h"))] "ISA_HAS_MACC && reload_completed" "macc\t%3,%1,%2" [(set_attr "type" "imadd") (set_attr "mode" "SI")])(define_insn "*msac2" [(set (match_operand:SI 0 "register_operand" "=l") (minus:SI (match_dup 0) (mult:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "register_operand" "d")))) (set (match_operand:SI 3 "register_operand" "=d") (minus:SI (match_dup 0) (mult:SI (match_dup 1) (match_dup 2)))) (clobber (match_scratch:SI 4 "=h"))] "ISA_HAS_MSAC && reload_completed" "msac\t%3,%1,%2" [(set_attr "type" "imadd") (set_attr "mode" "SI")]);; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>;; Similarly msac.;;;; Operand 0: LO;; Operand 1: macc/msac;; Operand 2: HI;; Operand 3: GPR (destination)(define_peephole2 [(parallel [(set (match_operand:SI 0 "register_operand") (match_operand:SI 1 "macc_msac_operand")) (clobber (match_operand:SI 2 "register_operand")) (clobber (scratch:SI))]) (set (match_operand:SI 3 "register_operand") (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))] "" [(parallel [(set (match_dup 0) (match_dup 1)) (set (match_dup 3) (match_dup 1)) (clobber (match_dup 2))])] "");; When we have a three-address multiplication instruction, it should;; be faster to do a separate multiply and add, rather than moving;; something into LO in order to use a macc instruction.;;;; This peephole needs a scratch register to cater for the case when one;; of the multiplication operands is the same as the destination.;;;; Operand 0: GPR (scratch);; Operand 1: LO;; Operand 2: GPR (addend);; Operand 3: GPR (destination);; Operand 4: macc/msac;; Operand 5: HI;; Operand 6: new multiplication;; Operand 7: new addition/subtraction(define_peephole2 [(match_scratch:SI 0 "d") (set (match_operand:SI 1 "register_operand") (match_operand:SI 2 "register_operand")) (match_dup 0) (parallel [(set (match_operand:SI 3 "register_operand") (match_operand:SI 4 "macc_msac_operand")) (clobber (match_operand:SI 5 "register_operand")) (clobber (match_dup 1))])] "GENERATE_MULT3_SI && true_regnum (operands[1]) == LO_REGNUM && peep2_reg_dead_p (2, operands[1]) && GP_REG_P (true_regnum (operands[3]))" [(parallel [(set (match_dup 0) (match_dup 6)) (clobber (match_dup 5)) (clobber (match_dup 1))]) (set (match_dup 3) (match_dup 7))]{ operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1); operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode, operands[2], operands[0]);});; Same as above, except LO is the initial target of the macc.;;;; Operand 0: GPR (scratch);; Operand 1: LO;; Operand 2: GPR (addend);; Operand 3: macc/msac;; Operand 4: HI;; Operand 5: GPR (destination);; Operand 6: new multiplication;; Operand 7: new addition/subtraction(define_peephole2 [(match_scratch:SI 0 "d") (set (match_operand:SI 1 "register_operand") (match_operand:SI 2 "register_operand")) (match_dup 0) (parallel [(set (match_dup 1) (match_operand:SI 3 "macc_msac_operand")) (clobber (match_operand:SI 4 "register_operand")) (clobber (scratch:SI))]) (match_dup 0) (set (match_operand:SI 5 "register_operand") (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))] "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])" [(parallel [(set (match_dup 0) (match_dup 6)) (clobber (match_dup 4)) (clobber (match_dup 1))]) (set (match_dup 5) (match_dup 7))]{ operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1); operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode, operands[2], operands[0]);})(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,1,l")) (clobber (match_scratch:SI 6 "=X,X,&d"))] "ISA_HAS_MADD_MSUB" "@ 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))] "reload_completed && !TARGET_DEBUG_D_MODE && GP_REG_P (true_regnum (operands[0])) && GP_REG_P (true_regnum (operands[1]))" [(parallel [(set (match_dup 6) (mult:SI (match_dup 2) (match_dup 3))) (clobber (match_dup 4)) (clobber (match_dup 5))]) (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))] "");; 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") (match_operand:SI 3 "register_operand")))) (clobber (match_scratch:SI 4)) (clobber (match_scratch:SI 5)) (clobber (match_scratch:SI 6))] "reload_completed && !TARGET_DEBUG_D_MODE && GP_REG_P (true_regnum (operands[0])) && true_regnum (operands[1]) == LO_REGNUM" [(parallel [(set (match_dup 1) (minus:SI (match_dup 1) (mult:SI (match_dup 2) (match_dup 3)))) (clobber (match_dup 4)) (clobber (match_dup 5)) (clobber (match_dup 6))]) (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))] "")(define_insn "*muls" [(set (match_operand:SI 0 "register_operand" "=l,d") (neg:SI (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 "=X,l"))] "ISA_HAS_MULS" "@ muls\t$0,%1,%2 muls\t%0,%1,%2" [(set_attr "type" "imul") (set_attr "mode" "SI")]);; ??? We could define a mulditi3 pattern when TARGET_64BIT.(define_expand "<u>mulsidi3" [(parallel [(set (match_operand:DI 0 "register_operand") (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand")) (any_extend:DI (match_operand:SI 2 "register_operand")))) (clobber (scratch:DI)) (clobber (scratch:DI)) (clobber (scratch:DI))])] "!TARGET_64BIT || !TARGET_FIX_R4000"{ if (!TARGET_64BIT) { if (!TARGET_FIX_R4000) emit_insn (gen_<u>mulsidi3_32bit_internal (operands[0], operands[1], operands[2])); else emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1], operands[2])); DONE; }})(define_insn "<u>mulsidi3_32bit_internal" [(set (match_operand:DI 0 "register_operand" "=x") (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))] "!TARGET_64BIT && !TARGET_FIX_R4000" "mult<u>\t%1,%2" [(set_attr "type" "imul") (set_attr "mode" "SI")])(define_insn "<u>mulsidi3_32bit_r4000" [(set (match_operand:DI 0 "register_operand" "=d") (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) (any_extend:DI (match_operand:SI 2 "register_operand" "d")))) (clobber (match_scratch:DI 3 "=x"))] "!TARGET_64BIT && TARGET_FIX_R4000" "mult<u>\t%1,%2\;mflo\t%L0;mfhi\t%M0" [(set_attr "type" "imul") (set_attr "mode" "SI") (set_attr "length" "12")])(define_insn_and_split "*<u>mulsidi3_64bit" [(set (match_operand:DI 0 "register_operand" "=d") (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) (any_extend:DI (match_operand:SI 2 "register_operand" "d")))) (clobber (match_scratch:DI 3 "=l")) (clobber (match_scratch:DI 4 "=h")) (clobber (match_scratch:DI 5 "=d"))] "TARGET_64BIT && !TARGET_FIX_R4000" "#" "&& reload_completed" [(parallel [(set (match_dup 3) (sign_extend:DI (mult:SI (match_dup 1) (match_dup 2)))) (set (match_dup 4) (ashiftrt:DI (mult:DI (any_extend:DI (match_dup 1)) (any_extend:DI (match_dup 2))) (const_int 32)))]) ;; OP5 <- LO, OP0 <- HI (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO)) (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO)) ;; Zero-extend OP5. (set (match_dup 5) (ashift:DI (match_dup 5) (const_int 32))) (set (match_dup 5) (lshiftrt:DI (match_dup 5) (const_int 32))) ;; Shift OP0 into place. (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32))) ;; OR the two halves together (set (match_dup 0) (ior:DI (match_dup 0) (match_dup 5)))] "" [(set_attr "type" "imul") (set_attr "mode" "SI") (set_attr "length" "24")])(define_insn "*<u>mulsidi3_64bit_parts" [(set (match_operand:DI 0 "register_operand" "=l") (sign_extend:DI (mult:SI (match_operand:SI 2 "register_operand" "d") (match_operand:SI 3 "register_operand" "d")))) (set (match_operand:DI 1 "register_operand" "=h") (ashiftrt:DI (mult:DI (any_extend:DI (match_dup 2)) (any_extend:DI (match_dup 3))) (const_int 32)))] "TARGET_64BIT && !TARGET_FIX_R4000" "mult<u>\t%2,%3" [(set_attr "type" "imul") (set_attr "mode" "SI")]);; Widening multiply with negation.(define_insn "*muls<u>_di" [(set (match_operand:DI 0 "register_operand" "=x") (neg:DI (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))] "!TARGET_64BIT && ISA_HAS_MULS" "muls<u>\t$0,%1,%2" [(set_attr "type" "imul") (set_attr "mode" "SI")])(define_insn "*msac<u>_di" [(set (match_operand:DI 0 "register_operand" "=x") (minus:DI (match_operand:DI 3 "register_operand" "0") (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))] "!TARGET_64BIT && (ISA_HAS_MSAC || TARGET_ALLEGREX)"{ if (TARGET_MIPS5500 || TARGET_ALLEGREX) return "msub<u>\t%1,%2"; else return "msac<u>\t$0,%1,%2";} [(set_attr "type" "imadd") (set_attr "mode" "SI")]);; _highpart patterns(define_expand "<su>mulsi3_highpart" [(set (match_operand:SI 0 "register_operand") (truncate:SI (lshiftrt:DI (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand")) (any_extend:DI (match_operand:SI 2 "register_operand"))) (const_int 32))))] "ISA_HAS_MULHI || !TARGET_FIX_R4000"{ if (ISA_HAS_MULHI) emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0], operands[1], operands[2])); else emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1], operands[2])); DONE;})(define_insn "<su>mulsi3_highpart_internal" [(set (match_operand:SI 0 "register_operand" "=h") (truncate:SI (lshiftrt:DI (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) (any_extend:DI (match_operand:SI 2 "register_operand" "d"))) (const_int 32)))) (clobber (match_scratch:SI 3 "=l"))] "!ISA_HAS_MULHI && !TARGET_FIX_R4000" "mult<u>\t%1,%2" [(set_attr "type" "imul") (set_attr "mode" "SI")])(define_insn "<su>mulsi3_highpart_mulhi_internal" [(set (match_operand:SI 0 "register_operand" "=h,d") (truncate:SI (lshiftrt:DI (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d,d")) (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))) (const_int 32)))) (clobber (match_scratch:SI 3 "=l,l")) (clobber (match_scratch:SI 4 "=X,h"))] "ISA_HAS_MULHI" "@ mult<u>\t%1,%2 mulhi<u>\t%0,%1,%2" [(set_attr "type" "imul") (set_attr "mode" "SI")])(define_insn "*<su>mulsi3_highpart_neg_mulhi_internal" [(set (match_operand:SI 0 "register_operand" "=h,d") (truncate:SI (lshiftrt:DI (neg:DI (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d,d")) (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))) (const_int 32)))) (clobber (match_scratch:SI 3 "=l,l")) (clobber (match_scratch:SI 4 "=X,h"))] "ISA_HAS_MULHI" "@ mulshi<u>\t%.,%1,%2 mulshi<u>\t%0,%1,%2" [(set_attr "type" "imul")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -