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

📄 stmt.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	    break;	  }      if (n == 0)	except_stack->exit_label = except_stack->data.except_stmt.after_label;    }  if (escapeflag)    {      struct nesting *n;      /* An `escape' from catch clauses goes out to next escape level,	 if there is one.  Otherwise, it just goes to the end	 of the construct.  */      for (n = except_stack->next; n; n = n->next)	if (n->data.except_stmt.escape_label != 0)	  {	    except_stack->data.except_stmt.escape_label	      = n->data.except_stmt.escape_label;	    break;	  }      if (n == 0)	except_stack->data.except_stmt.escape_label	  = except_stack->data.except_stmt.after_label;    }  do_pending_stack_adjust ();  emit_label (except_stack->data.except_stmt.except_label);}/* Generate code to `escape' from an exception contour.  This   is like `exiting', but does not conflict with constructs which   use `exit_label'.   Return nonzero if this contour is escapable, otherwise   return zero, and language-specific code will emit the   appropriate error message.  */intexpand_escape_except (){  struct nesting *n;  last_expr_type = 0;  for (n = except_stack; n; n = n->next)    if (n->data.except_stmt.escape_label != 0)      {	expand_goto_internal (NULL_TREE,			      n->data.except_stmt.escape_label, NULL_RTX);	return 1;      }  return 0;}/* Finish processing and `except' contour.   Culls out all exceptions which might be raise but not   handled, and returns the list to the caller.   Language-specific code is responsible for dealing with these   exceptions.  */treeexpand_end_except (){  struct nesting *n;  tree raised = NULL_TREE;  do_pending_stack_adjust ();  emit_label (except_stack->data.except_stmt.after_label);  n = except_stack->next;  if (n)    {      /* Propagate exceptions raised but not handled to next	 highest level.  */      tree handled = except_stack->data.except_stmt.raised;      if (handled != void_type_node)	{	  tree prev = NULL_TREE;	  raised = except_stack->data.except_stmt.raised;	  while (handled)	    {	      tree this_raise;	      for (this_raise = raised, prev = 0; this_raise;		   this_raise = TREE_CHAIN (this_raise))		{		  if (value_member (TREE_VALUE (this_raise), handled))		    {		      if (prev)			TREE_CHAIN (prev) = TREE_CHAIN (this_raise);		      else			{			  raised = TREE_CHAIN (raised);			  if (raised == NULL_TREE)			    goto nada;			}		    }		  else		    prev = this_raise;		}	      handled = TREE_CHAIN (handled);	    }	  if (prev == NULL_TREE)	    prev = raised;	  if (prev)	    TREE_CHAIN (prev) = n->data.except_stmt.raised;	nada:	  n->data.except_stmt.raised = raised;	}    }  POPSTACK (except_stack);  last_expr_type = 0;  return raised;}/* Record that exception EX is caught by this exception handler.   Return nonzero if in exception handling construct, otherwise return 0.  */intexpand_catch (ex)     tree ex;{  tree *raises_ptr;  if (except_stack == 0)    return 0;  raises_ptr = &except_stack->data.except_stmt.handled;  if (*raises_ptr != void_type_node      && ex != NULL_TREE      && ! value_member (ex, *raises_ptr))    *raises_ptr = tree_cons (NULL_TREE, ex, *raises_ptr);  return 1;}/* Record that this exception handler catches all exceptions.   Return nonzero if in exception handling construct, otherwise return 0.  */intexpand_catch_default (){  if (except_stack == 0)    return 0;  except_stack->data.except_stmt.handled = void_type_node;  return 1;}intexpand_end_catch (){  if (except_stack == 0 || except_stack->data.except_stmt.after_label == 0)    return 0;  expand_goto_internal (NULL_TREE, except_stack->data.except_stmt.after_label,			NULL_RTX);  return 1;}/* Generate RTL for the start of an if-then.  COND is the expression   whose truth should be tested.   If EXITFLAG is nonzero, this conditional is visible to   `exit_something'.  */voidexpand_start_cond (cond, exitflag)     tree cond;     int exitflag;{  struct nesting *thiscond = ALLOC_NESTING ();  /* Make an entry on cond_stack for the cond we are entering.  */  thiscond->next = cond_stack;  thiscond->all = nesting_stack;  thiscond->depth = ++nesting_depth;  thiscond->data.cond.next_label = gen_label_rtx ();  /* Before we encounter an `else', we don't need a separate exit label     unless there are supposed to be exit statements     to exit this conditional.  */  thiscond->exit_label = exitflag ? gen_label_rtx () : 0;  thiscond->data.cond.endif_label = thiscond->exit_label;  cond_stack = thiscond;  nesting_stack = thiscond;  do_jump (cond, thiscond->data.cond.next_label, NULL_RTX);}/* Generate RTL between then-clause and the elseif-clause   of an if-then-elseif-....  */voidexpand_start_elseif (cond)     tree cond;{  if (cond_stack->data.cond.endif_label == 0)    cond_stack->data.cond.endif_label = gen_label_rtx ();  emit_jump (cond_stack->data.cond.endif_label);  emit_label (cond_stack->data.cond.next_label);  cond_stack->data.cond.next_label = gen_label_rtx ();  do_jump (cond, cond_stack->data.cond.next_label, NULL_RTX);}/* Generate RTL between the then-clause and the else-clause   of an if-then-else.  */voidexpand_start_else (){  if (cond_stack->data.cond.endif_label == 0)    cond_stack->data.cond.endif_label = gen_label_rtx ();  emit_jump (cond_stack->data.cond.endif_label);  emit_label (cond_stack->data.cond.next_label);  cond_stack->data.cond.next_label = 0;  /* No more _else or _elseif calls. */}/* Generate RTL for the end of an if-then.   Pop the record for it off of cond_stack.  */voidexpand_end_cond (){  struct nesting *thiscond = cond_stack;  do_pending_stack_adjust ();  if (thiscond->data.cond.next_label)    emit_label (thiscond->data.cond.next_label);  if (thiscond->data.cond.endif_label)    emit_label (thiscond->data.cond.endif_label);  POPSTACK (cond_stack);  last_expr_type = 0;}/* Generate RTL for the start of a loop.  EXIT_FLAG is nonzero if this   loop should be exited by `exit_something'.  This is a loop for which   `expand_continue' will jump to the top of the loop.   Make an entry on loop_stack to record the labels associated with   this loop.  */struct nesting *expand_start_loop (exit_flag)     int exit_flag;{  register struct nesting *thisloop = ALLOC_NESTING ();  /* Make an entry on loop_stack for the loop we are entering.  */  thisloop->next = loop_stack;  thisloop->all = nesting_stack;  thisloop->depth = ++nesting_depth;  thisloop->data.loop.start_label = gen_label_rtx ();  thisloop->data.loop.end_label = gen_label_rtx ();  thisloop->data.loop.continue_label = thisloop->data.loop.start_label;  thisloop->exit_label = exit_flag ? thisloop->data.loop.end_label : 0;  loop_stack = thisloop;  nesting_stack = thisloop;  do_pending_stack_adjust ();  emit_queue ();  emit_note (NULL_PTR, NOTE_INSN_LOOP_BEG);  emit_label (thisloop->data.loop.start_label);  return thisloop;}/* Like expand_start_loop but for a loop where the continuation point   (for expand_continue_loop) will be specified explicitly.  */struct nesting *expand_start_loop_continue_elsewhere (exit_flag)     int exit_flag;{  struct nesting *thisloop = expand_start_loop (exit_flag);  loop_stack->data.loop.continue_label = gen_label_rtx ();  return thisloop;}/* Specify the continuation point for a loop started with   expand_start_loop_continue_elsewhere.   Use this at the point in the code to which a continue statement   should jump.  */voidexpand_loop_continue_here (){  do_pending_stack_adjust ();  emit_note (NULL_PTR, NOTE_INSN_LOOP_CONT);  emit_label (loop_stack->data.loop.continue_label);}/* Finish a loop.  Generate a jump back to the top and the loop-exit label.   Pop the block off of loop_stack.  */voidexpand_end_loop (){  register rtx insn = get_last_insn ();  register rtx start_label = loop_stack->data.loop.start_label;  rtx last_test_insn = 0;  int num_insns = 0;  /* Mark the continue-point at the top of the loop if none elsewhere.  */  if (start_label == loop_stack->data.loop.continue_label)    emit_note_before (NOTE_INSN_LOOP_CONT, start_label);  do_pending_stack_adjust ();  /* If optimizing, perhaps reorder the loop.  If the loop     starts with a conditional exit, roll that to the end     where it will optimize together with the jump back.     We look for the last conditional branch to the exit that we encounter     before hitting 30 insns or a CALL_INSN.  If we see an unconditional     branch to the exit first, use it.     We must also stop at NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes     because moving them is not valid.  */  if (optimize      &&      ! (GET_CODE (insn) == JUMP_INSN	 && GET_CODE (PATTERN (insn)) == SET	 && SET_DEST (PATTERN (insn)) == pc_rtx	 && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE))    {      /* Scan insns from the top of the loop looking for a qualified	 conditional exit.  */      for (insn = NEXT_INSN (loop_stack->data.loop.start_label); insn;	   insn = NEXT_INSN (insn))	{	  if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == CODE_LABEL)	    break;	  if (GET_CODE (insn) == NOTE	      && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG		  || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END))	    break;	  if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == INSN)	    num_insns++;	  if (last_test_insn && num_insns > 30)	    break;	  if (GET_CODE (insn) == JUMP_INSN && GET_CODE (PATTERN (insn)) == SET	      && SET_DEST (PATTERN (insn)) == pc_rtx	      && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE	      && ((GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == LABEL_REF		   && (XEXP (XEXP (SET_SRC (PATTERN (insn)), 1), 0)		       == loop_stack->data.loop.end_label))		  || (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 2)) == LABEL_REF		      && (XEXP (XEXP (SET_SRC (PATTERN (insn)), 2), 0)			  == loop_stack->data.loop.end_label))))	    last_test_insn = insn;	  if (last_test_insn == 0 && GET_CODE (insn) == JUMP_INSN	      && GET_CODE (PATTERN (insn)) == SET	      && SET_DEST (PATTERN (insn)) == pc_rtx	      && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF	      && (XEXP (SET_SRC (PATTERN (insn)), 0)		  == loop_stack->data.loop.end_label))	    /* Include BARRIER.  */	    last_test_insn = NEXT_INSN (insn);	}      if (last_test_insn != 0 && last_test_insn != get_last_insn ())	{	  /* We found one.  Move everything from there up	     to the end of the loop, and add a jump into the loop	     to jump to there.  */	  register rtx newstart_label = gen_label_rtx ();	  register rtx start_move = start_label;	  /* If the start label is preceded by a NOTE_INSN_LOOP_CONT note,	     then we want to move this note also.  */	  if (GET_CODE (PREV_INSN (start_move)) == NOTE	      && (NOTE_LINE_NUMBER (PREV_INSN (start_move))		  == NOTE_INSN_LOOP_CONT))	    start_move = PREV_INSN (start_move);	  emit_label_after (newstart_label, PREV_INSN (start_move));	  reorder_insns (start_move, last_test_insn, get_last_insn ());	  emit_jump_insn_after (gen_jump (start_label),				PREV_INSN (newstart_label));	  emit_barrier_after (PREV_INSN (newstart_label));	  start_label = newstart_label;	}    }  emit_jump (start_label);  emit_note (NULL_PTR, NOTE_INSN_LOOP_END);  emit_label (loop_stack->data.loop.end_label);  POPSTACK (loop_stack);  last_expr_type = 0;}/* Generate a jump to the current loop's continue-point.   This is usually the top of the loop, but may be specified   explicitly elsewhere.  If not currently inside a loop,   return 0 and do nothing; caller will print an error message.  */intexpand_continue_loop (whichloop)     struct nesting *whichloop;{  last_expr_type = 0;  if (whichloop == 0)    whichloop = loop_stack;  if (whichloop == 0)    return 0;  expand_goto_internal (NULL_TREE, whichloop->data.loop.continue_label,			NULL_RTX);  return 1;}/* Generate a jump to exit the current loop.  If not currently inside a loop,   return 0 and do nothing; caller will print an error message.  

⌨️ 快捷键说明

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