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

📄 mn10200.md

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 MD
📖 第 1 页 / 共 4 页
字号:
     Otherwise we allow optabs.c to open code the operation.  */  if (GET_CODE (operands[2]) == CONST_INT      && (INTVAL (operands[2]) <= 2))    {      int count = INTVAL (operands[2]);      emit_move_insn (operands[0], operands[1]);      while (count > 0)	{	  emit_insn (gen_rtx (SET, SImode, operands[0],				   gen_rtx (LSHIFTRT, SImode,					    operands[0], GEN_INT (1))));	  count--;	}      DONE;    }  else if (rtx_equal_function_value_matters	   && (GET_CODE (operands[2]) != CONST_INT	       || INTVAL (operands[2]) <= 15))    {      rtx ret, insns;      start_sequence ();      ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__lshrsi3\"),				     NULL_RTX, 1, SImode, 2, operands[1],				     SImode, operands[2], HImode);      insns = get_insns ();      end_sequence ();      emit_libcall_block (insns, operands[0], ret,			  gen_rtx (LSHIFTRT, SImode, operands[1], operands[2]));      DONE;    }  else    FAIL;}");; LSHIFTRT one bit.(define_insn ""  [(set (match_operand:SI 0 "general_operand" "=d")	(lshiftrt:SI (match_operand:SI 1 "general_operand" "0")		     (const_int 1)))]  ""  "lsr %H0\;ror %L0"  [(set_attr "cc" "clobber")])(define_expand "ashrsi3"  [(set (match_operand:SI 0 "register_operand" "")	(ashiftrt:SI (match_operand:SI 1 "register_operand" "")		     (match_operand:HI 2 "general_operand" "")))]  ""  "{  /* For small shifts, just emit a series of single bit shifts inline.     For other constant shift counts smaller than a word or non-constant     shift counts we call out to a library call during RTL generation time;     after RTL generation time we allow optabs.c to open code the operation.     See comments in addsi3/subsi3 expanders.     Otherwise we allow optabs.c to open code the operation.  */  if (GET_CODE (operands[2]) == CONST_INT      && (INTVAL (operands[2]) <= 2))    {      int count = INTVAL (operands[2]);      emit_move_insn (operands[0], operands[1]);      while (count > 0)	{	  emit_insn (gen_rtx (SET, SImode, operands[0],				   gen_rtx (ASHIFTRT, SImode,					    operands[0], GEN_INT (1))));	  count--;	}      DONE;    }  else if (rtx_equal_function_value_matters	   && (GET_CODE (operands[2]) != CONST_INT	       || INTVAL (operands[2]) <= 15))    {      rtx ret, insns;      start_sequence ();      ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__ashrsi3\"),				     NULL_RTX, 1, SImode, 2, operands[1],				     SImode, operands[2], HImode);      insns = get_insns ();      end_sequence ();      emit_libcall_block (insns, operands[0], ret,			  gen_rtx (ASHIFTRT, SImode, operands[1], operands[2]));      DONE;    }  else    FAIL;}");; ASHIFTRT one bit.(define_insn ""  [(set (match_operand:SI 0 "general_operand" "=d")	(ashiftrt:SI (match_operand:SI 1 "general_operand" "0")		     (const_int 1)))]  ""  "asr %H0\;ror %L0"  [(set_attr "cc" "clobber")]);; ----------------------------------------------------------------------;; FP INSTRUCTIONS;; ----------------------------------------------------------------------;;;; The mn102 series does not have floating point instructions, but since;; FP values are held in integer regs, we can clear the high bit easily;; which gives us an efficient inline floating point absolute value.;;;; Similarly for negation of a FP value.;;(define_expand "abssf2"  [(set (match_operand:SF 0 "register_operand" "")        (abs:SF (match_operand:SF 1 "register_operand" "")))]  ""  "{  rtx target, result, insns;  start_sequence ();  target = operand_subword (operands[0], 1, 1, SFmode);  result = expand_binop (HImode, and_optab,			 operand_subword_force (operands[1], 1, SFmode),			 GEN_INT(0x7fff), target, 0, OPTAB_WIDEN);  if (result == 0)    abort ();  if (result != target)    emit_move_insn (result, target);  emit_move_insn (operand_subword (operands[0], 0, 1, SFmode),		  operand_subword_force (operands[1], 0, SFmode));  insns = get_insns ();  end_sequence ();  emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);  DONE;}")(define_expand "negsf2"  [(set (match_operand:SF 0 "register_operand" "")        (neg:SF (match_operand:SF 1 "register_operand" "")))]  ""  "{  rtx target, result, insns;  start_sequence ();  target = operand_subword (operands[0], 1, 1, SFmode);  result = expand_binop (HImode, xor_optab,			 operand_subword_force (operands[1], 1, SFmode),			 GEN_INT(0x8000), target, 0, OPTAB_WIDEN);  if (result == 0)    abort ();  if (result != target)    emit_move_insn (result, target);  emit_move_insn (operand_subword (operands[0], 0, 1, SFmode),		  operand_subword_force (operands[1], 0, SFmode));  insns = get_insns ();  end_sequence ();  emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);  DONE;}");; ----------------------------------------------------------------------;; PROLOGUE/EPILOGUE;; ----------------------------------------------------------------------(define_expand "prologue"  [(const_int 0)]  ""  "expand_prologue (); DONE;")(define_insn "outline_prologue_call"  [(const_int 1)]  ""  "jsr ___prologue"  [(set_attr "cc" "clobber")])(define_expand "epilogue"  [(return)]  ""  "{  expand_epilogue ();  DONE;}")(define_insn "outline_epilogue_call_a0"  [(const_int 2)]  ""  "jsr ___epilogue_a0"  [(set_attr "cc" "clobber")])(define_insn "outline_epilogue_call_d0"  [(const_int 3)]  ""  "jsr ___epilogue_d0"  [(set_attr "cc" "clobber")])(define_insn "outline_epilogue_jump"  [(const_int 4)]  ""  "jmp ___epilogue_noreturn"  [(set_attr "cc" "clobber")])(define_insn "return"  [(return)]  "reload_completed && total_frame_size () == 0   && !current_function_needs_context"  "*{  rtx next = next_active_insn (insn);  if (next      && GET_CODE (next) == JUMP_INSN      && GET_CODE (PATTERN (next)) == RETURN)    return \"\";  return \"rts\";}"  [(set_attr "cc" "clobber")])(define_insn "return_internal"  [(const_int 0)   (return)]  ""  "rts"  [(set_attr "cc" "clobber")]);; These are special combiner patterns to improve array/pointer accesses.;;;; A typical sequence involves extending an integer/char, shifting it left;; a few times, then truncating the value to PSImode.;;;; This first pattern combines the shifting & truncation operations, by;; itself it is a win because the shifts end up occurring in PSImode instead;; of SImode.  However, it has the secondary effect of giving us the;; opportunity to match patterns which allow us to remove the initial;; extension completely, which is a big win.(define_insn ""  [(set (match_operand:PSI 0 "general_operand" "=d,d,a,da")	(truncate:PSI	  (ashift:SI (match_operand:SI 1 "general_operand" "d,m,m,i")		     (match_operand:HI 2 "const_int_operand" "i,i,i,i"))))]  ""  "*{  int count = INTVAL (operands[2]);  if (which_alternative == 0)    output_asm_insn (\"jsr ___truncsipsi2_%1_%0\", operands);  else if (which_alternative == 1)    output_asm_insn (\"movx %A1,%0\", operands);  else    output_asm_insn (\" mov %1,%0\", operands);  while (count)    {      output_asm_insn (\"add %0,%0\", operands);      count--;    }  return \"\";}"  [(set_attr "cc" "clobber")]);; Similarly, except that we also have zero/sign extension of the;; original operand.  */(define_insn ""  [(set (match_operand:PSI 0 "general_operand" "=d,d")	(truncate:PSI	  (ashift:SI	    (zero_extend:SI (match_operand:HI 1 "general_operand" "0,dim"))	    (match_operand:HI 2 "const_int_operand" "i,i"))))]  ""  "*{  int count = INTVAL (operands[2]);  /* First extend operand 1 to PSImode.  */  if (which_alternative == 0)    output_asm_insn (\"extxu %0\", operands);  else    output_asm_insn (\"mov %1,%0\;extxu %0\", operands);  /* Now do the shifting.  */  while (count)    {      output_asm_insn (\"add %0,%0\", operands);      count--;    }  return \"\";}"  [(set_attr "cc" "clobber")])(define_insn ""  [(set (match_operand:PSI 0 "general_operand" "=d,d,d")	(truncate:PSI	  (ashift:SI	    (sign_extend:SI (match_operand:HI 1 "general_operand" "0,di,m"))	    (match_operand:HI 2 "const_int_operand" "i,i,i"))))]  ""  "*{  int count = INTVAL (operands[2]);  /* First extend operand 1 to PSImode.  */  if (which_alternative == 0)    output_asm_insn (\"extx %0\", operands);  else if (which_alternative == 1)    output_asm_insn (\"mov %1,%0\;extx %0\", operands);  else    output_asm_insn (\"mov %1,%0\", operands);  /* Now do the shifting.  */  while (count)    {      output_asm_insn (\"add %0,%0\", operands);      count--;    }  return \"\";}"  [(set_attr "cc" "clobber")])(define_insn ""  [(set (match_operand:PSI 0 "general_operand" "=d,d,d")	(truncate:PSI	  (ashift:SI	    (sign_extend:SI	      (zero_extend:HI (match_operand:QI 1 "general_operand" "0,di,m")))	    (match_operand:HI 2 "const_int_operand" "i,i,i"))))]  ""  "*{  int count = INTVAL (operands[2]);  /* First extend operand 1 to PSImode.  */  if (which_alternative == 0)    output_asm_insn (\"extxbu %0\", operands);  else if (which_alternative == 1)    output_asm_insn (\"mov %1,%0\;extxbu %0\", operands);  else    output_asm_insn (\"movbu %1,%0\", operands);  /* Now do the shifting.  */  while (count)    {      output_asm_insn (\"add %0,%0\", operands);      count--;    }  return \"\";}"  [(set_attr "cc" "clobber")])(define_insn ""  [(set (match_operand:PSI 0 "general_operand" "=d,d,d")	(truncate:PSI	  (ashift:SI	    (sign_extend:SI	      (match_operand:QI 1 "general_operand" "0,di,m"))	    (match_operand:HI 2 "const_int_operand" "i,i,i"))))]  ""  "*{  int count = INTVAL (operands[2]);  /* First extend operand 1 to PSImode.  */  if (which_alternative == 0)    output_asm_insn (\"extxb %0\", operands);  else if (which_alternative == 1)    output_asm_insn (\"mov %1,%0\;extxb %0\", operands);  else if (GET_CODE (XEXP (operands[1], 0)) == REG)    output_asm_insn (\"movbu %1,%0\;extxb %0\", operands);  else    output_asm_insn (\"movb %1,%0\", operands);  /* Now do the shifting.  */  while (count)    {      output_asm_insn (\"add %0,%0\", operands);      count--;    }  return \"\";}"  [(set_attr "cc" "clobber")]);; Try to combine consecutive updates of the stack pointer (or any;; other register for that matter).(define_peephole  [(set (match_operand:PSI 0 "register_operand" "=da")	(plus:PSI (match_dup 0)		  (match_operand 1 "const_int_operand" "")))   (set (match_dup 0)	(plus:PSI (match_dup 0)		  (match_operand 2 "const_int_operand" "")))]  ""  "*{  operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));  return \"add %1,%0\";}"  [(set_attr "cc" "clobber")]);;;; We had patterns to check eq/ne, but the they don't work because;; 0x80000000 + 0x80000000 = 0x0 with a carry out.;;;; The Z flag and C flag would be set, and we have no way to;; check for the Z flag set and C flag clear.;;;; This will work on the mn10200 because we can check the ZX flag;; if the comparison is in HImode.(define_peephole  [(set (cc0) (match_operand:HI 0 "register_operand" "d"))   (set (pc) (if_then_else (ge (cc0) (const_int 0))			   (match_operand 1 "" "")			   (pc)))]  "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"  "add %0,%0\;bcc %1"  [(set_attr "cc" "clobber")])(define_peephole  [(set (cc0) (match_operand:HI 0 "register_operand" "d"))   (set (pc) (if_then_else (lt (cc0) (const_int 0))			   (match_operand 1 "" "")			   (pc)))]  "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"  "add %0,%0\;bcs %1"  [(set_attr "cc" "clobber")])(define_peephole  [(set (cc0) (match_operand:HI 0 "register_operand" "d"))   (set (pc) (if_then_else (ge (cc0) (const_int 0))			   (pc)			   (match_operand 1 "" "")))]  "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"  "add %0,%0\;bcs %1"  [(set_attr "cc" "clobber")])(define_peephole  [(set (cc0) (match_operand:HI 0 "register_operand" "d"))   (set (pc) (if_then_else (lt (cc0) (const_int 0))			   (pc)			   (match_operand 1 "" "")))]  "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"  "add %0,%0\;bcc %1"  [(set_attr "cc" "clobber")])(define_peephole  [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))   (set (pc) (if_then_else (ge (cc0) (const_int 0))			   (match_operand 1 "" "")			   (pc)))]  "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"  "add %0,%0\;bccx %1"  [(set_attr "cc" "clobber")])(define_peephole  [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))   (set (pc) (if_then_else (lt (cc0) (const_int 0))			   (match_operand 1 "" "")			   (pc)))]  "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"  "add %0,%0\;bcsx %1"  [(set_attr "cc" "clobber")])(define_peephole  [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))   (set (pc) (if_then_else (ge (cc0) (const_int 0))			   (pc)			   (match_operand 1 "" "")))]  "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"  "add %0,%0\;bcsx %1"  [(set_attr "cc" "clobber")])(define_peephole  [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))   (set (pc) (if_then_else (lt (cc0) (const_int 0))			   (pc)			   (match_operand 1 "" "")))]  "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"  "add %0,%0\;bccx %1"  [(set_attr "cc" "clobber")]);; We call out to library routines to perform 32bit addition and subtraction;; operations (see addsi3/subsi3 expanders for why).  These peepholes catch;; the trivial case where the operation could be done with an add;addc or;; sub;subc sequence.(define_peephole  [(set (mem:SI (reg:PSI 7)) (reg:SI 2))   (set (reg:SI 0) (call (match_operand:QI 1 "general_operand" "")			 (match_operand:HI 2 "general_operand" "")))]  "GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF   && strcmp (XSTR (XEXP (operands[1], 0), 0), \"__addsi3\") == 0"  "add d2,d0\;addc d3,d1"  [(set_attr "cc" "clobber")])(define_peephole  [(set (mem:SI (reg:PSI 7)) (reg:SI 2))   (set (reg:SI 0) (call (match_operand:QI 1 "general_operand" "")			 (match_operand:HI 2 "general_operand" "")))]  "GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF   && strcmp (XSTR (XEXP (operands[1], 0), 0), \"__subsi3\") == 0"  "sub d2,d0\;subc d3,d1"  [(set_attr "cc" "clobber")])

⌨️ 快捷键说明

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