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

📄 fr30.md

📁 linux下的gcc编译器
💻 MD
📖 第 1 页 / 共 3 页
字号:
;; Now, the actual comparisons, generated by the branch and/or scc operations(define_insn "*cmpsi_internal"  [(set (reg:CC 16)	(compare:CC (match_operand:SI 0 "register_operand"  "r,r,r")		    (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]  ""  "@  cmp	%1, %0  cmp	%1, %0  cmp2	%1, %0");;}}} ;;{{{ Branches ;; Define_expands called by the machine independent part of the compiler;; to allocate a new comparison register(define_expand "beq"  [(set (reg:CC 16)	(compare:CC (match_dup 1)		    (match_dup 2)))   (set (pc)	(if_then_else (eq:CC (reg:CC 16)			     (const_int 0))		      (label_ref (match_operand 0 "" ""))		      (pc)))]  ""  "{  operands[1] = fr30_compare_op0;  operands[2] = fr30_compare_op1;  }")(define_expand "bne"  [(set (reg:CC 16)	(compare:CC (match_dup 1)		    (match_dup 2)))   (set (pc)	(if_then_else (ne:CC (reg:CC 16)			     (const_int 0))		      (label_ref (match_operand 0 "" ""))		      (pc)))]  ""  "{  operands[1] = fr30_compare_op0;  operands[2] = fr30_compare_op1;  }")(define_expand "blt"  [(set (reg:CC 16)	(compare:CC (match_dup 1)		    (match_dup 2)))   (set (pc)	(if_then_else (lt:CC (reg:CC 16)			     (const_int 0))		      (label_ref (match_operand 0 "" ""))		      (pc)))]  ""  "{  operands[1] = fr30_compare_op0;  operands[2] = fr30_compare_op1;  }")(define_expand "ble"  [(set (reg:CC 16)	(compare:CC (match_dup 1)		    (match_dup 2)))   (set (pc)	(if_then_else (le:CC (reg:CC 16)			     (const_int 0))		      (label_ref (match_operand 0 "" ""))		      (pc)))]  ""  "{  operands[1] = fr30_compare_op0;  operands[2] = fr30_compare_op1;  }")(define_expand "bgt"  [(set (reg:CC 16)	(compare:CC (match_dup 1)		    (match_dup 2)))   (set (pc)	(if_then_else (gt:CC (reg:CC 16)			     (const_int 0))		      (label_ref (match_operand 0 "" ""))		      (pc)))]  ""  "{  operands[1] = fr30_compare_op0;  operands[2] = fr30_compare_op1;  }")(define_expand "bge"  [(set (reg:CC 16)	(compare:CC (match_dup 1)		    (match_dup 2)))   (set (pc)	(if_then_else (ge:CC (reg:CC 16)			     (const_int 0))		      (label_ref (match_operand 0 "" ""))		      (pc)))]  ""  "{  operands[1] = fr30_compare_op0;  operands[2] = fr30_compare_op1;  }")(define_expand "bltu"  [(set (reg:CC 16)	(compare:CC (match_dup 1)		    (match_dup 2)))   (set (pc)	(if_then_else (ltu:CC (reg:CC 16)			      (const_int 0))		      (label_ref (match_operand 0 "" ""))		      (pc)))]  ""  "{  operands[1] = fr30_compare_op0;  operands[2] = fr30_compare_op1;  }")(define_expand "bleu"  [(set (reg:CC 16)	(compare:CC (match_dup 1)		    (match_dup 2)))   (set (pc)	(if_then_else (leu:CC (reg:CC 16)			      (const_int 0))		      (label_ref (match_operand 0 "" ""))		      (pc)))]  ""  "{  operands[1] = fr30_compare_op0;  operands[2] = fr30_compare_op1;  }")(define_expand "bgtu"  [(set (reg:CC 16)	(compare:CC (match_dup 1)		    (match_dup 2)))   (set (pc)	(if_then_else (gtu:CC (reg:CC 16)			      (const_int 0))		      (label_ref (match_operand 0 "" ""))		      (pc)))]  ""  "{  operands[1] = fr30_compare_op0;  operands[2] = fr30_compare_op1;  }")(define_expand "bgeu"  [(set (reg:CC 16)	(compare:CC (match_dup 1)		    (match_dup 2)))   (set (pc)	(if_then_else (geu:CC (reg:CC 16)			      (const_int 0))		      (label_ref (match_operand 0 "" ""))		      (pc)))]  ""  "{  operands[1] = fr30_compare_op0;  operands[2] = fr30_compare_op1;  }");; Actual branches.  We must allow for the (label_ref) and the (pc) to be;; swapped.  If they are swapped, it reverses the sense of the branch.;; This pattern matches the (branch-if-true) branches generated above.;; It generates two different instruction sequences depending upon how;; far away the destination is.;; The calculation for the instruction length is derived as follows:;; The branch instruction has a 9 bit signed displacement so we have;; this inequality for the displacement:;;;;               -256 <= pc < 256;; or;;	   -256 + 256 <= pc + 256 < 256 + 256;; ie;;		    0 <= pc + 256 < 512 ;;;; if we consider the displacement as an unsigned value, then negative;; displacements become very large positive displacements, and the;; inequality becomes:;;;;		pc + 256 < 512;;;; In order to allow for the fact that the real branch instruction works;; from pc + 2, we increase the offset to 258.;;;; Note - we do not have to worry about whether the branch is delayed or;; not, as branch shortening happens after delay slot reorganisation.(define_insn "*branch_true"  [(set (pc)	(if_then_else (match_operator:CC 0 "comparison_operator"					 [(reg:CC 16)					  (const_int 0)])		      (label_ref (match_operand 1 "" ""))		      (pc)))]  ""  "*  {    if (get_attr_length (insn) == 2)      return \"b%b0%#\\t%l1\";    else      {        static char   buffer [100];	const char *  tmp_reg; 	const char *  ldi_insn;	        tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];		ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";	/* The code produced here is, for say the EQ case:	       Bne  1f	       LDI  <label>, r0	       JMP  r0	     1:                                         */	     	sprintf (buffer,	  \"b%%B0\\t1f\\t;\\n\\t%s\\t%%l1, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\\n1:\",	  ldi_insn, tmp_reg, tmp_reg);         return buffer;    }  }"  [(set (attr "length") (if_then_else			  (ltu			    (plus			      (minus			        (match_dup 1)				(pc))			      (const_int 254))			    (const_int 506))			  (const_int 2)			  (if_then_else (eq_attr "size" "small")					(const_int 8)					(const_int 10))))   (set_attr "delay_type" "delayed")]);; This pattern is a duplicate of the previous one, except that the;; branch occurs if the test is false, so the %B operator is used.(define_insn "*branch_false"  [(set (pc)	(if_then_else (match_operator:CC 0 "comparison_operator"					 [(reg:CC 16)					  (const_int 0)])		      (pc)		      (label_ref (match_operand 1 "" ""))))]  ""  "*  {    if (get_attr_length (insn) == 2)      return \"b%B0%#\\t%l1 \";    else      {        static char   buffer [100];	const char *  tmp_reg; 	const char *  ldi_insn;	        tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];		ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";	sprintf (buffer,	  \"b%%b0\\t1f\\t;\\n\\t%s\\t%%l1, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\\n1:\",	  ldi_insn, tmp_reg, tmp_reg);         return buffer;      }  }"  [(set (attr "length") (if_then_else (ltu (plus (minus (match_dup 1) (pc))						 (const_int 254))					   (const_int 506))				      (const_int 2)				      (if_then_else (eq_attr "size" "small")						    (const_int 8)						    (const_int 10))))   (set_attr "delay_type" "delayed")]);;}}} ;;{{{ Calls & Jumps ;; Subroutine call instruction returning no value.  Operand 0 is the function;; to call; operand 1 is the number of bytes of arguments pushed (in mode;; `SImode', except it is normally a `const_int'); operand 2 is the number of;; registers used as operands.(define_insn "call"  [(call (match_operand 0 "call_operand" "Qm")	 (match_operand 1 ""             "g"))   (clobber (reg:SI 17))]  ""  "call%#\\t%0"  [(set_attr "delay_type" "delayed")]);; Subroutine call instruction returning a value.  Operand 0 is the hard;; register in which the value is returned.  There are three more operands, the;; same as the three operands of the `call' instruction (but with numbers;; increased by one).;; Subroutines that return `BLKmode' objects use the `call' insn.(define_insn "call_value"  [(set (match_operand 0 "register_operand"  "=r")	(call (match_operand 1 "call_operand" "Qm")	      (match_operand 2 ""             "g")))   (clobber (reg:SI 17))]  ""  "call%#\\t%1"  [(set_attr "delay_type" "delayed")]);; Normal unconditional jump.;; For a description of the computation of the length ;; attribute see the branch patterns above.;;;; Although this instruction really clobbers r0, flow;; relies on jump being simplejump_p in several places;; and as r0 is fixed, this doesn't change anything(define_insn "jump"  [(set (pc) (label_ref (match_operand 0 "" "")))]  ""  "*  {    if (get_attr_length (insn) == 2)       return \"bra%#\\t%0\";    else      {        static char   buffer [100];	const char *  tmp_reg; 	const char *  ldi_insn;	        tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];	ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";	sprintf (buffer, \"%s\\t%%0, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\",	  ldi_insn, tmp_reg, tmp_reg);         return buffer;      }  }"  [(set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))						(const_int 254))					  (const_int 506))				     (const_int 2)				     (if_then_else (eq_attr "size" "small")						   (const_int 6)						   (const_int 8))))   (set_attr "delay_type" "delayed")]);; Indirect jump through a register(define_insn "indirect_jump"  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))]  "GET_CODE (operands[0]) != MEM || GET_CODE (XEXP (operands[0], 0)) != PLUS"  "jmp%#\\t@%0"  [(set_attr "delay_type" "delayed")])(define_insn "tablejump"  [(set (pc) (match_operand:SI 0 "register_operand" "r"))   (use (label_ref (match_operand 1 "" "")))]  ""  "jmp%#\\t@%0"  [(set_attr "delay_type" "delayed")]);;}}} ;;{{{ Function Prologues and Epilogues ;; Called after register allocation to add any instructions needed for the;; prologue.  Using a prologue insn is favored compared to putting all of the;; instructions in output_function_prologue(), since it allows the scheduler;; to intermix instructions with the saves of the caller saved registers.  In;; some cases, it might be necessary to emit a barrier instruction as the last;; insn to prevent such scheduling.(define_expand "prologue"  [(clobber (const_int 0))]  ""  "{  fr30_expand_prologue ();  DONE;  }");; Called after register allocation to add any instructions needed for the;; epilogue.  Using an epilogue insn is favored compared to putting all of the;; instructions in output_function_epilogue(), since it allows the scheduler;; to intermix instructions with the restores of the caller saved registers.;; In some cases, it might be necessary to emit a barrier instruction as the;; first insn to prevent such scheduling.(define_expand "epilogue"  [(return)]  ""  "{  fr30_expand_epilogue ();  DONE;  }")(define_insn "return_from_func"  [(return)   (use (reg:SI 17))]  "reload_completed"  "ret%#"  [(set_attr "delay_type" "delayed")])(define_insn "leave_func"  [(set (reg:SI 15) (reg:SI 14))   (set (reg:SI 14) (mem:SI (post_inc:SI (reg:SI 15))))]  "reload_completed"  "leave")(define_insn "enter_func"  [(set:SI (mem:SI (minus:SI (reg:SI 15)			     (const_int 4)))	   (reg:SI 14))   (set:SI (reg:SI 14)	   (minus:SI (reg:SI 15)		     (const_int 4)))   (set:SI (reg:SI 15)	   (minus:SI (reg:SI 15)		     (match_operand 0 "immediate_operand" "i")))]  "reload_completed"  "enter	#%0"  [(set_attr "delay_type" "other")]);;}}} ;;{{{ Miscellaneous ;; No operation, needed in case the user uses -g but not -O.(define_insn "nop"  [(const_int 0)]  ""  "nop");; Pseudo instruction that prevents the scheduler from moving code above this;; point.(define_insn "blockage"  [(unspec_volatile [(const_int 0)] 0)]  ""  ""  [(set_attr "length" "0")]);;}}}   ;; Local Variables:;; mode: md;; folded-file: t;; End:

⌨️ 快捷键说明

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