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

📄 m88k.md

📁 linux下的gcc编译器
💻 MD
📖 第 1 页 / 共 5 页
字号:
;; Recognize bcnd instructions for integer values.  This is distinguished;; from a conditional branch instruction (below) with SImode instead of;; CCmode.(define_insn ""  [(set (pc)	(if_then_else	 (match_operator 0 "relop_no_unsigned"			 [(match_operand:SI 1 "register_operand" "r")			  (const_int 0)])	 (match_operand 2 "pc_or_label_ref" "")	 (match_operand 3 "pc_or_label_ref" "")))]  ""  "bcnd%. %R3%B0,%1,%P2%P3"  [(set_attr "type" "branch")]);; Recognize tests for sign and zero.(define_insn ""  [(set (pc)	(if_then_else	 (match_operator 0 "equality_op"			 [(match_operand:SI 1 "register_operand" "r")			  (const_int -2147483648)])	 (match_operand 2 "pc_or_label_ref" "")	 (match_operand 3 "pc_or_label_ref" "")))]  ""  "bcnd%. %R3%E0,%1,%P2%P3"  [(set_attr "type" "branch")])(define_insn ""  [(set (pc)	(if_then_else	 (match_operator 0 "equality_op"			 [(zero_extract:SI			   (match_operand:SI 1 "register_operand" "r")			   (const_int 31)			   (const_int 1))			  (const_int 0)])	 (match_operand 2 "pc_or_label_ref" "")	 (match_operand 3 "pc_or_label_ref" "")))]  ""  "bcnd%. %R3%D0,%1,%P2%P3"  [(set_attr "type" "branch")]);; Recognize bcnd instructions for double integer values(define_insn ""  [(set (pc)	(if_then_else	 (match_operator 0 "relop_no_unsigned"			 [(sign_extend:DI			   (match_operand:SI 1 "register_operand" "r"))			  (const_int 0)])	 (match_operand 2 "pc_or_label_ref" "")	 (match_operand 3 "pc_or_label_ref" "")))]  ""  "bcnd%. %R3%B0,%1,%P2%P3"  [(set_attr "type" "branch")])(define_insn ""  [(set (pc)	(if_then_else	 (match_operator 0 "equality_op"			 [(zero_extend:DI			   (match_operand:SI 1 "register_operand" "r"))			  (const_int 0)])	 (match_operand 2 "pc_or_label_ref" "")	 (match_operand 3 "pc_or_label_ref" "")))]  ""  "bcnd%. %R3%B0,%1,%P2%P3"  [(set_attr "type" "branch")]); @@ I doubt this is interesting until cmpdi is provided.  Anyway, it needs; to be reworked.;;(define_insn "";  [(set (pc);	(if_then_else;	 (match_operator 0 "relop_no_unsigned";			 [(match_operand:DI 1 "register_operand" "r");			  (const_int 0)]);	 (match_operand 2 "pc_or_label_ref" "");	 (match_operand 3 "pc_or_label_ref" "")))];  "";  "*;{;  switch (GET_CODE (operands[0]));    {;    case EQ:;    case NE:;      /* I'm not sure if it's safe to use .n here.  */;      return \"or %!,%1,%d1\;bcnd %R3%B0,%!,%P2%P3\";;    case GE:;    case LT:;      return \"bcnd%. %R3%B0,%1,%P2%P3\";;    case GT:;      {;	rtx op2 = operands[2];;	operands[2] = operands[3];;	operands[3] = op2;;      };    case LE:;      if (GET_CODE (operands[3]) == LABEL_REF);	{;	  int label_num;;	  operands[2] = gen_label_rtx ();;	  label_num = XINT (operands[2], 3);;	  output_asm_insn;	    (\"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#ne0,%!,%3\", operands);;	  output_label (label_num);;	  return \"\";;	};      else;	return \"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#eq0,%!,%2\";;    };}");; Recognize bcnd instructions for single precision float values;; Exclude relational operations as they must signal NaNs.;; @@ These bcnd insns for float and double values don't seem to be recognized.(define_insn ""  [(set (pc)	(if_then_else	 (match_operator 0 "equality_op"			 [(float_extend:DF			   (match_operand:SF 1 "register_operand" "r"))			  (const_int 0)])	 (match_operand 2 "pc_or_label_ref" "")	 (match_operand 3 "pc_or_label_ref" "")))]  ""  "bcnd%. %R3%D0,%1,%P2%P3"  [(set_attr "type" "branch")])(define_insn ""  [(set (pc)	(if_then_else	 (match_operator 0 "equality_op"			 [(match_operand:SF 1 "register_operand" "r")			  (const_int 0)])	 (match_operand 2 "pc_or_label_ref" "")	 (match_operand 3 "pc_or_label_ref" "")))]  ""  "bcnd%. %R3%D0,%1,%P2%P3"  [(set_attr "type" "branch")]);; Recognize bcnd instructions for double precision float values;; Exclude relational operations as they must signal NaNs.(define_insn ""  [(set (pc)	(if_then_else	 (match_operator 0 "equality_op"			 [(match_operand:DF 1 "register_operand" "r")			  (const_int 0)])	 (match_operand 2 "pc_or_label_ref" "")	 (match_operand 3 "pc_or_label_ref" "")))]  ""  "*{  int label_num;  if (GET_CODE (operands[0]) == NE)    {      rtx op2 = operands[2];      operands[2] = operands[3];      operands[3] = op2;    }  if (GET_CODE (operands[3]) == LABEL_REF)    return \"bcnd 0x5,%1,%3\;bcnd %#ne0,%d1,%3\";  operands[3] = gen_label_rtx ();  label_num = XINT (operands[3], 3);  output_asm_insn (\"bcnd 0x5,%1,%3\;bcnd %#eq0,%d1,%2\", operands);  output_label (label_num);  return \"\";}"  [(set_attr "type" "weird")   (set_attr "length" "3")]);; Recognize bb0 and bb1 instructions.  These use two unusual template;; patterns, %Lx and %Px.  %Lx outputs a 1 if operand `x' is a LABEL_REF;; otherwise it outputs a 0.  It then may print ".n" if the delay slot;; is used.  %Px does noting if `x' is PC and outputs the operand if `x';; is a LABEL_REF.(define_insn ""  [(set (pc)	(if_then_else	 (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "r")			      (const_int 1)			      (match_operand:SI 1 "int5_operand" ""))	     (const_int 0))	 (match_operand 2 "pc_or_label_ref" "")	 (match_operand 3 "pc_or_label_ref" "")))]  ""  "bb%L2 (31-%1),%0,%P2%P3"  [(set_attr "type" "branch")])(define_insn ""  [(set (pc)	(if_then_else	 (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "r")			      (const_int 1)			      (match_operand:SI 1 "int5_operand" ""))	     (const_int 0))	 (match_operand 2 "pc_or_label_ref" "")	 (match_operand 3 "pc_or_label_ref" "")))]  ""  "bb%L3 (31-%1),%0,%P2%P3"  [(set_attr "type" "branch")])(define_insn ""  [(set (pc)	(if_then_else	 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")			      (const_int 1)			      (match_operand:SI 1 "int5_operand" ""))	     (const_int 0))	 (match_operand 2 "pc_or_label_ref" "")	 (match_operand 3 "pc_or_label_ref" "")))]  ""  "bb%L2 (31-%1),%0,%P2%P3"  [(set_attr "type" "branch")])(define_insn ""  [(set (pc)	(if_then_else	 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")			      (const_int 1)			      (match_operand:SI 1 "int5_operand" ""))	     (const_int 0))	 (match_operand 2 "pc_or_label_ref" "")	 (match_operand 3 "pc_or_label_ref" "")))]  ""  "bb%L3 (31-%1),%0,%P2%P3"  [(set_attr "type" "branch")])(define_insn ""  [(set (pc)	(if_then_else	 (eq (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")		     (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))	      (const_int 0))	 (match_operand 2 "pc_or_label_ref" "")	 (match_operand 3 "pc_or_label_ref" "")))]  "(GET_CODE (operands[0]) == CONST_INT)   != (GET_CODE (operands[1]) == CONST_INT)"  "bb%L3 %p1,%0,%P2%P3"  [(set_attr "type" "branch")])(define_insn ""  [(set (pc)	(if_then_else	 (ne (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")		     (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))	     (const_int 0))	 (match_operand 2 "pc_or_label_ref" "")	 (match_operand 3 "pc_or_label_ref" "")))]  "(GET_CODE (operands[0]) == CONST_INT)   != (GET_CODE (operands[1]) == CONST_INT)"  "bb%L2 %p1,%0,%P2%P3"  [(set_attr "type" "branch")]);; The comparison operations store the comparison into a register and;; record that register.  The following Bxx or Sxx insn uses that;; register as an input.  To facilitate use of bcnd instead of cmp/bb1,;; cmpsi records its operands and produces no code when any operand;; is constant.  In this case, the Bxx insns use gen_bcnd and the;; Sxx insns use gen_test to ensure a cmp has been emitted.;;;; This could also be done for SFmode and DFmode having only beq and bne;; use gen_bcnd.  The others must signal NaNs.  It seems though that zero;; has already been copied into a register.;;;; cmpsi/beq and cmpsi/bne can always be done with bcnd if any operand;; is a constant.  (This idea is due to Torbjorn Granlund.)  Others can;; use bcnd only if an operand is zero.;;;; It is necessary to distinguish a register holding condition codes.;; This is done by context.(define_expand "test"  [(set (match_dup 2)	(compare:CC (match_operand 0 "" "")		    (match_operand 1 "" "")))]  ""  "{  if (m88k_compare_reg)    abort ();  if (GET_CODE (operands[0]) == CONST_INT      && ! SMALL_INT (operands[0]))    operands[0] = force_reg (SImode, operands[0]);  if (GET_CODE (operands[1]) == CONST_INT      && ! SMALL_INT (operands[1]))    operands[1] = force_reg (SImode, operands[1]);  operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);}"); @@ The docs say don't do this.  It's probably a nop since the insn looks; identical to cmpsi against zero.  Is there an advantage to providing; this, perhaps with a different form?;(define_expand "tstsi";  [(set (match_dup 1);	(compare:CC (match_operand:SI 0 "register_operand" "");		    (const_int 0)))]; ""; ";{;  m88k_compare_reg = 0;;  m88k_compare_op0 = operands[0];;  m88k_compare_op1 = const0_rtx;;  DONE;;}")(define_expand "cmpsi"  [(set (match_dup 2)	(compare:CC (match_operand:SI 0 "register_operand" "")		    (match_operand:SI 1 "arith32_operand" "")))]  ""  "{  if (GET_CODE (operands[0]) == CONST_INT      || GET_CODE (operands[1]) == CONST_INT)    {      m88k_compare_reg = 0;      m88k_compare_op0 = operands[0];      m88k_compare_op1 = operands[1];      DONE;    }  operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);}")(define_expand "cmpsf"  [(set (match_dup 2)	(compare:CC (match_operand:SF 0 "register_operand" "")		    (match_operand:SF 1 "register_operand" "")))]  ""  "operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);")(define_expand "cmpdf"  [(set (match_dup 2)	(compare:CC (match_operand:DF 0 "general_operand" "")		    (match_operand:DF 1 "general_operand" "")))]  ""  "{  operands[0] = legitimize_operand (operands[0], DFmode);  operands[1] = legitimize_operand (operands[1], DFmode);  operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);}"); @@ Get back to this later on.;;(define_insn "cmpdi";  [(set (cc0);	(compare:CC (match_operand:DI 0 "register_operand" "r");		    (match_operand:DI 1 "register_operand" "r")))];  "";  "*;{;  if ((cc_status.mdep & MDEP_LS_CHANGE) != 0);    abort ();	/* output_move_double MDEP_LS_CHANGE bits were set. */;;  cc_status.mdep &= ~ MDEP_LS_MASK;;;  operands[2] = gen_label_rtx ();;  /* Remember, %! is the condition code register and %@ is the;     literal synthesis register.  */;;  output_asm_insn (\"cmp %!,%0,%1\;bb0 %#eq,%!,%l2\;cmp %!,%d0,%d1\",;		   operands);;;  output_asm_insn (\"extu %@,%!,4<8>\;clr %!,%!,4<4>\", operands);;  output_asm_insn (\"mak %@,%@,4<4>\;or %!,%!,%@\", operands);;  output_label (XINT (operands[2], 3));;  return \"\";;}";; The actual compare instructions.(define_insn ""  [(set (match_operand:CC 0 "register_operand" "=r")	(compare:CC (match_operand:SI 1 "register_operand" "rO")		    (match_operand:SI 2 "arith_operand" "rI")))]  ""  "cmp %0,%r1,%2")(define_insn ""  [(set (match_operand:CC 0 "register_operand" "=r,r,r,r")	(compare:CC (match_operand:SF 1 "register_operand" "r,r,x,x")		    (match_operand:SF 2 "real_or_0_operand" "r,G,x,G")))]  ""  "@   fcmp.sss %0,%1,%2   fcmp.sss %0,%1,%#r0   fcmp.sss %0,%1,%2   fcmp.sss %0,%1,%#x0"  [(set_attr "type" "spcmp")])(define_insn ""  [(set (match_operand:CC 0 "register_operand" "=r,r")	(compare:CC (match_operand:DF 1 "register_operand" "r,x")		    (float_extend:DF		     (match_operand:SF 2 "register_operand" "r,x"))))]  ""  "fcmp.sds %0,%1,%2"  [(set_attr "type" "dpcmp")])(define_insn ""  [(set (match_operand:CC 0 "register_operand" "=r,r")	(compare:CC (float_extend:DF		     (match_operand:SF 1 "register_operand" "r,x"))		    (match_operand:DF 2 "register_operand" "r,x")))]  ""  "fcmp.ssd %0,%1,%2"  [(set_attr "type" "dpcmp")])(define_insn ""

⌨️ 快捷键说明

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