示例#1
0
/* Merge two sets of coalesced pseudos given correspondingly by
   pseudos REGNO1 and REGNO2 (more accurately merging REGNO2 group
   into REGNO1 group).	Set up COALESCED_PSEUDOS_BITMAP.  */
static void
merge_pseudos (int regno1, int regno2)
{
  int regno, first, first2, last, next;

  first = first_coalesced_pseudo[regno1];
  if ((first2 = first_coalesced_pseudo[regno2]) == first)
    return;
  for (last = regno2, regno = next_coalesced_pseudo[regno2];;
       regno = next_coalesced_pseudo[regno])
    {
      first_coalesced_pseudo[regno] = first;
      bitmap_set_bit (&coalesced_pseudos_bitmap, regno);
      if (regno == regno2)
	break;
      last = regno;
    }
  next = next_coalesced_pseudo[first];
  next_coalesced_pseudo[first] = regno2;
  next_coalesced_pseudo[last] = next;
  lra_reg_info[first].live_ranges
    = (lra_merge_live_ranges
       (lra_reg_info[first].live_ranges,
	lra_copy_live_range_list (lra_reg_info[first2].live_ranges)));
  if (GET_MODE_SIZE (lra_reg_info[first].biggest_mode)
      < GET_MODE_SIZE (lra_reg_info[first2].biggest_mode))
    lra_reg_info[first].biggest_mode = lra_reg_info[first2].biggest_mode;
}
示例#2
0
static int
index_term_p (rtx prod, enum machine_mode mode, int strict)
{
  rtx xfoo0, xfoo1;

  if (GET_MODE_SIZE (mode) == 1)
    return BASE_REGISTER_P (prod, strict);

  if (GET_CODE (prod) != MULT || GET_MODE_SIZE (mode) > 8)
    return 0;

  xfoo0 = XEXP (prod, 0);
  xfoo1 = XEXP (prod, 1);

  if (GET_CODE (xfoo0) == CONST_INT
      && INTVAL (xfoo0) == (int)GET_MODE_SIZE (mode)
      && INDEX_REGISTER_P (xfoo1, strict))
    return 1;

  if (GET_CODE (xfoo1) == CONST_INT
      && INTVAL (xfoo1) == (int)GET_MODE_SIZE (mode)
      && INDEX_REGISTER_P (xfoo0, strict))
    return 1;

  return 0;
}
示例#3
0
/* Transform (subreg (plus reg const)) to (plus (subreg reg) const)
   when it is possible.  Return X or the transformation result if the
   transformation is done.  */
static rtx
move_plus_up (rtx x)
{
  rtx subreg_reg;
  enum machine_mode x_mode, subreg_reg_mode;
  
  if (GET_CODE (x) != SUBREG || !subreg_lowpart_p (x))
    return x;
  subreg_reg = SUBREG_REG (x);
  x_mode = GET_MODE (x);
  subreg_reg_mode = GET_MODE (subreg_reg);
  if (GET_CODE (x) == SUBREG && GET_CODE (subreg_reg) == PLUS
      && GET_MODE_SIZE (x_mode) <= GET_MODE_SIZE (subreg_reg_mode)
      && CONSTANT_P (XEXP (subreg_reg, 1))
      && GET_MODE_CLASS (x_mode) == MODE_INT
      && GET_MODE_CLASS (subreg_reg_mode) == MODE_INT)
    {
      rtx cst = simplify_subreg (x_mode, XEXP (subreg_reg, 1), subreg_reg_mode,
				 subreg_lowpart_offset (x_mode,
							subreg_reg_mode));
      if (cst && CONSTANT_P (cst))
	return gen_rtx_PLUS (x_mode, lowpart_subreg (x_mode,
						     XEXP (subreg_reg, 0),
						     subreg_reg_mode), cst);
    }
  return x;
}
void
crx_print_operand_address (FILE * file, rtx addr)
{
  enum crx_addrtype addrtype;
  struct crx_address address;

  int offset;
  
  addrtype = crx_decompose_address (addr, &address);
  
  if (address.disp)
    offset = INTVAL (address.disp);
  else
    offset = 0;

  switch (addrtype)
    {
    case CRX_REG_REL:
      fprintf (file, "%d(%s)", offset, reg_names[REGNO (address.base)]);
      return;
      
    case CRX_POST_INC:
      switch (GET_CODE (address.side_effect))
	{
	case PLUS:
	  break;
	case MINUS:
	  offset = -offset;
	  break;
	case POST_INC:
	  offset = GET_MODE_SIZE (output_memory_reference_mode);
	  break;
	case POST_DEC:
	  offset = -GET_MODE_SIZE (output_memory_reference_mode);
	  break;
	default:
	  abort ();
	}
	fprintf (file, "%d(%s)+", offset, reg_names[REGNO (address.base)]);
      return;
      
    case CRX_SCALED_INDX:
      fprintf (file, "%d(%s, %s, %d)", offset, reg_names[REGNO (address.base)],
	       reg_names[REGNO (address.index)], address.scale);
      return;
      
    case CRX_ABSOLUTE:
      output_addr_const (file, address.disp);
      return;
      
    default:
      abort ();
    }
}
示例#5
0
static void
sdbout_reg_parms (tree parms)
{
  for (; parms; parms = TREE_CHAIN (parms))
    if (DECL_NAME (parms))
      {
	const char *name = IDENTIFIER_POINTER (DECL_NAME (parms));

	/* Report parms that live in registers during the function
	   but were passed in memory.  */
	if (REG_P (DECL_RTL (parms))
	    && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER
	    && PARM_PASSED_IN_MEMORY (parms))
	  {
	    if (name == 0 || *name == 0)
	      name = gen_fake_label ();
	    PUT_SDB_DEF (name);
	    PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms))));
	    PUT_SDB_SCL (C_REG);
	    PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
	    PUT_SDB_ENDEF;
	  }
	/* Report parms that live in memory but not where they were passed.  */
	else if (MEM_P (DECL_RTL (parms))
		 && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
		 && CONST_INT_P (XEXP (XEXP (DECL_RTL (parms), 0), 1))
		 && PARM_PASSED_IN_MEMORY (parms)
		 && ! rtx_equal_p (DECL_RTL (parms), DECL_INCOMING_RTL (parms)))
	  {
#if 0 /* ??? It is not clear yet what should replace this.  */
	    int offset = DECL_OFFSET (parms) / BITS_PER_UNIT;
	    /* A parm declared char is really passed as an int,
	       so it occupies the least significant bytes.
	       On a big-endian machine those are not the low-numbered ones.  */
	    if (BYTES_BIG_ENDIAN
		&& offset != -1
		&& TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
	      offset += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
			 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
	    if (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) != offset) {...}
#endif
	      {
		if (name == 0 || *name == 0)
		  name = gen_fake_label ();
		PUT_SDB_DEF (name);
		PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET
				 (XEXP (DECL_RTL (parms), 0)));
		PUT_SDB_SCL (C_AUTO);
		PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
		PUT_SDB_ENDEF;
	      }
	  }
      }
示例#6
0
static bool
mode_change_ok (enum machine_mode orig_mode, enum machine_mode new_mode,
		unsigned int regno ATTRIBUTE_UNUSED)
{
  if (GET_MODE_SIZE (orig_mode) < GET_MODE_SIZE (new_mode))
    return false;

#ifdef CANNOT_CHANGE_MODE_CLASS
  return !REG_CANNOT_CHANGE_MODE_P (regno, orig_mode, new_mode);
#endif

  return true;
}
示例#7
0
bool
expand_vec_cond_expr_p (tree value_type, tree cmp_op_type)
{
  machine_mode value_mode = TYPE_MODE (value_type);
  machine_mode cmp_op_mode = TYPE_MODE (cmp_op_type);
  if (VECTOR_BOOLEAN_TYPE_P (cmp_op_type))
    return get_vcond_mask_icode (TYPE_MODE (value_type),
				 TYPE_MODE (cmp_op_type)) != CODE_FOR_nothing;
  if (GET_MODE_SIZE (value_mode) != GET_MODE_SIZE (cmp_op_mode)
      || GET_MODE_NUNITS (value_mode) != GET_MODE_NUNITS (cmp_op_mode)
      || get_vcond_icode (TYPE_MODE (value_type), TYPE_MODE (cmp_op_type),
			  TYPE_UNSIGNED (cmp_op_type)) == CODE_FOR_nothing)
    return false;
  return true;
}
示例#8
0
文件: moxie.c 项目: chinabin/gcc-tiny
static int
moxie_arg_partial_bytes (cumulative_args_t cum_v,
			 machine_mode mode,
			 tree type, bool named)
{
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
  int bytes_left, size;

  if (*cum >= 8)
    return 0;

  if (moxie_pass_by_reference (cum_v, mode, type, named))
    size = 4;
  else if (type)
    {
      if (AGGREGATE_TYPE_P (type))
	return 0;
      size = int_size_in_bytes (type);
    }
  else
    size = GET_MODE_SIZE (mode);

  bytes_left = (4 * 6) - ((*cum - 2) * 4);

  if (size > bytes_left)
    return bytes_left;
  else
    return 0;
}
示例#9
0
文件: dojump.c 项目: FilipinOTech/gcc
static void
do_jump_by_parts_equality_rtx (enum machine_mode mode, rtx op0, rtx op1,
			       rtx if_false_label, rtx if_true_label, int prob)
{
  int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
  rtx drop_through_label = 0;
  int i;

  if (op1 == const0_rtx)
    {
      do_jump_by_parts_zero_rtx (mode, op0, if_false_label, if_true_label,
				 prob);
      return;
    }
  else if (op0 == const0_rtx)
    {
      do_jump_by_parts_zero_rtx (mode, op1, if_false_label, if_true_label,
				 prob);
      return;
    }

  if (! if_false_label)
    drop_through_label = if_false_label = gen_label_rtx ();

  for (i = 0; i < nwords; i++)
    do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
                             operand_subword_force (op1, i, mode),
                             EQ, 0, word_mode, NULL_RTX,
			     if_false_label, NULL_RTX, prob);

  if (if_true_label)
    emit_jump (if_true_label);
  if (drop_through_label)
    emit_label (drop_through_label);
}
示例#10
0
/* Target hook for llvm-abi.h. It returns true if an aggregate of the
   specified type should be passed using the byval mechanism. */
