⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mips.md.svn-base

📁 PSP用开发必装库GCC4
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
	    (minus:SI (match_operand:SI 1 "register_operand" "d")		      (match_operand:SI 2 "register_operand" "d"))))]  "TARGET_64BIT"  "subu\t%0,%1,%2"  [(set_attr "type" "arith")   (set_attr "mode" "DI")]);;;;  ....................;;;;	MULTIPLICATION;;;;  ....................;;(define_expand "mul<mode>3"  [(set (match_operand:SCALARF 0 "register_operand")	(mult:SCALARF (match_operand:SCALARF 1 "register_operand")		      (match_operand:SCALARF 2 "register_operand")))]  ""  "")(define_insn "*mul<mode>3"  [(set (match_operand:SCALARF 0 "register_operand" "=f")	(mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")		      (match_operand:SCALARF 2 "register_operand" "f")))]  "!TARGET_4300_MUL_FIX"  "mul.<fmt>\t%0,%1,%2"  [(set_attr "type" "fmul")   (set_attr "mode" "<MODE>")]);; 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_insn "*mul<mode>3_r4300"  [(set (match_operand:SCALARF 0 "register_operand" "=f")	(mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f")		      (match_operand:SCALARF 2 "register_operand" "f")))]  "TARGET_4300_MUL_FIX"  "mul.<fmt>\t%0,%1,%2\;nop"  [(set_attr "type" "fmul")   (set_attr "mode" "<MODE>")   (set_attr "length" "8")])(define_insn "mulv2sf3"  [(set (match_operand:V2SF 0 "register_operand" "=f")	(mult:V2SF (match_operand:V2SF 1 "register_operand" "f")		   (match_operand:V2SF 2 "register_operand" "f")))]  "TARGET_PAIRED_SINGLE_FLOAT"  "mul.ps\t%0,%1,%2"  [(set_attr "type" "fmul")   (set_attr "mode" "SF")]);; The original R4000 has a cpu bug.  If a double-word or a variable;; shift executes while an integer multiplication is in progress, the;; shift may give an incorrect result.  Avoid this by keeping the mflo;; with the mult on the R4000.;;;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0";; (also valid for MIPS R4000MC processors):;;;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to;;	this errata description.;;	The following code sequence causes the R4000 to incorrectly;;	execute the Double Shift Right Arithmetic 32 (dsra32);;	instruction.  If the dsra32 instruction is executed during an;;	integer multiply, the dsra32 will only shift by the amount in;;	specified in the instruction rather than the amount plus 32;;	bits.;;	instruction 1:		mult	rs,rt		integer multiply;;	instruction 2-12:	dsra32	rd,rt,rs	doubleword shift;;							right arithmetic + 32;;	Workaround: A dsra32 instruction placed after an integer;;	multiply should not be one of the 11 instructions after the;;	multiply instruction.";;;; and:;;;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by;;	the following description.;;	All extended shifts (shift by n+32) and variable shifts (32 and;;	64-bit versions) may produce incorrect results under the;;	following conditions:;;	1) An integer multiply is currently executing;;	2) These types of shift instructions are executed immediately;;	   following an integer divide instruction.;;	Workaround:;;	1) Make sure no integer multiply is running wihen these;;	   instruction are executed.  If this cannot be predicted at;;	   compile time, then insert a "mfhi" to R0 instruction;;	   immediately after the integer multiply instruction.  This;;	   will cause the integer multiply to complete before the shift;;	   is executed.;;	2) Separate integer divide and these two classes of shift;;	   instructions by another instruction or a noop.";;;; These processors have PRId values of 0x00004220 and 0x00004300,;; respectively.(define_expand "mul<mode>3"  [(set (match_operand:GPR 0 "register_operand")	(mult:GPR (match_operand:GPR 1 "register_operand")		  (match_operand:GPR 2 "register_operand")))]  ""{  if (GENERATE_MULT3_<MODE>)    emit_insn (gen_mul<mode>3_mult3 (operands[0], operands[1], operands[2]));  else if (!TARGET_FIX_R4000)    emit_insn (gen_mul<mode>3_internal (operands[0], operands[1],					operands[2]));  else    emit_insn (gen_mul<mode>3_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"))]  "GENERATE_MULT3_SI"{  if (which_alternative == 1)    return "mult\t%1,%2";  if (TARGET_MAD      || TARGET_MIPS5400      || TARGET_MIPS5500      || TARGET_MIPS7000      || TARGET_MIPS9000      || ISA_MIPS32      || ISA_MIPS32R2      || ISA_MIPS64)    return "mul\t%0,%1,%2";  return "mult\t%0,%1,%2";}  [(set_attr "type" "imul")   (set_attr "mode" "SI")])(define_insn "muldi3_mult3"  [(set (match_operand:DI 0 "register_operand" "=d")	(mult:DI (match_operand:DI 1 "register_operand" "d")		 (match_operand:DI 2 "register_operand" "d")))   (clobber (match_scratch:DI 3 "=h"))   (clobber (match_scratch:DI 4 "=l"))]  "TARGET_64BIT && GENERATE_MULT3_DI"  "dmult\t%0,%1,%2"  [(set_attr "type" "imul")   (set_attr "mode" "DI")]);; If a register gets allocated to LO, and we spill to memory, the reload;; will include a move from LO to a GPR.  Merge it into the multiplication;; if it can set the GPR directly.;;;; Operand 0: LO;; Operand 1: GPR (1st multiplication operand);; Operand 2: GPR (2nd multiplication operand);; Operand 3: HI;; Operand 4: GPR (destination)(define_peephole2  [(parallel       [(set (match_operand:SI 0 "register_operand")	     (mult:SI (match_operand:SI 1 "register_operand")		      (match_operand:SI 2 "register_operand")))        (clobber (match_operand:SI 3 "register_operand"))        (clobber (scratch:SI))])   (set (match_operand:SI 4 "register_operand")	(unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]  "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])"  [(parallel       [(set (match_dup 4)	     (mult:SI (match_dup 1)		      (match_dup 2)))        (clobber (match_dup 3))        (clobber (match_dup 0))])])(define_insn "mul<mode>3_internal"  [(set (match_operand:GPR 0 "register_operand" "=l")	(mult:GPR (match_operand:GPR 1 "register_operand" "d")		  (match_operand:GPR 2 "register_operand" "d")))   (clobber (match_scratch:GPR 3 "=h"))]  "!TARGET_FIX_R4000"  "<d>mult\t%1,%2"  [(set_attr "type" "imul")   (set_attr "mode" "<MODE>")])(define_insn "mul<mode>3_r4000"  [(set (match_operand:GPR 0 "register_operand" "=d")	(mult:GPR (match_operand:GPR 1 "register_operand" "d")		  (match_operand:GPR 2 "register_operand" "d")))   (clobber (match_scratch:GPR 3 "=h"))   (clobber (match_scratch:GPR 4 "=l"))]  "TARGET_FIX_R4000"  "<d>mult\t%1,%2\;mflo\t%0"  [(set_attr "type" "imul")   (set_attr "mode" "<MODE>")   (set_attr "length" "8")]);; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead;; of "mult; mflo".  They have the same latency, but the first form gives;; us an extra cycle to compute the operands.;; Operand 0: LO;; Operand 1: GPR (1st multiplication operand);; Operand 2: GPR (2nd multiplication operand);; Operand 3: HI;; Operand 4: GPR (destination)(define_peephole2  [(parallel       [(set (match_operand:SI 0 "register_operand")	     (mult:SI (match_operand:SI 1 "register_operand")		      (match_operand:SI 2 "register_operand")))        (clobber (match_operand:SI 3 "register_operand"))])   (set (match_operand:SI 4 "register_operand")	(unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))]  "ISA_HAS_MACC && !GENERATE_MULT3_SI"  [(set (match_dup 0)	(const_int 0))   (parallel       [(set (match_dup 0)	     (plus:SI (mult:SI (match_dup 1)			       (match_dup 2))		      (match_dup 0)))	(set (match_dup 4)	     (plus:SI (mult:SI (match_dup 1)			       (match_dup 2))		      (match_dup 0)))        (clobber (match_dup 3))])]);; 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 "=X,X,&d"))]  "(TARGET_MIPS3900   || ISA_HAS_MADD_MSUB)   && !TARGET_MIPS16"{  static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };  if (which_alternative == 2)    return "#";  if (ISA_HAS_MADD_MSUB && which_alternative != 0)    return "#";  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))]  "reload_completed && !TARGET_DEBUG_D_MODE   && GP_REG_P (true_regnum (operands[0]))   && GP_REG_P (true_regnum (operands[3]))"  [(parallel [(set (match_dup 6)		   (mult:SI (match_dup 1) (match_dup 2)))	      (clobber (match_dup 4))	      (clobber (match_dup 5))])   (set (match_dup 0) (plus:SI (match_dup 6) (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))]  "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))])   (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))]  "")(define_insn "*macc"  [(set (match_operand:SI 0 "register_operand" "=l,d")	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")			  (match_operand:SI 2 "register_operand" "d,d"))		 (match_operand:SI 3 "register_operand" "0,l")))   (clobber (match_scratch:SI 4 "=h,h"))   (clobber (match_scratch:SI 5 "=X,3"))]  "ISA_HAS_MACC"{  if (which_alternative == 1)    return "macc\t%0,%1,%2";  else if (TARGET_MIPS5500)    return "madd\t%1,%2";  else    /* The VR4130 assumes that there is a two-cycle latency between a macc       that "writes" to $0 and an instruction that reads from it.  We avoid       this by assigning to $1 instead.  */    return "%[macc\t%@,%1,%2%]";}  [(set_attr "type" "imadd")   (set_attr "mode" "SI")])(define_insn "*msac"  [(set (match_operand:SI 0 "register_operand" "=l,d")        (minus:SI (match_operand:SI 1 "register_operand" "0,l")                  (mult:SI (match_operand:SI 2 "register_operand" "d,d")                           (match_operand:SI 3 "register_operand" "d,d"))))   (clobber (match_scratch:SI 4 "=h,h"))   (clobber (match_scratch:SI 5 "=X,1"))]  "ISA_HAS_MSAC"{  if (which_alternative == 1)    return "msac\t%0,%2,%3";  else if (TARGET_MIPS5500)    return "msub\t%2,%3";  else    return "msac\t$0,%2,%3";}  [(set_attr "type"     "imadd")   (set_attr "mode"     "SI")]);; An msac-like instruction implemented using negation and a macc.(define_insn_and_split "*msac_using_macc"  [(set (match_operand:SI 0 "register_operand" "=l,d")        (minus:SI (match_operand:SI 1 "register_operand" "0,l")                  (mult:SI (match_operand:SI 2 "register_operand" "d,d")                           (match_operand:SI 3 "register_operand" "d,d"))))   (clobber (match_scratch:SI 4 "=h,h"))   (clobber (match_scratch:SI 5 "=X,1"))   (clobber (match_scratch:SI 6 "=d,d"))]  "ISA_HAS_MACC && !ISA_HAS_MSAC"  "#"  "&& reload_completed"  [(set (match_dup 6)	(neg:SI (match_dup 3)))   (parallel       [(set (match_dup 0)	     (plus:SI (mult:SI (match_dup 2)			       (match_dup 6))		      (match_dup 1)))	(clobber (match_dup 4))	(clobber (match_dup 5))])]  ""  [(set_attr "type"     "imadd")   (set_attr "length"	"8")]);; Patterns generated by the define_peephole2 below.(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>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -