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

📄 fr30.c

📁 gcc-you can use this code to learn something about gcc, and inquire further into linux,
💻 C
📖 第 1 页 / 共 3 页
字号:
  if ((size % UNITS_PER_WORD) == 0)    {      t = build (POSTINCREMENT_EXPR, va_list_type_node, valist, build_int_2 (size, 0));      TREE_SIDE_EFFECTS (t) = 1;            return expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL);    }  rsize = (size + UNITS_PER_WORD - 1) & - UNITS_PER_WORD;        /* Care for bigendian correction on the aligned address.  */  t = build (PLUS_EXPR, ptr_type_node, valist, build_int_2 (rsize - size, 0));  addr_rtx = expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL);  addr_rtx = copy_to_reg (addr_rtx);        /* Increment AP.  */  t = build (PLUS_EXPR, va_list_type_node, valist, build_int_2 (rsize, 0));  t = build (MODIFY_EXPR, va_list_type_node, valist, t);  TREE_SIDE_EFFECTS (t) = 1;  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);    return addr_rtx;}/* Implement `va_arg'.  */rtxfr30_va_arg (valist, type)     tree valist;     tree type;{  HOST_WIDE_INT size;    if (AGGREGATE_TYPE_P (type))    return fr30_pass_by_reference (valist, type);    size = int_size_in_bytes (type);  if ((size % sizeof (int)) == 0      || size < 4)    return fr30_pass_by_value (valist, type);  return fr30_pass_by_reference (valist, type);}/*}}}*//*{{{  Operand predicates */ #ifndef Mmode#define Mmode enum machine_mode#endif/* Returns true if OPERAND is an integer value suitable for use in   an ADDSP instruction.  */intstack_add_operand (operand, mode)     rtx operand;     Mmode mode ATTRIBUTE_UNUSED;{  return    (GET_CODE (operand) == CONST_INT     && INTVAL (operand) >= -512     && INTVAL (operand) <=  508     && ((INTVAL (operand) & 3) == 0));}/* Returns true if OPERAND is an integer value suitable for use in   an ADD por ADD2 instruction, or if it is a register.  */intadd_immediate_operand (operand, mode)     rtx operand;     Mmode mode ATTRIBUTE_UNUSED;{  return    (GET_CODE (operand) == REG     || (GET_CODE (operand) == CONST_INT	 && INTVAL (operand) >= -16	 && INTVAL (operand) <=  15));}/* Returns true if OPERAND is hard register in the range 8 - 15.  */inthigh_register_operand (operand, mode)     rtx operand;     Mmode mode ATTRIBUTE_UNUSED;{  return    (GET_CODE (operand) == REG     && REGNO (operand) <= 15     && REGNO (operand) >= 8);}/* Returns true if OPERAND is hard register in the range 0 - 7.  */intlow_register_operand (operand, mode)     rtx operand;     Mmode mode ATTRIBUTE_UNUSED;{  return    (GET_CODE (operand) == REG     && REGNO (operand) <= 7);}/* Returns true if OPERAND is suitable for use in a CALL insn.  */intcall_operand (operand, mode)     rtx operand;     Mmode mode ATTRIBUTE_UNUSED;{  return (GET_CODE (operand) == MEM	  && (GET_CODE (XEXP (operand, 0)) == SYMBOL_REF	      || GET_CODE (XEXP (operand, 0)) == REG));}/* Returns TRUE if OP is a valid operand of a DImode operation.  */intdi_operand (op, mode)     rtx op;     Mmode mode;{  if (register_operand (op, mode))    return TRUE;  if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)    return FALSE;  if (GET_CODE (op) == SUBREG)    op = SUBREG_REG (op);  switch (GET_CODE (op))    {    case CONST_DOUBLE:    case CONST_INT:      return TRUE;    case MEM:      return memory_address_p (DImode, XEXP (op, 0));    default:      return FALSE;    }}/* Returns TRUE if OP is a DImode register or MEM.  */intnonimmediate_di_operand (op, mode)     rtx op;     Mmode mode;{  if (register_operand (op, mode))    return TRUE;  if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)    return FALSE;  if (GET_CODE (op) == SUBREG)    op = SUBREG_REG (op);  if (GET_CODE (op) == MEM)    return memory_address_p (DImode, XEXP (op, 0));  return FALSE;}/* Returns true iff all the registers in the operands array   are in descending or ascending order.  */intfr30_check_multiple_regs (operands, num_operands, descending)     rtx * operands;     int   num_operands;     int   descending;{  if (descending)    {      unsigned int prev_regno = 0;            while (num_operands --)	{	  if (GET_CODE (operands [num_operands]) != REG)	    return 0;	  	  if (REGNO (operands [num_operands]) < prev_regno)	    return 0;	  	  prev_regno = REGNO (operands [num_operands]);	}    }  else    {      unsigned int prev_regno = CONDITION_CODE_REGNUM;            while (num_operands --)	{	  if (GET_CODE (operands [num_operands]) != REG)	    return 0;	  	  if (REGNO (operands [num_operands]) > prev_regno)	    return 0;	  	  prev_regno = REGNO (operands [num_operands]);	}    }  return 1;}intfr30_const_double_is_zero (operand)     rtx operand;{  REAL_VALUE_TYPE d;  if (operand == NULL || GET_CODE (operand) != CONST_DOUBLE)    return 0;  REAL_VALUE_FROM_CONST_DOUBLE (d, operand);  return REAL_VALUES_EQUAL (d, dconst0);}/*}}}*//*{{{  Instruction Output Routines  *//* Output a double word move.   It must be REG<-REG, REG<-MEM, MEM<-REG or REG<-CONST.   On the FR30 we are contrained by the fact that it does not   support offsetable addresses, and so we have to load the   address of the secnd word into the second destination register   before we can use it.  */rtxfr30_move_double (operands)     rtx * operands;{  rtx src  = operands[1];  rtx dest = operands[0];  enum rtx_code src_code = GET_CODE (src);  enum rtx_code dest_code = GET_CODE (dest);  enum machine_mode mode = GET_MODE (dest);  rtx val;  start_sequence ();  if (dest_code == REG)    {      if (src_code == REG)	{	  int reverse = (REGNO (dest) == REGNO (src) + 1);	  	  /* We normally copy the low-numbered register first.  However, if	     the first register of operand 0 is the same as the second register	     of operand 1, we must copy in the opposite order.  */	  emit_insn (gen_rtx_SET (VOIDmode,				  operand_subword (dest, reverse, TRUE, mode),				  operand_subword (src,  reverse, TRUE, mode)));	  	  emit_insn (gen_rtx_SET (VOIDmode,			      operand_subword (dest, !reverse, TRUE, mode),			      operand_subword (src,  !reverse, TRUE, mode)));	}      else if (src_code == MEM)	{	  rtx addr = XEXP (src, 0);	  int dregno = REGNO (dest);	  rtx dest0;	  rtx dest1;	  rtx new_mem;	  	  /* If the high-address word is used in the address, we	     must load it last.  Otherwise, load it first.  */	  int reverse = (refers_to_regno_p (dregno, dregno + 1, addr, 0) != 0);	  if (GET_CODE (addr) != REG)	    abort ();	  	  dest0 = operand_subword (dest, reverse, TRUE, mode);	  dest1 = operand_subword (dest, !reverse, TRUE, mode);	  if (reverse)	    {	      emit_insn (gen_rtx_SET (VOIDmode, dest1,				      adjust_address (src, SImode, 0)));	      emit_insn (gen_rtx_SET (SImode, dest0,				      gen_rtx_REG (SImode, REGNO (addr))));	      emit_insn (gen_rtx_SET (SImode, dest0,				      plus_constant (dest0, UNITS_PER_WORD)));	      new_mem = gen_rtx_MEM (SImode, dest0);	      MEM_COPY_ATTRIBUTES (new_mem, src);	      	      emit_insn (gen_rtx_SET (VOIDmode, dest0, new_mem));	    }	  else	    {	      emit_insn (gen_rtx_SET (VOIDmode, dest0,				      adjust_address (src, SImode, 0)));	      emit_insn (gen_rtx_SET (SImode, dest1,				      gen_rtx_REG (SImode, REGNO (addr))));	      emit_insn (gen_rtx_SET (SImode, dest1,				      plus_constant (dest1, UNITS_PER_WORD)));	      new_mem = gen_rtx_MEM (SImode, dest1);	      MEM_COPY_ATTRIBUTES (new_mem, src);	      	      emit_insn (gen_rtx_SET (VOIDmode, dest1, new_mem));	    }	}      else if (src_code == CONST_INT || src_code == CONST_DOUBLE)	{	  rtx words[2];	  split_double (src, &words[0], &words[1]);	  emit_insn (gen_rtx_SET (VOIDmode,				  operand_subword (dest, 0, TRUE, mode),				  words[0]));      	  emit_insn (gen_rtx_SET (VOIDmode,				  operand_subword (dest, 1, TRUE, mode),				  words[1]));	}    }  else if (src_code == REG && dest_code == MEM)    {      rtx addr = XEXP (dest, 0);      rtx src0;      rtx src1;      if (GET_CODE (addr) != REG)	abort ();            src0 = operand_subword (src, 0, TRUE, mode);      src1 = operand_subword (src, 1, TRUE, mode);            emit_insn (gen_rtx_SET (VOIDmode, adjust_address (dest, SImode, 0),			      src0));      if (REGNO (addr) == STACK_POINTER_REGNUM	  || REGNO (addr) == FRAME_POINTER_REGNUM)	emit_insn (gen_rtx_SET (VOIDmode,				adjust_address (dest, SImode, UNITS_PER_WORD),				src1));      else	{	  rtx new_mem;	  	  /* We need a scratch register to hold the value of 'address + 4'.	     We ought to allow gcc to find one for us, but for now, just	     push one of the source registers.  */	  emit_insn (gen_movsi_push (src0));	  emit_insn (gen_movsi_internal (src0, addr));	  emit_insn (gen_addsi_small_int (src0, src0, GEN_INT (UNITS_PER_WORD)));	  	  new_mem = gen_rtx_MEM (SImode, src0);	  MEM_COPY_ATTRIBUTES (new_mem, dest);	  	  emit_insn (gen_rtx_SET (VOIDmode, new_mem, src1));	  emit_insn (gen_movsi_pop (src0));	}    }  else    /* This should have been prevented by the constraints on movdi_insn.  */    abort ();    val = get_insns ();  end_sequence ();  return val;}/*}}}*//* Local Variables: *//* folded-file: t   *//* End:		    */

⌨️ 快捷键说明

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