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

📄 emit-rtl.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
      insn = make_insn_raw (pattern, NULL);      add_insn (insn);    }  return insn;}/* Emit the insns in a chain starting with INSN.  */rtxemit_insns (insn)     rtx insn;{  while (insn)    {      rtx next = NEXT_INSN (insn);      add_insn (insn);      insn = next;    }}/* Make an insn of code JUMP_INSN with pattern PATTERN   and add it to the end of the doubly-linked list.  */rtxemit_jump_insn (pattern)     rtx pattern;{  if (GET_CODE (pattern) == SEQUENCE)    return emit_insn (pattern);  else    {      register rtx insn = make_jump_insn_raw (pattern, NULL);      add_insn (insn);      return insn;    }}/* Make an insn of code CALL_INSN with pattern PATTERN   and add it to the end of the doubly-linked list.  */rtxemit_call_insn (pattern)     rtx pattern;{  if (GET_CODE (pattern) == SEQUENCE)    return emit_insn (pattern);  else    {      register rtx insn = make_insn_raw (pattern, NULL);      add_insn (insn);      PUT_CODE (insn, CALL_INSN);      return insn;    }}/* Add the label LABEL to the end of the doubly-linked list.  */rtxemit_label (label)     rtx label;{  /* This can be called twice for the same label     as a result of the confusion that follows a syntax error!     So make it harmless.  */  if (INSN_UID (label) == 0)    {      INSN_UID (label) = cur_insn_uid++;      add_insn (label);    }  return label;}/* Make an insn of code BARRIER   and add it to the end of the doubly-linked list.  */rtxemit_barrier (){  register rtx barrier = rtx_alloc (BARRIER);  INSN_UID (barrier) = cur_insn_uid++;  add_insn (barrier);  return barrier;}/* Make an insn of code NOTE   with data-fields specified by FILE and LINE   and add it to the end of the doubly-linked list,   but only if line-numbers are desired for debugging info.  */rtxemit_line_note (file, line)     char *file;     int line;{  emit_filename = file;  emit_lineno = line;#if 0  if (no_line_numbers)    return 0;#endif  return emit_note (file, line);}/* Make an insn of code NOTE   with data-fields specified by FILE and LINE   and add it to the end of the doubly-linked list.   If it is a line-number NOTE, omit it if it matches the previous one.  */rtxemit_note (file, line)     char *file;     int line;{  register rtx note;  if (line > 0)    {      if (file && last_filename && !strcmp (file, last_filename)	  && line == last_linenum)	return 0;      last_filename = file;      last_linenum = line;    }  if (no_line_numbers && line > 0)    {      cur_insn_uid++;      return 0;    }  note = rtx_alloc (NOTE);  INSN_UID (note) = cur_insn_uid++;  XSTR (note, 3) = file;  XINT (note, 4) = line;  add_insn (note);  return note;}/* Emit a NOTE, and don't omit it even if LINE it the previous note.  */rtxemit_line_note_force (file, line)     char *file;     int line;{  last_linenum = -1;  return emit_line_note (file, line);}/* Cause next statement to emit a line note even if the line number   has not changed.  This is used at the beginning of a function.  */voidforce_next_line_note (){  last_linenum = -1;}/* Return an indication of which type of insn should have X as a body.   The value is CODE_LABEL, INSN, CALL_INSN or JUMP_INSN.  */enum rtx_codeclassify_insn (x)     rtx x;{  if (GET_CODE (x) == CODE_LABEL)    return CODE_LABEL;  if (GET_CODE (x) == CALL)    return CALL_INSN;  if (GET_CODE (x) == RETURN)    return JUMP_INSN;  if (GET_CODE (x) == SET)    {      if (SET_DEST (x) == pc_rtx)	return JUMP_INSN;      else if (GET_CODE (SET_SRC (x)) == CALL)	return CALL_INSN;      else	return INSN;    }  if (GET_CODE (x) == PARALLEL)    {      register int j;      for (j = XVECLEN (x, 0) - 1; j >= 0; j--)	if (GET_CODE (XVECEXP (x, 0, j)) == CALL)	  return CALL_INSN;	else if (GET_CODE (XVECEXP (x, 0, j)) == SET		 && SET_DEST (XVECEXP (x, 0, j)) == pc_rtx)	  return JUMP_INSN;	else if (GET_CODE (XVECEXP (x, 0, j)) == SET		 && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == CALL)	  return CALL_INSN;    }  return INSN;}/* Emit the rtl pattern X as an appropriate kind of insn.   If X is a label, it is simply added into the insn chain.  */voidemit (x)     rtx x;{  enum rtx_code code = classify_insn (x);  if (code == CODE_LABEL)    emit_label (x);  else if (code == INSN)    emit_insn (x);  else if (code == JUMP_INSN)    {      register rtx insn = emit_jump_insn (x);      if (simplejump_p (insn) || GET_CODE (x) == RETURN)	emit_barrier ();    }  else if (code == CALL_INSN)    emit_call_insn (x);}/* Begin emitting insns to a sequence which can be packaged in an RTL_EXPR.   Return an rtx containing data on any sequence already in progress.  */rtxstart_sequence (){  sequence_stack    = gen_rtx (INSN_LIST, VOIDmode,	       first_insn, gen_rtx (INSN_LIST, VOIDmode,				    last_insn, sequence_stack));  first_insn = 0;  last_insn = 0;  return sequence_stack;}/* Set up the insn chain starting with FIRST   as the current sequence, saving the previously current one.  */voidpush_to_sequence (first)     rtx first;{  rtx last;  for (last = first; last && NEXT_INSN (last); last = NEXT_INSN (last));  sequence_stack    = gen_rtx (INSN_LIST, VOIDmode,	       first_insn, gen_rtx (INSN_LIST, VOIDmode,				    last_insn, sequence_stack));  first_insn = first;  last_insn = last;}/* After emitting to a sequence, restore previous saved state.   The argument SAVED is no longer used.   To get the contents of the sequence just made,   you must call `gen_sequence' *before* calling here.  */voidend_sequence (saved)     rtx saved;{  first_insn = XEXP (sequence_stack, 0);  last_insn = XEXP (XEXP (sequence_stack, 1), 0);  sequence_stack = XEXP (XEXP (sequence_stack, 1), 1);}/* Generate a SEQUENCE rtx containing the insns already emitted   to the current sequence.   This is how the gen_... function from a DEFINE_EXPAND   constructs the SEQUENCE that it returns.  */rtxgen_sequence (){  rtx tem;  rtvec newvec;  int i;  int len;  /* Count the insns in the chain.  */  len = 0;  for (tem = first_insn; tem; tem = NEXT_INSN (tem))    len++;  /* For an empty sequence... */  if (len == 0)    return gen_rtx (SEQUENCE, VOIDmode, NULL);  /* If only one insn, return its pattern rather than a SEQUENCE.  */  if (len == 1      && (GET_CODE (first_insn) == INSN	  || GET_CODE (first_insn) == JUMP_INSN	  || GET_CODE (first_insn) == CALL_INSN))    return PATTERN (first_insn);  /* Put them in a vector.  */  newvec = rtvec_alloc (len);  i = 0;  for (tem = first_insn; tem; tem = NEXT_INSN (tem), i++)    newvec->elem[i].rtx = tem;  /* Make a SEQUENCE from this vector.  */  return gen_rtx (SEQUENCE, VOIDmode, newvec);}/* Set up regno_reg_rtx, reg_rtx_no and regno_pointer_flag   according to the chain of insns starting with FIRST.   Also set cur_insn_uid to exceed the largest uid in that chain.   This is used when an inline function's rtl is saved   and passed to rest_of_compilation later.  */static void restore_reg_data_1 ();voidrestore_reg_data (first)     rtx first;{  register rtx insn;  int i;  register int max_uid = 0;  for (insn = first; insn; insn = NEXT_INSN (insn))    {      if (INSN_UID (insn) >= max_uid)	max_uid = INSN_UID (insn);      switch (GET_CODE (insn))	{	case NOTE:	case CODE_LABEL:	case BARRIER:	  break;	case JUMP_INSN:	case CALL_INSN:	case INSN:	  restore_reg_data_1 (PATTERN (insn));	  break;	}    }  /* Don't duplicate the uids already in use.  */  cur_insn_uid = max_uid + 1;  /* If any regs are missing, make them up.  */  for (i = FIRST_PSEUDO_REGISTER; i < reg_rtx_no; i++)    if (regno_reg_rtx[i] == 0)      regno_reg_rtx[i] = gen_rtx (REG, SImode, i);}static voidrestore_reg_data_1 (orig)     rtx orig;{  register rtx x = orig;  register int i;  register enum rtx_code code;  register char *format_ptr;  code = GET_CODE (x);  switch (code)    {    case QUEUED:    case CONST_INT:    case CONST_DOUBLE:    case SYMBOL_REF:    case CODE_LABEL:    case PC:    case CC0:    case LABEL_REF:      return;    case REG:      if (REGNO (x) >= FIRST_PSEUDO_REGISTER)	{	  /* Make sure regno_pointer_flag and regno_reg_rtx are large	     enough to have an element for this pseudo reg number.  */	  if (REGNO (x) >= reg_rtx_no)	    {	      reg_rtx_no = REGNO (x);	      if (reg_rtx_no >= regno_pointer_flag_length)		{		  int newlen = max (regno_pointer_flag_length * 2,				    reg_rtx_no + 30);		  rtx *new1;		  char *new = (char *) oballoc (newlen);		  bzero (new, newlen);		  bcopy (regno_pointer_flag, new, regno_pointer_flag_length);		  new1 = (rtx *) oballoc (newlen * sizeof (rtx));		  bzero (new1, newlen * sizeof (rtx));		  bcopy (regno_reg_rtx, new1, regno_pointer_flag_length * sizeof (rtx));		  regno_pointer_flag = new;		  regno_reg_rtx = new1;		  regno_pointer_flag_length = newlen;		}	      reg_rtx_no ++;	    }	  regno_reg_rtx[REGNO (x)] = x;	}      return;    case MEM:      if (GET_CODE (XEXP (x, 0)) == REG)	mark_reg_pointer (XEXP (x, 0));      restore_reg_data_1 (XEXP (x, 0));      return;    }  /* Now scan the subexpressions recursively.  */  format_ptr = GET_RTX_FORMAT (code);  for (i = 0; i < GET_RTX_LENGTH (code); i++)    {      switch (*format_ptr++)	{	case 'e':	  restore_reg_data_1 (XEXP (x, i));	  break;	case 'E':	  if (XVEC (x, i) != NULL)	    {	      register int j;	      for (j = 0; j < XVECLEN (x, i); j++)		restore_reg_data_1 (XVECEXP (x, i, j));	    }	  break;	}    }}/* Initialize data structures and variables in this file   before generating rtl for each function.   WRITE_SYMBOLS is nonzero if any kind of debugging info   is to be generated.  */voidinit_emit (write_symbols)     int write_symbols;{  first_insn = NULL;  last_insn = NULL;  sequence_stack = NULL;  cur_insn_uid = 1;  reg_rtx_no = FIRST_PSEUDO_REGISTER;  last_linenum = 0;  last_filename = 0;  first_label_num = label_num;  no_line_numbers = ! write_symbols;    /* Init the tables that describe all the pseudo regs.  */  regno_pointer_flag_length = FIRST_PSEUDO_REGISTER + 100;  regno_pointer_flag     = (char *) oballoc (regno_pointer_flag_length);  bzero (regno_pointer_flag, regno_pointer_flag_length);  regno_reg_rtx     = (rtx *) oballoc (regno_pointer_flag_length * sizeof (rtx));  bzero (regno_reg_rtx, regno_pointer_flag_length * sizeof (rtx));}/* Create some permanent unique rtl objects shared between all functions.  */voidinit_emit_once (){  /* Create the unique rtx's for certain rtx codes and operand values.  */  pc_rtx = gen_rtx (PC, VOIDmode);  cc0_rtx = gen_rtx (CC0, VOIDmode);  /* Don't use gen_rtx here since gen_rtx in this case     tries to use these variables.  */  const0_rtx = rtx_alloc (CONST_INT);  INTVAL (const0_rtx) = 0;  const1_rtx = rtx_alloc (CONST_INT);  INTVAL (const1_rtx) = 1;  fconst0_rtx = rtx_alloc (CONST_DOUBLE);  dconst0_rtx = rtx_alloc (CONST_DOUBLE);  {    union real_extract u;#ifdef REAL_IS_NOT_DOUBLE    bzero (&u, sizeof u);    u.d = REAL_VALUE_ATOF ("0");#else    u.d = 0;#endif    bcopy (&u, &CONST_DOUBLE_LOW (fconst0_rtx), sizeof u);    CONST_DOUBLE_MEM (fconst0_rtx) = cc0_rtx;    PUT_MODE (fconst0_rtx, SFmode);    bcopy (&u, &CONST_DOUBLE_LOW (dconst0_rtx), sizeof u);    CONST_DOUBLE_MEM (dconst0_rtx) = cc0_rtx;    PUT_MODE (dconst0_rtx, DFmode);  }  stack_pointer_rtx = gen_rtx (REG, Pmode, STACK_POINTER_REGNUM);  frame_pointer_rtx = gen_rtx (REG, Pmode, FRAME_POINTER_REGNUM);#ifdef STRUCT_VALUE  struct_value_rtx = STRUCT_VALUE;#else  struct_value_rtx = gen_rtx (REG, Pmode, STRUCT_VALUE_REGNUM);#endif#ifdef STRUCT_VALUE_INCOMING  struct_value_incoming_rtx = STRUCT_VALUE_INCOMING;#else#ifdef STRUCT_VALUE_INCOMING_REGNUM  struct_value_incoming_rtx    = gen_rtx (REG, Pmode, STRUCT_VALUE_INCOMING_REGNUM);#else  struct_value_incoming_rtx = struct_value_rtx;#endif#endif  static_chain_rtx = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);#ifdef STATIC_CHAIN_INCOMING_REGNUM  if (STATIC_CHAIN_INCOMING_REGNUM != STATIC_CHAIN_REGNUM)    static_chain_incoming_rtx = gen_rtx (REG, Pmode, STATIC_CHAIN_INCOMING_REGNUM);  else#endif    static_chain_incoming_rtx = static_chain_rtx;  if (FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM)    arg_pointer_rtx = frame_pointer_rtx;  else    arg_pointer_rtx = gen_rtx (REG, Pmode, ARG_POINTER_REGNUM);}

⌨️ 快捷键说明

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