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

📄 explow.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 3 页
字号:
  /* We get better cse by rejecting indirect addressing at this stage.     Let the combiner create indirect addresses where appropriate.     For now, generate the code so that the subexpressions useful to share     are visible.  But not if cse won't be done!  */  else    {      if (! cse_not_expected && GET_CODE (x) != REG)	x = break_out_memory_refs (x);      /* At this point, any valid address is accepted.  */      GO_IF_LEGITIMATE_ADDRESS (mode, x, win);      /* If it was valid before but breaking out memory refs invalidated it,	 use it the old way.  */      if (memory_address_p (mode, oldx))	goto win2;      /* Perform machine-dependent transformations on X	 in certain cases.  This is not necessary since the code	 below can handle all possible cases, but machine-dependent	 transformations can make better code.  */      LEGITIMIZE_ADDRESS (x, oldx, mode, win);      /* PLUS and MULT can appear in special ways	 as the result of attempts to make an address usable for indexing.	 Usually they are dealt with by calling force_operand, below.	 But a sum containing constant terms is special	 if removing them makes the sum a valid address:	 then we generate that address in a register	 and index off of it.  We do this because it often makes	 shorter code, and because the addresses thus generated	 in registers often become common subexpressions.  */      if (GET_CODE (x) == PLUS)	{	  rtx constant_term = const0_rtx;	  rtx y = eliminate_constant_term (x, &constant_term);	  if (constant_term == const0_rtx	      || ! memory_address_p (mode, y))	    x = force_operand (x, NULL_RTX);	  else	    {	      y = gen_rtx (PLUS, GET_MODE (x), copy_to_reg (y), constant_term);	      if (! memory_address_p (mode, y))		x = force_operand (x, NULL_RTX);	      else		x = y;	    }	}      else if (GET_CODE (x) == MULT || GET_CODE (x) == MINUS)	x = force_operand (x, NULL_RTX);      /* If we have a register that's an invalid address,	 it must be a hard reg of the wrong class.  Copy it to a pseudo.  */      else if (GET_CODE (x) == REG)	x = copy_to_reg (x);      /* Last resort: copy the value to a register, since	 the register is a valid address.  */      else	x = force_reg (Pmode, x);      goto done;    win2:      x = oldx;    win:      if (flag_force_addr && ! cse_not_expected && GET_CODE (x) != REG	  /* Don't copy an addr via a reg if it is one of our stack slots.  */	  && ! (GET_CODE (x) == PLUS		&& (XEXP (x, 0) == virtual_stack_vars_rtx		    || XEXP (x, 0) == virtual_incoming_args_rtx)))	{	  if (general_operand (x, Pmode))	    x = force_reg (Pmode, x);	  else	    x = force_operand (x, NULL_RTX);	}    } done:  /* If we didn't change the address, we are done.  Otherwise, mark     a reg as a pointer if we have REG or REG + CONST_INT.  */  if (oldx == x)    return x;  else if (GET_CODE (x) == REG)    mark_reg_pointer (x);  else if (GET_CODE (x) == PLUS	   && GET_CODE (XEXP (x, 0)) == REG	   && GET_CODE (XEXP (x, 1)) == CONST_INT)    mark_reg_pointer (XEXP (x, 0));  /* OLDX may have been the address on a temporary.  Update the address     to indicate that X is now used.  */  update_temp_slot_address (oldx, x);  return x;}/* Like `memory_address' but pretend `flag_force_addr' is 0.  */rtxmemory_address_noforce (mode, x)     enum machine_mode mode;     rtx x;{  int ambient_force_addr = flag_force_addr;  rtx val;  flag_force_addr = 0;  val = memory_address (mode, x);  flag_force_addr = ambient_force_addr;  return val;}/* Convert a mem ref into one with a valid memory address.   Pass through anything else unchanged.  */rtxvalidize_mem (ref)     rtx ref;{  if (GET_CODE (ref) != MEM)    return ref;  if (memory_address_p (GET_MODE (ref), XEXP (ref, 0)))    return ref;  /* Don't alter REF itself, since that is probably a stack slot.  */  return change_address (ref, GET_MODE (ref), XEXP (ref, 0));}/* Return a modified copy of X with its memory address copied   into a temporary register to protect it from side effects.   If X is not a MEM, it is returned unchanged (and not copied).   Perhaps even if it is a MEM, if there is no need to change it.  */rtxstabilize (x)     rtx x;{  register rtx addr;  if (GET_CODE (x) != MEM)    return x;  addr = XEXP (x, 0);  if (rtx_unstable_p (addr))    {      rtx temp = copy_all_regs (addr);      rtx mem;      if (GET_CODE (temp) != REG)	temp = copy_to_reg (temp);      mem = gen_rtx (MEM, GET_MODE (x), temp);      /* Mark returned memref with in_struct if it's in an array or	 structure.  Copy const and volatile from original memref.  */      MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (x) || GET_CODE (addr) == PLUS;      RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (x);      MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (x);      return mem;    }  return x;}/* Copy the value or contents of X to a new temp reg and return that reg.  */rtxcopy_to_reg (x)     rtx x;{  register rtx temp = gen_reg_rtx (GET_MODE (x));   /* If not an operand, must be an address with PLUS and MULT so     do the computation.  */   if (! general_operand (x, VOIDmode))    x = force_operand (x, temp);    if (x != temp)    emit_move_insn (temp, x);  return temp;}/* Like copy_to_reg but always give the new register mode Pmode   in case X is a constant.  */rtxcopy_addr_to_reg (x)     rtx x;{  return copy_to_mode_reg (Pmode, x);}/* Like copy_to_reg but always give the new register mode MODE   in case X is a constant.  */rtxcopy_to_mode_reg (mode, x)     enum machine_mode mode;     rtx x;{  register rtx temp = gen_reg_rtx (mode);    /* If not an operand, must be an address with PLUS and MULT so     do the computation.  */   if (! general_operand (x, VOIDmode))    x = force_operand (x, temp);  if (GET_MODE (x) != mode && GET_MODE (x) != VOIDmode)    abort ();  if (x != temp)    emit_move_insn (temp, x);  return temp;}/* Load X into a register if it is not already one.   Use mode MODE for the register.   X should be valid for mode MODE, but it may be a constant which   is valid for all integer modes; that's why caller must specify MODE.   The caller must not alter the value in the register we return,   since we mark it as a "constant" register.  */rtxforce_reg (mode, x)     enum machine_mode mode;     rtx x;{  register rtx temp, insn, set;  if (GET_CODE (x) == REG)    return x;  temp = gen_reg_rtx (mode);  insn = emit_move_insn (temp, x);  /* Let optimizers know that TEMP's value never changes     and that X can be substituted for it.  Don't get confused     if INSN set something else (such as a SUBREG of TEMP).  */  if (CONSTANT_P (x)      && (set = single_set (insn)) != 0      && SET_DEST (set) == temp)    {      rtx note = find_reg_note (insn, REG_EQUAL, NULL_RTX);      if (note)	XEXP (note, 0) = x;      else	REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, x, REG_NOTES (insn));    }  return temp;}/* If X is a memory ref, copy its contents to a new temp reg and return   that reg.  Otherwise, return X.  */rtxforce_not_mem (x)     rtx x;{  register rtx temp;  if (GET_CODE (x) != MEM || GET_MODE (x) == BLKmode)    return x;  temp = gen_reg_rtx (GET_MODE (x));  emit_move_insn (temp, x);  return temp;}/* Copy X to TARGET (if it's nonzero and a reg)   or to a new temp reg and return that reg.   MODE is the mode to use for X in case it is a constant.  */rtxcopy_to_suggested_reg (x, target, mode)     rtx x, target;     enum machine_mode mode;{  register rtx temp;  if (target && GET_CODE (target) == REG)    temp = target;  else    temp = gen_reg_rtx (mode);  emit_move_insn (temp, x);  return temp;}/* Return the mode to use to store a scalar of TYPE and MODE.   PUNSIGNEDP points to the signedness of the type and may be adjusted   to show what signedness to use on extension operations.   FOR_CALL is non-zero if this call is promoting args for a call.  */enum machine_modepromote_mode (type, mode, punsignedp, for_call)     tree type;     enum machine_mode mode;     int *punsignedp;     int for_call;{  enum tree_code code = TREE_CODE (type);  int unsignedp = *punsignedp;#ifdef PROMOTE_FOR_CALL_ONLY  if (! for_call)    return mode;#endif  switch (code)    {#ifdef PROMOTE_MODE    case INTEGER_TYPE:   case ENUMERAL_TYPE:   case BOOLEAN_TYPE:    case CHAR_TYPE:      case REAL_TYPE:       case OFFSET_TYPE:      PROMOTE_MODE (mode, unsignedp, type);      break;#endif#ifdef POINTERS_EXTEND_UNSIGNED    case POINTER_TYPE:      mode = Pmode;      unsignedp = POINTERS_EXTEND_UNSIGNED;      break;#endif    }  *punsignedp = unsignedp;  return mode;}/* Adjust the stack pointer by ADJUST (an rtx for a number of bytes).   This pops when ADJUST is positive.  ADJUST need not be constant.  */voidadjust_stack (adjust)     rtx adjust;{  rtx temp;  adjust = protect_from_queue (adjust, 0);  if (adjust == const0_rtx)    return;  temp = expand_binop (Pmode,#ifdef STACK_GROWS_DOWNWARD		       add_optab,#else		       sub_optab,#endif		       stack_pointer_rtx, adjust, stack_pointer_rtx, 0,		       OPTAB_LIB_WIDEN);  if (temp != stack_pointer_rtx)    emit_move_insn (stack_pointer_rtx, temp);}/* Adjust the stack pointer by minus ADJUST (an rtx for a number of bytes).   This pushes when ADJUST is positive.  ADJUST need not be constant.  */voidanti_adjust_stack (adjust)     rtx adjust;{  rtx temp;  adjust = protect_from_queue (adjust, 0);  if (adjust == const0_rtx)    return;  temp = expand_binop (Pmode,#ifdef STACK_GROWS_DOWNWARD		       sub_optab,#else		       add_optab,#endif		       stack_pointer_rtx, adjust, stack_pointer_rtx, 0,		       OPTAB_LIB_WIDEN);  if (temp != stack_pointer_rtx)    emit_move_insn (stack_pointer_rtx, temp);}/* Round the size of a block to be pushed up to the boundary required   by this machine.  SIZE is the desired size, which need not be constant.  */rtxround_push (size)     rtx size;{#ifdef STACK_BOUNDARY  int align = STACK_BOUNDARY / BITS_PER_UNIT;  if (align == 1)    return size;  if (GET_CODE (size) == CONST_INT)    {      int new = (INTVAL (size) + align - 1) / align * align;      if (INTVAL (size) != new)	size = GEN_INT (new);    }  else    {      /* CEIL_DIV_EXPR needs to worry about the addition overflowing,	 but we know it can't.  So add ourselves and then do TRUNC_DIV_EXPR. */      size = expand_binop (Pmode, add_optab, size, GEN_INT (align - 1),			   NULL_RTX, 1, OPTAB_LIB_WIDEN);      size = expand_divmod (0, TRUNC_DIV_EXPR, Pmode, size, GEN_INT (align),			    NULL_RTX, 1);      size = expand_mult (Pmode, size, GEN_INT (align), NULL_RTX, 1);

⌨️ 快捷键说明

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