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

📄 m32r.md

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 MD
📖 第 1 页 / 共 4 页
字号:
  else    {      if (GET_CODE (operands[1]) == EQ)	return \"bne %2,%3,1f\;bra %l0\;1:\";      else	return \"beq %2,%3,1f\;bra %l0\;1:\";    }}"  [(set_attr "type" "branch")  ; We use 25000/50000 instead of 32768/65536 to account for slot filling  ; which is complex to track and inaccurate length specs.   (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))						 (const_int 25000))					   (const_int 50000))				      (const_int 4)				      (const_int 8)))])(define_insn "*rev_reg_branch_insn"  [(set (pc)	(if_then_else (match_operator 1 "eqne_comparison_operator"				      [(match_operand:SI 2 "register_operand" "r")				       (match_operand:SI 3 "register_operand" "r")])		      (pc)		      (label_ref (match_operand 0 "" ""))))]  ""  "*{  /* Is branch target reachable with beq/bne?  */  if (get_attr_length (insn) == 4)    {      if (GET_CODE (operands[1]) == NE)	return \"beq %2,%3,%l0\";      else	return \"bne %2,%3,%l0\";    }  else    {      if (GET_CODE (operands[1]) == NE)	return \"bne %2,%3,1f\;bra %l0\;1:\";      else	return \"beq %2,%3,1f\;bra %l0\;1:\";    }}"  [(set_attr "type" "branch")  ; We use 25000/50000 instead of 32768/65536 to account for slot filling  ; which is complex to track and inaccurate length specs.   (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))						 (const_int 25000))					   (const_int 50000))				      (const_int 4)				      (const_int 8)))]); reg/zero compare and branch insns(define_insn "*zero_branch_insn"  [(set (pc)	(if_then_else (match_operator 1 "signed_comparison_operator"				      [(match_operand:SI 2 "register_operand" "r")				       (const_int 0)])		      (label_ref (match_operand 0 "" ""))		      (pc)))]  ""  "*{  char *br,*invbr;  char asmtext[40];  switch (GET_CODE (operands[1]))    {      case EQ : br = \"eq\"; invbr = \"ne\"; break;      case NE : br = \"ne\"; invbr = \"eq\"; break;      case LE : br = \"le\"; invbr = \"gt\"; break;      case GT : br = \"gt\"; invbr = \"le\"; break;      case LT : br = \"lt\"; invbr = \"ge\"; break;      case GE : br = \"ge\"; invbr = \"lt\"; break;    }  /* Is branch target reachable with bxxz?  */  if (get_attr_length (insn) == 4)    {      sprintf (asmtext, \"b%sz %%2,%%l0\", br);      output_asm_insn (asmtext, operands);    }  else    {      sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", invbr);      output_asm_insn (asmtext, operands);    }  return \"\";}"  [(set_attr "type" "branch")  ; We use 25000/50000 instead of 32768/65536 to account for slot filling  ; which is complex to track and inaccurate length specs.   (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))						 (const_int 25000))					   (const_int 50000))				      (const_int 4)				      (const_int 8)))])(define_insn "*rev_zero_branch_insn"  [(set (pc)	(if_then_else (match_operator 1 "eqne_comparison_operator"				      [(match_operand:SI 2 "register_operand" "r")				       (const_int 0)])		      (pc)		      (label_ref (match_operand 0 "" ""))))]  ""  "*{  char *br,*invbr;  char asmtext[40];  switch (GET_CODE (operands[1]))    {      case EQ : br = \"eq\"; invbr = \"ne\"; break;      case NE : br = \"ne\"; invbr = \"eq\"; break;      case LE : br = \"le\"; invbr = \"gt\"; break;      case GT : br = \"gt\"; invbr = \"le\"; break;      case LT : br = \"lt\"; invbr = \"ge\"; break;      case GE : br = \"ge\"; invbr = \"lt\"; break;    }  /* Is branch target reachable with bxxz?  */  if (get_attr_length (insn) == 4)    {      sprintf (asmtext, \"b%sz %%2,%%l0\", invbr);      output_asm_insn (asmtext, operands);    }  else    {      sprintf (asmtext, \"b%sz %%2,1f\;bra %%l0\;1:\", br);      output_asm_insn (asmtext, operands);    }  return \"\";}"  [(set_attr "type" "branch")  ; We use 25000/50000 instead of 32768/65536 to account for slot filling  ; which is complex to track and inaccurate length specs.   (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))						 (const_int 25000))					   (const_int 50000))				      (const_int 4)				      (const_int 8)))]);; Unconditional and other jump instructions.(define_insn "jump"  [(set (pc) (label_ref (match_operand 0 "" "")))]  ""  "bra %l0"  [(set_attr "type" "uncond_branch")   (set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))						 (const_int 400))					   (const_int 800))				      (const_int 2)				      (const_int 4)))])(define_insn "indirect_jump"  [(set (pc) (match_operand:SI 0 "address_operand" "p"))]  ""  "jmp %a0"  [(set_attr "type" "uncond_branch")   (set_attr "length" "2")]) (define_insn "tablejump"  [(set (pc) (match_operand:SI 0 "address_operand" "p"))   (use (label_ref (match_operand 1 "" "")))]  ""  "jmp %a0"  [(set_attr "type" "uncond_branch")   (set_attr "length" "2")])(define_expand "call"  ;; operands[1] is stack_size_rtx  ;; operands[2] is next_arg_register  [(parallel [(call (match_operand:SI 0 "call_operand" "")		    (match_operand 1 "" ""))	     (clobber (reg:SI 14))])]  ""  "")(define_insn "*call_via_reg"  [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))	 (match_operand 1 "" ""))   (clobber (reg:SI 14))]  ""  "jl %0"  [(set_attr "type" "call")   (set_attr "length" "2")])(define_insn "*call_via_label"  [(call (mem:SI (match_operand:SI 0 "call_address_operand" ""))	 (match_operand 1 "" ""))   (clobber (reg:SI 14))]  ""  "*{  int call26_p = call26_operand (operands[0], FUNCTION_MODE);  if (! call26_p)    {      /* We may not be able to reach with a `bl' insn so punt and leave it to	 the linker.	 We do this here, rather than doing a force_reg in the define_expand	 so these insns won't be separated, say by scheduling, thus simplifying	 the linker.  */      return \"seth r14,%T0\;add3 r14,r14,%B0\;jl r14\";    }  else    return \"bl %0\";}"  [(set_attr "type" "call")   (set (attr "length")	(if_then_else (eq (symbol_ref "call26_operand (operands[0], FUNCTION_MODE)")			  (const_int 0))		      (const_int 12) ; 10 + 2 for nop filler		      ; The return address must be on a 4 byte boundary so		      ; there's no point in using a value of 2 here.  A 2 byte		      ; insn may go in the left slot but we currently can't		      ; use such knowledge.		      (const_int 4)))])(define_expand "call_value"  ;; operand 2 is stack_size_rtx  ;; operand 3 is next_arg_register  [(parallel [(set (match_operand 0 "register_operand" "=r")		   (call (match_operand:SI 1 "call_operand" "")			 (match_operand 2 "" "")))	     (clobber (reg:SI 14))])]  ""  "")(define_insn "*call_value_via_reg"  [(set (match_operand 0 "register_operand" "=r")	(call (mem:SI (match_operand:SI 1 "register_operand" "r"))	      (match_operand 2 "" "")))   (clobber (reg:SI 14))]  ""  "jl %1"  [(set_attr "type" "call")   (set_attr "length" "2")])(define_insn "*call_value_via_label"  [(set (match_operand 0 "register_operand" "=r")	(call (mem:SI (match_operand:SI 1 "call_address_operand" ""))	      (match_operand 2 "" "")))   (clobber (reg:SI 14))]  ""  "*{  int call26_p = call26_operand (operands[1], FUNCTION_MODE);  if (! call26_p)    {      /* We may not be able to reach with a `bl' insn so punt and leave it to	 the linker.	 We do this here, rather than doing a force_reg in the define_expand	 so these insns won't be separated, say by scheduling, thus simplifying	 the linker.  */      return \"seth r14,%T1\;add3 r14,r14,%B1\;jl r14\";    }  else    return \"bl %1\";}"  [(set_attr "type" "call")   (set (attr "length")	(if_then_else (eq (symbol_ref "call26_operand (operands[1], FUNCTION_MODE)")			  (const_int 0))		      (const_int 12) ; 10 + 2 for nop filler		      ; The return address must be on a 4 byte boundary so		      ; there's no point in using a value of 2 here.  A 2 byte		      ; insn may go in the left slot but we currently can't		      ; use such knowledge.		      (const_int 4)))])(define_insn "nop"  [(const_int 0)]  ""  "nop"  [(set_attr "type" "int2")   (set_attr "length" "2")]);; UNSPEC_VOLATILE is considered to use and clobber all hard registers and;; all of memory.  This blocks insns from being moved across this point.(define_insn "blockage"  [(unspec_volatile [(const_int 0)] 0)]  ""  "");; Special pattern to flush the icache.(define_insn "flush_icache"  [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0)]  ""  "* return \"nop ; flush-icache\";"  [(set_attr "type" "int2")   (set_attr "length" "2")]);; Conditional move instructions;; Based on those done for the d10v(define_expand "movsicc"  [   (set (match_operand:SI 0 "register_operand" "r")	(if_then_else:SI (match_operand 1 "" "")			 (match_operand:SI 2 "conditional_move_operand" "O")			 (match_operand:SI 3 "conditional_move_operand" "O")        )   )  ]  ""  "{  if (! zero_and_one (operands [2], operands [3]))    FAIL;  /* Generate the comparision that will set the carry flag.  */  operands[1] = gen_compare ((int)GET_CODE (operands[1]), m32r_compare_op0,			     m32r_compare_op1, TRUE);  /* See other movsicc pattern below for reason why.  */  emit_insn (gen_blockage());}");; Generate the conditional instructions based on how the carry flag is examined.(define_insn "*movsicc_internal"  [(set (match_operand:SI 0 "register_operand" "r")	(if_then_else:SI (match_operand 1 "carry_compare_operand" "")			 (match_operand:SI 2 "conditional_move_operand" "O")			 (match_operand:SI 3 "conditional_move_operand" "O")        )   )]  "zero_and_one (operands [2], operands[3])"  "* return emit_cond_move (operands, insn);"  [(set_attr "type" "multi")   (set_attr "length" "8")  ])(define_insn "movcc_insn"  [(set (match_operand:SI 0 "register_operand" "=r")	(reg:SI 17))]  ""  "mvfc %0, cbr"  [(set_attr "type" "misc")   (set_attr "length" "2")]);; Split up troublesome insns for better scheduling.;; Peepholes go at the end.;; ??? Setting the type attribute may not be useful, but for completeness;; we do it.(define_peephole  [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")			 (const_int 4)))        (match_operand:SI 1 "register_operand" "r"))]  "0 && dead_or_set_p (insn, operands[0])"  "st %1,@+%0"  [(set_attr "type" "store2")   (set_attr "length" "2")]);; This case is triggered by compiling this code:;; ;; extern void sub(int *);;; void main (void);; {;;   int i=2,j=3,k;;;   while (i < j)  sub(&k);;;   i = j / k;;;   sub(&i);;;   i = j - k;;;   sub(&i);;; };;;; Without the peephole the following assembler is generated for the;; divide and subtract expressions:;;;;         div r5,r4     ;;         mv r4,r5      ;;         st r4,@(4,sp) ;;         bl sub;; ;; Simialr code is produced for the subtract expression.  With this;; peephole the redundant move is eliminated.;;;; This optimisation onbly works if PRESERVE_DEATH_INFO_REGNO_P is;; defined in m32r.h(define_peephole  [(set (match_operand:SI 0 "register_operand" "r")        (match_operand:SI 1 "register_operand" "r")   )   (set (mem:SI (plus: SI (match_operand:SI 2 "register_operand" "r")                (match_operand:SI 3 "immediate_operand" "J")))        (match_dup 0)   )  ]  "0 && dead_or_set_p (insn, operands [0])"  "st %1,@(%3,%2)"  [(set_attr "type" "store4")   (set_attr "length" "4")  ]);; Block moves, see m32r.c for more details.;; Argument 0 is the destination;; Argument 1 is the source;; Argument 2 is the length;; Argument 3 is the alignment(define_expand "movstrsi"  [(parallel [(set (match_operand:BLK 0 "general_operand" "")		   (match_operand:BLK 1 "general_operand" ""))	      (use (match_operand:SI  2 "immediate_operand" ""))	      (use (match_operand:SI  3 "immediate_operand" ""))])]  ""  "{  if (operands[0])		/* avoid unused code messages */    {      m32r_expand_block_move (operands);      DONE;    }}");; Insn generated by block moves(define_insn "movstrsi_internal"  [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))	;; destination	(mem:BLK (match_operand:SI 1 "register_operand" "r")))	;; source   (use (match_operand:SI 2 "m32r_block_immediate_operand" "J"));; # bytes to move   (set (match_dup 0) (plus:SI (match_dup 0) (minus:SI (match_dup 2) (const_int 4))))   (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))   (clobber (match_scratch:SI 3 "=&r"))				;; temp 1   (clobber (match_scratch:SI 4 "=&r"))]			;; temp 2  ""  "* return m32r_output_block_move (insn, operands);"  [(set_attr "type"	"store8")   (set_attr "length"	"72")]) ;; Maximum

⌨️ 快捷键说明

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