bool llvm_rs6000_should_pass_aggregate_byval(tree TreeType, const Type *Ty) {

  /* FIXME byval not implemented for ppc64. */
  if (TARGET_64BIT)
    return false;

  HOST_WIDE_INT Bytes = (TYPE_MODE(TreeType) == BLKmode) ? 
                        int_size_in_bytes(TreeType) : 
                        (int) GET_MODE_SIZE(TYPE_MODE(TreeType));

  // Zero sized array, struct, or class, ignored.
  if (Bytes == 0)
    return false;

  // Large types always use byval.  If this is a small fixed size type, 
  // investigate it.
  if (Bytes <= 0 || Bytes > 16)
    return true;

  // ppc32 passes aggregates by copying, either in int registers or on the 
  // stack.
  const StructType *STy = dyn_cast<StructType>(Ty);
  if (!STy) return true;

  // A struct containing only a float, double or vector field, possibly with
  // some zero-length fields as well, must be passed as the field type.
  // Note this does not apply to long double.
  // This is required for ABI correctness.  
  tree tType = isSingleElementStructOrArray(TreeType, true, false);
  if (tType && int_size_in_bytes(tType)==Bytes && TYPE_MODE(tType)!=TFmode &&
      (TREE_CODE(tType)!=VECTOR_TYPE || Bytes==16))
    return false;

  return true;
}
示例#11
0
文件: builtins.c 项目: Nodplus/gcc
static tree
compareAndSwapLong_builtin (tree method_return_type ATTRIBUTE_UNUSED,
			    tree orig_call)
{
  enum machine_mode mode = TYPE_MODE (long_type_node);
  /* We don't trust flag_use_atomic_builtins for multi-word compareAndSwap.
     Some machines such as ARM have atomic libfuncs but not the multi-word
     versions.  */
  if (can_compare_and_swap_p (mode,
			      (flag_use_atomic_builtins
			       && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)))
    {
      tree addr, stmt;
      enum built_in_function fncode = BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8;
      UNMARSHAL5 (orig_call);
      (void) value_type; /* Avoid set but not used warning.  */

      addr = build_addr_sum (long_type_node, obj_arg, offset_arg);
      stmt = build_call_expr (builtin_decl_explicit (fncode),
			      3, addr, expected_arg, value_arg);

      return build_check_this (stmt, this_arg);
    }
  return NULL_TREE;
}
示例#12
0
int
avm2_return_pops_args (tree fundecl, tree funtype, int size)
{
    int rtd = TARGET_RTD && (!fundecl || TREE_CODE (fundecl) != IDENTIFIER_NODE);

    /* Cdecl functions override -mrtd, and never pop the stack.  */
    if (! lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype))) {

        /* Stdcall and fastcall functions will pop the stack if not
           variable args.  */
        if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype))
                || lookup_attribute ("fastcall", TYPE_ATTRIBUTES (funtype)))
            rtd = 1;

        if (rtd
                && (TYPE_ARG_TYPES (funtype) == NULL_TREE
                    || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype)))
                        == void_type_node)))
            return size;
    }

    /* Lose any fake structure return argument if it is passed on the stack.  */
    if (aggregate_value_p (TREE_TYPE (funtype), fundecl)
            && !KEEP_AGGREGATE_RETURN_POINTER)
    {
        int nregs = avm2_function_regparm (funtype, fundecl);

        if (!nregs)
            return GET_MODE_SIZE (Pmode);
    }

    return 0;
}
示例#13
0
rtx
gen_lowpart_general (machine_mode mode, rtx x)
{
  rtx result = gen_lowpart_common (mode, x);

  if (result)
    return result;
  /* Handle SUBREGs and hard REGs that were rejected by
     simplify_gen_subreg.  */
  else if (REG_P (x) || GET_CODE (x) == SUBREG)
    {
      result = gen_lowpart_common (mode, copy_to_reg (x));
      gcc_assert (result != 0);
      return result;
    }
  else
    {
      /* The only additional case we can do is MEM.  */
      gcc_assert (MEM_P (x));

      /* The following exposes the use of "x" to CSE.  */
      scalar_int_mode xmode;
      if (is_a <scalar_int_mode> (GET_MODE (x), &xmode)
	  && GET_MODE_SIZE (xmode) <= UNITS_PER_WORD
	  && TRULY_NOOP_TRUNCATION_MODES_P (mode, xmode)
	  && !reload_completed)
	return gen_lowpart_general (mode, force_reg (xmode, x));

      poly_int64 offset = byte_lowpart_offset (mode, GET_MODE (x));
      return adjust_address (x, mode, offset);
    }
}
示例#14
0
文件: moxie.c 项目: chinabin/gcc-tiny
static void
moxie_setup_incoming_varargs (cumulative_args_t cum_v,
			      machine_mode mode ATTRIBUTE_UNUSED,
			      tree type ATTRIBUTE_UNUSED,
			      int *pretend_size, int no_rtl)
{
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
  int regno;
  int regs = 8 - *cum;
  
  *pretend_size = regs < 0 ? 0 : GET_MODE_SIZE (SImode) * regs;
  
  if (no_rtl)
    return;
  
  for (regno = *cum; regno < 8; regno++)
    {
      rtx reg = gen_rtx_REG (SImode, regno);
      rtx slot = gen_rtx_PLUS (Pmode,
			       gen_rtx_REG (SImode, ARG_POINTER_REGNUM),
			       GEN_INT (UNITS_PER_WORD * (3 + (regno-2))));
      
      emit_move_insn (gen_rtx_MEM (SImode, slot), reg);
    }
}
static int crx_addr_reg_p (rtx addr_reg)
{
  rtx reg;

  if (REG_P (addr_reg))
    {
      reg = addr_reg;
    }
  else if ((GET_CODE (addr_reg) == SUBREG
	   && REG_P (SUBREG_REG (addr_reg))
	   && GET_MODE_SIZE (GET_MODE (SUBREG_REG (addr_reg)))
	   <= UNITS_PER_WORD))
    {
      reg = SUBREG_REG (addr_reg);
    }
  else
    return FALSE;

  if (GET_MODE (addr_reg) != Pmode)
    {
      return FALSE;
    }

  return TRUE;
}
示例#16
0
static rtx
maybe_mode_change (enum machine_mode orig_mode, enum machine_mode copy_mode,
		   enum machine_mode new_mode, unsigned int regno,
		   unsigned int copy_regno ATTRIBUTE_UNUSED)
{
  if (GET_MODE_SIZE (copy_mode) < GET_MODE_SIZE (orig_mode)
      && GET_MODE_SIZE (copy_mode) < GET_MODE_SIZE (new_mode))
    return NULL_RTX;

  if (orig_mode == new_mode)
    return gen_rtx_raw_REG (new_mode, regno);
  else if (mode_change_ok (orig_mode, new_mode, regno))
    {
      int copy_nregs = hard_regno_nregs[copy_regno][copy_mode];
      int use_nregs = hard_regno_nregs[copy_regno][new_mode];
      int copy_offset
	= GET_MODE_SIZE (copy_mode) / copy_nregs * (copy_nregs - use_nregs);
      int offset
	= GET_MODE_SIZE (orig_mode) - GET_MODE_SIZE (new_mode) - copy_offset;
      int byteoffset = offset % UNITS_PER_WORD;
      int wordoffset = offset - byteoffset;

      offset = ((WORDS_BIG_ENDIAN ? wordoffset : 0)
		+ (BYTES_BIG_ENDIAN ? byteoffset : 0));
      regno += subreg_regno_offset (regno, orig_mode, offset, new_mode);
      if (HARD_REGNO_MODE_OK (regno, new_mode))
	return gen_rtx_raw_REG (new_mode, regno);
    }
  return NULL_RTX;
}
int
x86_64_movabs_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
  return (
#line 359 "../.././gcc/config/i386/predicates.md"
(!TARGET_64BIT || !flag_pic)) ? (nonmemory_operand (op, mode)) : ((register_operand (op, mode)) || ((const_double_operand (op, mode)) && (
#line 363 "../.././gcc/config/i386/predicates.md"
(GET_MODE_SIZE (mode) <= 8))));
}
// For the body of the function, our recommended style looks like this:
void
foo ()
{
  if (x < foo (y, z))
    haha = bar[4] + 5;
  else
    {
      while (z)
        {
          haha += foo (z, z);
          z--;
        }
      return ++x + bar ();
    }
  // We find it easier to read a program when it has spaces before the open-parentheses and after
  // the commas.  Especially after the commas.
  
  // When you split an expression into multiple lines, split it before an operator, not after one.
  // Here is the right way:
  if (foo_this_is_long && bar > win (x, y, z)
      && remaining_condition)
    {}

  // Try to avoid having two operators of different precedence at the same level of indentation.
  // For example, don’t write this:
  mode = (inmode[j] == VOIDmode
          || GET_MODE_SIZE (outmode[j]) > GET_MODE_SIZE (inmode[j])
          ? outmode[j] : inmode[j]);
  // Instead, use extra parentheses so that the indentation shows the nesting:
  mode = ((inmode[j] == VOIDmode
           || (GET_MODE_SIZE (outmode[j]) > GET_MODE_SIZE (inmode[j])))
          ? outmode[j] : inmode[j]);
  
  // Insert extra parentheses so that Emacs will indent the code properly.
  v = (rup->ru_utime.tv_sec*1000 + rup->ru_utime.tv_usec/1000
       + rup->ru_stime.tv_sec*1000 + rup->ru_stime.tv_usec/1000);

  // Format do-while statements like this:
  do
    {
      a = foo (a);
    }
  while (a > 0);
}
示例#19
0
// llvm_mips_should_not_return_complex_in_memory -  Return true if TYPE 
// should be returned using multiple value return instruction. This 
// implementation is based on mips_function_value in mips.c
bool llvm_mips_should_not_return_complex_in_memory(tree type) {

  enum machine_mode mode = TYPE_MODE(type);

  if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
      && GET_MODE_SIZE (mode) <= UNITS_PER_HWFPVALUE * 2)
    return true;

  return false;
}
示例#20
0
文件: fwprop.c 项目: ollie314/gcc
static rtx
propagate_rtx (rtx x, machine_mode mode, rtx old_rtx, rtx new_rtx,
	       bool speed)
{
  rtx tem;
  bool collapsed;
  int flags;

  if (REG_P (new_rtx) && REGNO (new_rtx) < FIRST_PSEUDO_REGISTER)
    return NULL_RTX;

  flags = 0;
  if (REG_P (new_rtx)
      || CONSTANT_P (new_rtx)
      || (GET_CODE (new_rtx) == SUBREG
	  && REG_P (SUBREG_REG (new_rtx))
	  && (GET_MODE_SIZE (mode)
	      <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (new_rtx))))))
    flags |= PR_CAN_APPEAR;
  if (!varying_mem_p (new_rtx))
    flags |= PR_HANDLE_MEM;

  if (speed)
    flags |= PR_OPTIMIZE_FOR_SPEED;

  tem = x;
  collapsed = propagate_rtx_1 (&tem, old_rtx, copy_rtx (new_rtx), flags);
  if (tem == x || !collapsed)
    return NULL_RTX;

  /* gen_lowpart_common will not be able to process VOIDmode entities other
     than CONST_INTs.  */
  if (GET_MODE (tem) == VOIDmode && !CONST_INT_P (tem))
    return NULL_RTX;

  if (GET_MODE (tem) == VOIDmode)
    tem = rtl_hooks.gen_lowpart_no_emit (mode, tem);
  else
    gcc_assert (GET_MODE (tem) == mode);

  return tem;
}
示例#21
0
文件: rtlhooks.c 项目: AlexMioMio/gcc
rtx
gen_lowpart_general (machine_mode mode, rtx x)
{
  rtx result = gen_lowpart_common (mode, x);

  if (result)
    return result;
  /* Handle SUBREGs and hard REGs that were rejected by
     simplify_gen_subreg.  */
  else if (REG_P (x) || GET_CODE (x) == SUBREG)
    {
      result = gen_lowpart_common (mode, copy_to_reg (x));
      gcc_assert (result != 0);
      return result;
    }
  else
    {
      int offset = 0;

      /* The only additional case we can do is MEM.  */
      gcc_assert (MEM_P (x));

      /* The following exposes the use of "x" to CSE.  */
      if (GET_MODE_SIZE (GET_MODE (x)) <= UNITS_PER_WORD
	  && SCALAR_INT_MODE_P (GET_MODE (x))
	  && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (x))
	  && !reload_completed)
	return gen_lowpart_general (mode, force_reg (GET_MODE (x), x));

      if (WORDS_BIG_ENDIAN)
	offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
		  - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));

      if (BYTES_BIG_ENDIAN)
	/* Adjust the address so that the address-after-the-data
	   is unchanged.  */
	offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
		   - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));

      return adjust_address (x, mode, offset);
    }
}
示例#22
0
文件: ree.c 项目: aixoss/gcc
static bool
transform_ifelse (ext_cand *cand, rtx def_insn)
{
  rtx set_insn = PATTERN (def_insn);
  rtx srcreg, dstreg, srcreg2;
  rtx map_srcreg, map_dstreg, map_srcreg2;
  rtx ifexpr;
  rtx cond;
  rtx new_set;

  gcc_assert (GET_CODE (set_insn) == SET);

  cond = XEXP (SET_SRC (set_insn), 0);
  dstreg = SET_DEST (set_insn);
  srcreg = XEXP (SET_SRC (set_insn), 1);
  srcreg2 = XEXP (SET_SRC (set_insn), 2);
  /* If the conditional move already has the right or wider mode,
     there is nothing to do.  */
  if (GET_MODE_SIZE (GET_MODE (dstreg)) >= GET_MODE_SIZE (cand->mode))
    return true;

  map_srcreg = gen_rtx_REG (cand->mode, REGNO (srcreg));
  map_srcreg2 = gen_rtx_REG (cand->mode, REGNO (srcreg2));
  map_dstreg = gen_rtx_REG (cand->mode, REGNO (dstreg));
  ifexpr = gen_rtx_IF_THEN_ELSE (cand->mode, cond, map_srcreg, map_srcreg2);
  new_set = gen_rtx_SET (VOIDmode, map_dstreg, ifexpr);

  if (validate_change (def_insn, &PATTERN (def_insn), new_set, true)
      && update_reg_equal_equiv_notes (def_insn, cand->mode, GET_MODE (dstreg),
				       cand->code))
    {
      if (dump_file)
        {
          fprintf (dump_file,
		   "Mode of conditional move instruction extended:\n");
          print_rtl_single (dump_file, def_insn);
        }
      return true;
    }

  return false;
}
示例#23
0
rtx
gen_lowpart_general (enum machine_mode mode, rtx x)
{
  rtx result = gen_lowpart_common (mode, x);

  if (result)
    return result;
  else if (REG_P (x))
    {
      /* Must be a hard reg that's not valid in MODE.  */
      result = gen_lowpart_common (mode, copy_to_reg (x));
      gcc_assert (result != 0);
      return result;
    }
  else
    {
      int offset = 0;

      /* The only additional case we can do is MEM.  */
      gcc_assert (MEM_P (x));

      /* The following exposes the use of "x" to CSE.  */
      if (GET_MODE_SIZE (GET_MODE (x)) <= UNITS_PER_WORD
	  && SCALAR_INT_MODE_P (GET_MODE (x))
	  && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
				    GET_MODE_BITSIZE (GET_MODE (x)))
	  && ! no_new_pseudos)
	return gen_lowpart_general (mode, force_reg (GET_MODE (x), x));

      if (WORDS_BIG_ENDIAN)
	offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
		  - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));

      if (BYTES_BIG_ENDIAN)
	/* Adjust the address so that the address-after-the-data
	   is unchanged.  */
	offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
		   - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));

      return adjust_address (x, mode, offset);
    }
}
static inline int
zero_extended_scalar_load_operand_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
#line 747 "../.././gcc/config/i386/predicates.md"
{
  unsigned n_elts;
  op = maybe_get_pool_constant (op);
  if (!op)
    return 0;
  if (GET_CODE (op) != CONST_VECTOR)
    return 0;
  n_elts =
    (GET_MODE_SIZE (GET_MODE (op)) /
     GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (op))));
  for (n_elts--; n_elts > 0; n_elts--)
    {
      rtx elt = CONST_VECTOR_ELT (op, n_elts);
      if (elt != CONST0_RTX (GET_MODE_INNER (GET_MODE (op))))
	return 0;
    }
  return 1;
}
示例#25
0
/* Target hook for llvm-abi.h. It returns true if an aggregate of the
   specified type should be passed in memory. In mips EABI this is 
   true for aggregates with size > 32-bits. */
