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

📄 iq2000.c

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	  || ! host_integerp (TYPE_SIZE_UNIT (type), 1))	ret = gen_rtx_REG (mode, regbase + *arg_words + bias);      else	{	  tree field;	  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))	    if (TREE_CODE (field) == FIELD_DECL		&& TREE_CODE (TREE_TYPE (field)) == REAL_TYPE		&& TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD		&& host_integerp (bit_position (field), 0)		&& int_bit_position (field) % BITS_PER_WORD == 0)	      break;	  /* If the whole struct fits a DFmode register,	     we don't need the PARALLEL.  */	  if (! field || mode == DFmode)	    ret = gen_rtx_REG (mode, regbase + *arg_words + bias);	  else	    {	      unsigned int chunks;	      HOST_WIDE_INT bitpos;	      unsigned int regno;	      unsigned int i;	      /* ??? If this is a packed structure, then the last hunk won't		 be 64 bits.  */	      chunks		= tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD;	      if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS)		chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;	      /* Assign_parms checks the mode of ENTRY_PARM, so we must		 use the actual mode here.  */	      ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks));	      bitpos = 0;	      regno = regbase + *arg_words + bias;	      field = TYPE_FIELDS (type);	      for (i = 0; i < chunks; i++)		{		  rtx reg;		  for (; field; field = TREE_CHAIN (field))		    if (TREE_CODE (field) == FIELD_DECL			&& int_bit_position (field) >= bitpos)		      break;		  if (field		      && int_bit_position (field) == bitpos		      && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE		      && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)		    reg = gen_rtx_REG (DFmode, regno++);		  else		    reg = gen_rtx_REG (word_mode, regno);		  XVECEXP (ret, 0, i)		    = gen_rtx_EXPR_LIST (VOIDmode, reg,					 GEN_INT (bitpos / BITS_PER_UNIT));		  bitpos += 64;		  regno++;		}	    }	}      if (TARGET_DEBUG_D_MODE)	fprintf (stderr, "%s%s\n", reg_names[regbase + *arg_words + bias],		 struct_p ? ", [struct]" : "");    }  /* We will be called with a mode of VOIDmode after the last argument     has been seen.  Whatever we return will be passed to the call     insn.  If we need any shifts for small structures, return them in     a PARALLEL.  */  if (mode == VOIDmode)    {      if (cum->num_adjusts > 0)	ret = gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code,		       gen_rtvec_v (cum->num_adjusts, cum->adjust));    }  return ret;}static intiq2000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,			  tree type ATTRIBUTE_UNUSED,			  bool named ATTRIBUTE_UNUSED){  if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS - 1)    {      if (TARGET_DEBUG_D_MODE)	fprintf (stderr, "iq2000_arg_partial_bytes=%d\n", UNITS_PER_WORD);      return UNITS_PER_WORD;    }  return 0;}/* Implement va_start.  */voidiq2000_va_start (tree valist, rtx nextarg){  int int_arg_words;  /* Find out how many non-float named formals.  */  int gpr_save_area_size;  /* Note UNITS_PER_WORD is 4 bytes.  */  int_arg_words = current_function_args_info.arg_words;  if (int_arg_words < 8 )    /* Adjust for the prologue's economy measure.  */    gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD;  else    gpr_save_area_size = 0;  /* Everything is in the GPR save area, or in the overflow     area which is contiguous with it.  */  nextarg = plus_constant (nextarg, - gpr_save_area_size);  std_expand_builtin_va_start (valist, nextarg);}/* Allocate a chunk of memory for per-function machine-dependent data.  */static struct machine_function *iq2000_init_machine_status (void){  struct machine_function *f;  f = ggc_alloc_cleared (sizeof (struct machine_function));  return f;}static enum processor_typeiq2000_parse_cpu (const char * cpu_string){  const char *p = cpu_string;  enum processor_type cpu;  cpu = PROCESSOR_DEFAULT;  switch (p[2])    {    case '1':      if (!strcmp (p, "iq10"))	cpu = PROCESSOR_IQ10;      break;    case '2':      if (!strcmp (p, "iq2000"))	cpu = PROCESSOR_IQ2000;      break;    }  return cpu;}/* Detect any conflicts in the switches.  */voidoverride_options (void){  enum processor_type iq2000_cpu;  target_flags &= ~MASK_GPOPT;  iq2000_isa = IQ2000_ISA_DEFAULT;  /* Identify the processor type.  */  if (iq2000_cpu_string != 0)    {      iq2000_cpu = iq2000_parse_cpu (iq2000_cpu_string);      if (iq2000_cpu == PROCESSOR_DEFAULT)	{	  error ("bad value (%s) for -mcpu= switch", iq2000_arch_string);	  iq2000_cpu_string = "default";	}      iq2000_arch = iq2000_cpu;      iq2000_tune = iq2000_cpu;    }  if (iq2000_arch_string == 0      || ! strcmp (iq2000_arch_string, "default")      || ! strcmp (iq2000_arch_string, "DEFAULT"))    {      switch (iq2000_isa)	{	default:	  iq2000_arch_string = "iq2000";	  iq2000_arch = PROCESSOR_IQ2000;	  break;	}    }  else    {      iq2000_arch = iq2000_parse_cpu (iq2000_arch_string);      if (iq2000_arch == PROCESSOR_DEFAULT)	{	  error ("bad value (%s) for -march= switch", iq2000_arch_string);	  iq2000_arch_string = "default";	}      if (iq2000_arch == PROCESSOR_IQ10)	{	  error ("The compiler does not support -march=%s.", iq2000_arch_string);	  iq2000_arch_string = "default";	}    }  iq2000_print_operand_punct['?'] = 1;  iq2000_print_operand_punct['#'] = 1;  iq2000_print_operand_punct['&'] = 1;  iq2000_print_operand_punct['!'] = 1;  iq2000_print_operand_punct['*'] = 1;  iq2000_print_operand_punct['@'] = 1;  iq2000_print_operand_punct['.'] = 1;  iq2000_print_operand_punct['('] = 1;  iq2000_print_operand_punct[')'] = 1;  iq2000_print_operand_punct['['] = 1;  iq2000_print_operand_punct[']'] = 1;  iq2000_print_operand_punct['<'] = 1;  iq2000_print_operand_punct['>'] = 1;  iq2000_print_operand_punct['{'] = 1;  iq2000_print_operand_punct['}'] = 1;  iq2000_print_operand_punct['^'] = 1;  iq2000_print_operand_punct['$'] = 1;  iq2000_print_operand_punct['+'] = 1;  iq2000_print_operand_punct['~'] = 1;  /* Save GPR registers in word_mode sized hunks.  word_mode hasn't been     initialized yet, so we can't use that here.  */  gpr_mode = SImode;  /* Function to allocate machine-dependent function status.  */  init_machine_status = iq2000_init_machine_status;}/* The arg pointer (which is eliminated) points to the virtual frame pointer,   while the frame pointer (which may be eliminated) points to the stack   pointer after the initial adjustments.  */HOST_WIDE_INTiq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset){  rtx offset2 = const0_rtx;  rtx reg = eliminate_constant_term (addr, & offset2);  if (offset == 0)    offset = INTVAL (offset2);  if (reg == stack_pointer_rtx || reg == frame_pointer_rtx      || reg == hard_frame_pointer_rtx)    {      HOST_WIDE_INT frame_size = (!cfun->machine->initialized)				  ? compute_frame_size (get_frame_size ())				  : cfun->machine->total_size;      offset = offset - frame_size;    }  return offset;}/* If defined, a C statement to be executed just prior to the output of   assembler code for INSN, to modify the extracted operands so they will be   output differently.   Here the argument OPVEC is the vector containing the operands extracted   from INSN, and NOPERANDS is the number of elements of the vector which   contain meaningful data for this insn.  The contents of this vector are   what will be used to convert the insn template into assembler code, so you   can change the assembler output by changing the contents of the vector.   We use it to check if the current insn needs a nop in front of it because   of load delays, and also to update the delay slot statistics.  */voidfinal_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED,		    int noperands ATTRIBUTE_UNUSED){  if (dslots_number_nops > 0)    {      rtx pattern = PATTERN (insn);      int length = get_attr_length (insn);      /* Do we need to emit a NOP?  */      if (length == 0	  || (iq2000_load_reg != 0 && reg_mentioned_p (iq2000_load_reg,  pattern))	  || (iq2000_load_reg2 != 0 && reg_mentioned_p (iq2000_load_reg2, pattern))	  || (iq2000_load_reg3 != 0 && reg_mentioned_p (iq2000_load_reg3, pattern))	  || (iq2000_load_reg4 != 0	      && reg_mentioned_p (iq2000_load_reg4, pattern)))	fputs ("\tnop\n", asm_out_file);      else	dslots_load_filled ++;      while (--dslots_number_nops > 0)	fputs ("\tnop\n", asm_out_file);      iq2000_load_reg = 0;      iq2000_load_reg2 = 0;      iq2000_load_reg3 = 0;      iq2000_load_reg4 = 0;    }  if (   (GET_CODE (insn) == JUMP_INSN       || GET_CODE (insn) == CALL_INSN       || (GET_CODE (PATTERN (insn)) == RETURN))	   && NEXT_INSN (PREV_INSN (insn)) == insn)    {      rtx nop_insn = emit_insn_after (gen_nop (), insn);      INSN_ADDRESSES_NEW (nop_insn, -1);    }    if (TARGET_STATS      && (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN))    dslots_jump_total ++;}/* Return the bytes needed to compute the frame pointer from the current   stack pointer where SIZE is the # of var. bytes allocated.   IQ2000 stack frames look like:             Before call		        After call        +-----------------------+	+-----------------------+   high |			|       |      			|   mem. |		        |	|			|        |  caller's temps.    	|       |  caller's temps.    	|	|       		|       |       	        |        +-----------------------+	+-----------------------+ 	|       		|	|		        |        |  arguments on stack.  |	|  arguments on stack.  |	|       		|	|			|        +-----------------------+	+-----------------------+ 	|  4 words to save     	|	|  4 words to save	|	|  arguments passed	|	|  arguments passed	|	|  in registers, even	|	|  in registers, even	|    SP->|  if not passed.       |  VFP->|  if not passed.	|	+-----------------------+       +-----------------------+					|		        |                                        |  fp register save     |					|			|					+-----------------------+					|		        |                                        |  gp register save     |                                        |       		|					+-----------------------+					|			|					|  local variables	|					|			|					+-----------------------+					|			|                                        |  alloca allocations   |        				|			|					+-----------------------+					|			|					|  GP save for V.4 abi	|					|			|					+-----------------------+					|			|                                        |  arguments on stack   |        				|		        |					+-----------------------+                                        |  4 words to save      |					|  arguments passed     |                                        |  in registers, even   |   low                              SP->|  if not passed.       |   memory        			+-----------------------+  */HOST_WIDE_INTcompute_frame_size (HOST_WIDE_INT size){  int regno;  HOST_WIDE_INT total_size;	/* # bytes that the entire frame takes up.  */  HOST_WIDE_INT var_size;	/* # bytes that variables take up.  */  HOST_WIDE_INT args_size;	/* # bytes that outgoing arguments take up.  */  HOST_WIDE_INT extra_size;	/* # extra bytes.  */  HOST_WIDE_INT gp_reg_rounded;	/* # bytes needed to store gp after rounding.  */  HOST_WIDE_INT gp_reg_size;	/* # bytes needed to store gp regs.  */  HOST_WIDE_INT fp_reg_size;	/* # bytes needed to store fp regs.  */  long mask;			/* mask of saved gp registers.  */  int  fp_inc;			/* 1 or 2 depending on the size of fp regs.  */  long fp_bits;			/* bitmask to use for each fp register.  */  gp_reg_size = 0;  fp_reg_size = 0;  mask = 0;  extra_size = IQ2000_STACK_ALIGN ((0));  var_size = IQ2000_STACK_ALIGN (size);  args_size = IQ2000_STACK_ALIGN (current_function_outgoing_args_size);  /* If a function dynamically allocates the stack and     has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space.  */  if (args_size == 0 && current_function_calls_alloca)    args_size = 4 * UNITS_PER_WORD;  total_size = var_size + args_size + extra_size;  /* Calculate space needed for gp registers.  */  for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)    {      if (MUST_SAVE_REGISTER (regno))	{	  gp_reg_size += GET_MODE_SIZE (gpr_mode);	  mask |= 1L << (regno - GP_REG_FIRST);	}    }  /* We need to restore these for the handler.  */  if (current_function_calls_eh_return)    {      unsigned int i;      for (i = 0; ; ++i)	{	  regno = EH_RETURN_DATA_REGNO (i);	  if (regno == (int) INVALID_REGNUM)	    break;	  gp_reg_size += GET_MODE_SIZE (gpr_mode);	  mask |= 1L << (regno - GP_REG_FIRST);	}    }  fp_inc = 2;  fp_bits = 3;  gp_reg_rounded = IQ2000_STACK_ALIGN (gp_reg_size);  total_size += gp_reg_rounded + IQ2000_STACK_ALIGN (fp_reg_size);  /* The gp reg is caller saved, so there is no need for leaf routines      (total_size == extra_size) to save the gp reg.  */  if (total_size == extra_size      && ! profile_flag)    total_size = extra_size = 0;  total_size += IQ2000_STACK_ALIGN (current_function_pretend_args_size);  /* Save other computed information.  */  cfun->machine->total_size = total_size;  cfun->machine->var_size = var_size;  cfun->machine->args_size = args_size;  cfun->machine->extra_size = extra_size;  cfun->machine->gp_reg_size = gp_reg_size;  cfun->machine->fp_reg_size = fp_reg_size;  cfun->machine->mask = mask;  cfun->machine->initialized = reload_completed;  cfun->machine->num_gp = gp_reg_size / UNITS_PER_WORD;  if (mask)    {      unsigned long offset;      offset = (args_size + extra_size + var_size		+ gp_reg_size - GET_MODE_SIZE (gpr_mode));      cfun->machine->gp_sp_offset = offset;      cfun->machine->gp_save_offset = offset - total_size;    }  else    {      cfun->machine->gp_sp_offset = 0;      cfun->machine->gp_save_offset = 0;    }  cfun->machine->fp_sp_offset = 0;  cfun->machine->fp_save_offset = 0;  /* Ok, we're done.  */  return total_size;}/* Implement INITIAL_ELIMINATION_OFFSET.  FROM is either the frame   pointer, argument pointer, or return address pointer.  TO is either   the stack pointer or hard frame pointer.  */intiq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED){  int offset;  compute_frame_size (get_frame_size ());				   if ((from) == FRAME_POINTER_REGNUM)     (offset) = 0;   else if ((from) == ARG_POINTER_REGNUM)     (offset) = (cfun->machine->total_size);   else if ((from) == RETURN_ADDRESS_POINTER_REGNUM)     {      if (leaf_function_p ()) 	(offset) = 0; 

⌨️ 快捷键说明

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