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

📄 sparc.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
	  case CCXmode :	  case CCFPEmode :	  case CCFPmode :	    break;	  default :	    abort ();	}	emit_insn (gen_rtx (SET, VOIDmode, operands[0], const0_rtx));	emit_insn (gen_rtx (SET, VOIDmode, operands[0],			    gen_rtx (IF_THEN_ELSE, VOIDmode,				     gen_rtx (compare_code,					      GET_MODE (operands[1]),					      operands[1], const0_rtx),					      const1_rtx, operands[0])));	return 1;    }}/* Emit a conditional jump insn for the v9 architecture using comparison code   CODE and jump target LABEL.   This function exists to take advantage of the v9 brxx insns.  */voidemit_v9_brxx_insn (code, op0, label)     enum rtx_code code;     rtx op0, label;{  emit_jump_insn (gen_rtx (SET, VOIDmode,			   pc_rtx,			   gen_rtx (IF_THEN_ELSE, VOIDmode,				    gen_rtx (code, GET_MODE (op0),					     op0, const0_rtx),				    gen_rtx (LABEL_REF, VOIDmode, label),				    pc_rtx)));}/* Return nonzero if a return peephole merging return with   setting of output register is ok.  */intleaf_return_peephole_ok (){  return (actual_fsize == 0);}/* Return nonzero if TRIAL can go into the function epilogue's   delay slot.  SLOT is the slot we are trying to fill.  */inteligible_for_epilogue_delay (trial, slot)     rtx trial;     int slot;{  rtx pat, src;  if (slot >= 1)    return 0;  if (GET_CODE (trial) != INSN      || GET_CODE (PATTERN (trial)) != SET)    return 0;  if (get_attr_length (trial) != 1)    return 0;  /* In the case of a true leaf function, anything can go into the delay slot.     A delay slot only exists however if the frame size is zero, otherwise     we will put an insn to adjust the stack after the return.  */  if (leaf_function)    {      if (leaf_return_peephole_ok ())	return (get_attr_in_uncond_branch_delay (trial) == IN_BRANCH_DELAY_TRUE);      return 0;    }  /* Otherwise, only operations which can be done in tandem with     a `restore' insn can go into the delay slot.  */  pat = PATTERN (trial);  if (GET_CODE (SET_DEST (pat)) != REG      || REGNO (SET_DEST (pat)) == 0      || REGNO (SET_DEST (pat)) >= 32      || REGNO (SET_DEST (pat)) < 24)    return 0;  src = SET_SRC (pat);  if (arith_operand (src, GET_MODE (src)))    return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (SImode);  if (arith_double_operand (src, GET_MODE (src)))    return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (DImode);  if (GET_CODE (src) == PLUS)    {      if (register_operand (XEXP (src, 0), SImode)	  && arith_operand (XEXP (src, 1), SImode))	return 1;      if (register_operand (XEXP (src, 1), SImode)	  && arith_operand (XEXP (src, 0), SImode))	return 1;      if (register_operand (XEXP (src, 0), DImode)	  && arith_double_operand (XEXP (src, 1), DImode))	return 1;      if (register_operand (XEXP (src, 1), DImode)	  && arith_double_operand (XEXP (src, 0), DImode))	return 1;    }  if (GET_CODE (src) == MINUS      && register_operand (XEXP (src, 0), SImode)      && small_int (XEXP (src, 1), VOIDmode))    return 1;  if (GET_CODE (src) == MINUS      && register_operand (XEXP (src, 0), DImode)      && !register_operand (XEXP (src, 1), DImode)      && arith_double_operand (XEXP (src, 1), DImode))    return 1;  return 0;}intshort_branch (uid1, uid2)     int uid1, uid2;{  unsigned int delta = insn_addresses[uid1] - insn_addresses[uid2];  if (delta + 1024 < 2048)    return 1;  /* warning ("long branch, distance %d", delta); */  return 0;}/* Return non-zero if REG is not used after INSN.   We assume REG is a reload reg, and therefore does   not live past labels or calls or jumps.  */intreg_unused_after (reg, insn)     rtx reg;     rtx insn;{  enum rtx_code code, prev_code = UNKNOWN;  while (insn = NEXT_INSN (insn))    {      if (prev_code == CALL_INSN && call_used_regs[REGNO (reg)])	return 1;      code = GET_CODE (insn);      if (GET_CODE (insn) == CODE_LABEL)	return 1;      if (GET_RTX_CLASS (code) == 'i')	{	  rtx set = single_set (insn);	  int in_src = set && reg_overlap_mentioned_p (reg, SET_SRC (set));	  if (set && in_src)	    return 0;	  if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))	    return 1;	  if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))	    return 0;	}      prev_code = code;    }  return 1;}/* The rtx for the global offset table which is a special form   that *is* a position independent symbolic constant.  */static rtx pic_pc_rtx;/* Ensure that we are not using patterns that are not OK with PIC.  */intcheck_pic (i)     int i;{  switch (flag_pic)    {    case 1:      if (GET_CODE (recog_operand[i]) == SYMBOL_REF	  || (GET_CODE (recog_operand[i]) == CONST	      && ! rtx_equal_p (pic_pc_rtx, recog_operand[i])))	abort ();    case 2:    default:      return 1;    }}/* Return true if X is an address which needs a temporary register when    reloaded while generating PIC code.  */intpic_address_needs_scratch (x)     rtx x;{  /* An address which is a symbolic plus a non SMALL_INT needs a temp reg.  */  if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS      && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF      && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT      && ! SMALL_INT (XEXP (XEXP (x, 0), 1)))    return 1;  return 0;}/* Legitimize PIC addresses.  If the address is already position-independent,   we return ORIG.  Newly generated position-independent addresses go into a   reg.  This is REG if non zero, otherwise we allocate register(s) as   necessary.  */rtxlegitimize_pic_address (orig, mode, reg)     rtx orig;     enum machine_mode mode;     rtx reg;{  if (GET_CODE (orig) == SYMBOL_REF)    {      rtx pic_ref, address;      rtx insn;      if (reg == 0)	{	  if (reload_in_progress || reload_completed)	    abort ();	  else	    reg = gen_reg_rtx (Pmode);	}      if (flag_pic == 2)	{	  /* If not during reload, allocate another temp reg here for loading	     in the address, so that these instructions can be optimized	     properly.  */	  rtx temp_reg = ((reload_in_progress || reload_completed)			  ? reg : gen_reg_rtx (Pmode));	  /* Must put the SYMBOL_REF inside an UNSPEC here so that cse	     won't get confused into thinking that these two instructions	     are loading in the true address of the symbol.  If in the	     future a PIC rtx exists, that should be used instead.  */	  emit_insn (gen_rtx (SET, VOIDmode, temp_reg,			      gen_rtx (HIGH, Pmode,				       gen_rtx (UNSPEC, Pmode,						gen_rtvec (1, orig),						0))));	  emit_insn (gen_rtx (SET, VOIDmode, temp_reg,			      gen_rtx (LO_SUM, Pmode, temp_reg,				       gen_rtx (UNSPEC, Pmode,						gen_rtvec (1, orig),						0))));	  address = temp_reg;	}      else	address = orig;      pic_ref = gen_rtx (MEM, Pmode,			 gen_rtx (PLUS, Pmode,				  pic_offset_table_rtx, address));      current_function_uses_pic_offset_table = 1;      RTX_UNCHANGING_P (pic_ref) = 1;      insn = emit_move_insn (reg, pic_ref);      /* Put a REG_EQUAL note on this insn, so that it can be optimized	 by loop.  */      REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, orig,				  REG_NOTES (insn));      return reg;    }  else if (GET_CODE (orig) == CONST)    {      rtx base, offset;      if (GET_CODE (XEXP (orig, 0)) == PLUS	  && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)	return orig;      if (reg == 0)	{	  if (reload_in_progress || reload_completed)	    abort ();	  else	    reg = gen_reg_rtx (Pmode);	}      if (GET_CODE (XEXP (orig, 0)) == PLUS)	{	  base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);	  offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,					 base == reg ? 0 : reg);	}      else	abort ();      if (GET_CODE (offset) == CONST_INT)	{	  if (SMALL_INT (offset))	    return plus_constant_for_output (base, INTVAL (offset));	  else if (! reload_in_progress && ! reload_completed)	    offset = force_reg (Pmode, offset);	  else	    /* If we reach here, then something is seriously wrong.  */	    abort ();	}      return gen_rtx (PLUS, Pmode, base, offset);    }  else if (GET_CODE (orig) == LABEL_REF)    current_function_uses_pic_offset_table = 1;  return orig;}/* Set up PIC-specific rtl.  This should not cause any insns   to be emitted.  */voidinitialize_pic (){}/* Emit special PIC prologues and epilogues.  */voidfinalize_pic (){  /* The table we use to reference PIC data.  */  rtx global_offset_table;  /* Labels to get the PC in the prologue of this function.  */  rtx l1, l2;  rtx seq;  int orig_flag_pic = flag_pic;  if (current_function_uses_pic_offset_table == 0)    return;  if (! flag_pic)    abort ();  flag_pic = 0;  l1 = gen_label_rtx ();  l2 = gen_label_rtx ();  start_sequence ();  emit_label (l1);  /* Note that we pun calls and jumps here!  */  emit_jump_insn (gen_rtx (PARALLEL, VOIDmode,                         gen_rtvec (2,                                    gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (LABEL_REF, VOIDmode, l2)),                                    gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 15), gen_rtx (LABEL_REF, VOIDmode, l2)))));  emit_label (l2);  /* Initialize every time through, since we can't easily     know this to be permanent.  */  global_offset_table = gen_rtx (SYMBOL_REF, Pmode, "_GLOBAL_OFFSET_TABLE_");  pic_pc_rtx = gen_rtx (CONST, Pmode,			gen_rtx (MINUS, Pmode,				 global_offset_table,				 gen_rtx (CONST, Pmode,					  gen_rtx (MINUS, Pmode,						   gen_rtx (LABEL_REF, VOIDmode, l1),						   pc_rtx))));  if (Pmode == DImode)    emit_insn (gen_rtx (PARALLEL, VOIDmode,			gen_rtvec (2,				   gen_rtx (SET, VOIDmode, pic_offset_table_rtx,					    gen_rtx (HIGH, Pmode, pic_pc_rtx)),				   gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, Pmode, 1)))));  else    emit_insn (gen_rtx (SET, VOIDmode, pic_offset_table_rtx,			gen_rtx (HIGH, Pmode, pic_pc_rtx)));  emit_insn (gen_rtx (SET, VOIDmode,		      pic_offset_table_rtx,		      gen_rtx (LO_SUM, Pmode,			       pic_offset_table_rtx, pic_pc_rtx)));  emit_insn (gen_rtx (SET, VOIDmode,		      pic_offset_table_rtx,		      gen_rtx (PLUS, Pmode,			       pic_offset_table_rtx, gen_rtx (REG, Pmode, 15))));  /* emit_insn (gen_rtx (ASM_INPUT, VOIDmode, "!#PROLOGUE# 1")); */  LABEL_PRESERVE_P (l1) = 1;  LABEL_PRESERVE_P (l2) = 1;  flag_pic = orig_flag_pic;  seq = gen_sequence ();  end_sequence ();  emit_insn_after (seq, get_insns ());  /* Need to emit this whether or not we obey regdecls,     since setjmp/longjmp can cause life info to screw up.  */  emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx));}/* Emit insns to move operands[1] into operands[0].   Return 1 if we have written out everything that needs to be done to   do the move.  Otherwise, return 0 and the caller will emit the move   normally.  */intemit_move_sequence (operands, mode)     rtx *operands;     enum machine_mode mode;{  register rtx operand0 = operands[0];  register rtx operand1 = operands[1];  if (CONSTANT_P (operand1) && flag_pic      && pic_address_needs_scratch (operand1))    operands[1] = operand1 = legitimize_pic_address (operand1, mode, 0);  /* Handle most common case first: storing into a register.  */  if (register_operand (operand0, mode))    {      if (register_operand (operand1, mode)	  || (GET_CODE (operand1) == CONST_INT && SMALL_INT (operand1))	  || (GET_CODE (operand1) == CONST_DOUBLE	      && arith_double_operand (operand1, DImode))	  || (GET_CODE (operand1) == HIGH && GET_MODE (operand1) != DImode)	  /* Only `general_operands' can come here, so MEM is ok.  */	  || GET_CODE (operand1) == MEM)	{	  /* Run this case quickly.  */	  emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1));	  return 1;	}    }  else if (GET_CODE (operand0) == MEM)    {      if (register_operand (operand1, mode) || operand1 == const0_rtx)	{	  /* Run this case quickly.  */	  emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1));	  return 1;	}      if (! reload_in_progress)	{	  operands[0] = validize_mem (operand0);	  operands[1] = operand1 = force_reg (mode, operand1);	}    }  /* Simplify the source if we need to.  Must handle DImode HIGH operators     here because such a move needs a clobber added.  */  if ((GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode))      || (GET_CODE (operand1) == HIGH && GET_MODE (operand1) == DImode))    {      if (flag_pic && symbolic_operand (operand1, mode))	{	  rtx temp_reg = reload_in_progress ? operand0 : 0;	  operands[1] = legitimize_pic_address (operand1, mode, temp_reg);	}      else if (GET_CODE (operand1) == CONST_INT	       ? (! SMALL_INT (operand1)		  && (INTVAL (operand1) & 0x3ff) != 0)	       : (GET_CODE (operand1) == CONST_DOUBLE		  ? ! arith_double_operand (operand1, DImode)		  : 1))	{	  /* For DImode values, temp must be operand0 because of the way	     HI and LO_SUM work.  The LO_SUM operator only copies half of	     the LSW from the dest of the HI operator.  If the LO_SUM dest is

⌨️ 快捷键说明

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