bool llvm_mips_should_pass_aggregate_in_memory(tree TreeType, Type *Ty) {
  if (mips_abi == ABI_EABI)
  {
    enum machine_mode mode = TYPE_MODE(TreeType);
    int size;

    if (mode == DImode || mode == DFmode)
      return false;

    size = TreeType ? int_size_in_bytes (TreeType) : GET_MODE_SIZE (mode);
    return size == -1 || size > UNITS_PER_WORD;
  }
  return false; // TODO: support o32 ABI
}
示例#26
0
文件: dce.c 项目: AHelper/gcc
static bool
check_argument_store (rtx mem, HOST_WIDE_INT off, HOST_WIDE_INT min_sp_off,
		      HOST_WIDE_INT max_sp_off, bitmap sp_bytes)
{
  HOST_WIDE_INT byte;
  for (byte = off; byte < off + GET_MODE_SIZE (GET_MODE (mem)); byte++)
    {
      if (byte < min_sp_off
	  || byte >= max_sp_off
	  || !bitmap_clear_bit (sp_bytes, byte - min_sp_off))
	return false;
    }
  return true;
}
示例#27
0
static bool
get_best_extraction_insn (extraction_insn *insn,
			  enum extraction_pattern pattern,
			  enum extraction_type type,
			  unsigned HOST_WIDE_INT struct_bits,
			  machine_mode field_mode)
{
  opt_scalar_int_mode mode_iter;
  FOR_EACH_MODE_FROM (mode_iter, smallest_int_mode_for_size (struct_bits))
    {
      scalar_int_mode mode = mode_iter.require ();
      if (get_extraction_insn (insn, pattern, type, mode))
	{
	  FOR_EACH_MODE_FROM (mode_iter, mode)
	    {
	      mode = mode_iter.require ();
	      if (maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (field_mode))
		  || TRULY_NOOP_TRUNCATION_MODES_P (insn->field_mode,
						    field_mode))
		break;
	      get_extraction_insn (insn, pattern, type, mode);
	    }
	  return true;
	}
示例#28
0
/* Compute the number of word sized registers needed to hold a
   function argument of mode INT_MODE and tree type TYPE.  */
int
fr30_num_arg_regs (enum machine_mode mode, tree type)
{
  int size;

  if (targetm.calls.must_pass_in_stack (mode, type))
    return 0;

  if (type && mode == BLKmode)
    size = int_size_in_bytes (type);
  else
    size = GET_MODE_SIZE (mode);

  return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
}
示例#29
0
static void
do_jump_by_parts_greater_rtx (enum machine_mode mode, int unsignedp, rtx op0,
			      rtx op1, rtx if_false_label, rtx if_true_label,
			      int prob)
{
  int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
  rtx drop_through_label = 0;
  int i;

  if (! if_true_label || ! if_false_label)
    drop_through_label = gen_label_rtx ();
  if (! if_true_label)
    if_true_label = drop_through_label;
  if (! if_false_label)
    if_false_label = drop_through_label;

  /* Compare a word at a time, high order first.  */
  for (i = 0; i < nwords; i++)
    {
      rtx op0_word, op1_word;

      if (WORDS_BIG_ENDIAN)
        {
          op0_word = operand_subword_force (op0, i, mode);
          op1_word = operand_subword_force (op1, i, mode);
        }
      else
        {
          op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
          op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
        }

      /* All but high-order word must be compared as unsigned.  */
      do_compare_rtx_and_jump (op0_word, op1_word, GT,
                               (unsignedp || i > 0), word_mode, NULL_RTX,
			       NULL_RTX, if_true_label, prob);

      /* Consider lower words only if these are equal.  */
      do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode,
			       NULL_RTX, NULL_RTX, if_false_label,
			       inv (prob));
    }

  if (if_false_label)
    emit_jump (if_false_label);
  if (drop_through_label)
    emit_label (drop_through_label);
}
示例#30
0
static void
lm32_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
                             tree type, int *pretend_size, int no_rtl)
{
    int first_anon_arg;
    tree fntype;
    int stdarg_p;

    fntype = TREE_TYPE (current_function_decl);
    stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
                && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
                    != void_type_node));

    if (stdarg_p)
        first_anon_arg = *cum + LM32_FIRST_ARG_REG;
    else
    {
        /* this is the common case, we have been passed details setup
           for the last named argument, we want to skip over the
           registers, if any used in passing this named paramter in
           order to determine which is the first registers used to pass
           anonymous arguments */
        int size;

        if (mode==BLKmode)
            size = int_size_in_bytes (type);
        else
            size = GET_MODE_SIZE (mode);

        first_anon_arg = *cum + LM32_FIRST_ARG_REG + ((size + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
    }

    if ((first_anon_arg < (LM32_FIRST_ARG_REG + LM32_NUM_ARG_REGS)) && !no_rtl)
    {
        int first_reg_offset = first_anon_arg;
        int size = LM32_FIRST_ARG_REG + LM32_NUM_ARG_REGS - first_anon_arg;
        rtx regblock;

        regblock = gen_rtx_MEM (BLKmode,
                                plus_constant (arg_pointer_rtx,
                                               FIRST_PARM_OFFSET (0)));
        move_block_from_reg (first_reg_offset, regblock, size);

        *pretend_size = size * UNITS_PER_WORD;
    }
}