contrib/gcc-2.3.3/config/mips.c
/* Expand the prologue into a bunch of separate insns.  */
Expand the prologue into a bunch of separate insns.
Expand the prologue into a bunch of separate insns .
void
mips_expand_prologue ()
{
  int regno;
  long tsize;
  rtx tmp_rtx	 = (rtx)0;
  char *arg_name = (char *)0;
  tree fndecl	 = current_function_decl;
  tree fntype	 = TREE_TYPE (fndecl);
  tree fnargs	 = (TREE_CODE (fntype) != METHOD_TYPE)
			? DECL_ARGUMENTS (fndecl)
			: 0;
  rtx next_arg_reg;
  int i;
  tree next_arg;
  tree cur_arg;
  CUMULATIVE_ARGS args_so_far;
  INIT_CUMULATIVE_ARGS (args_so_far, fntype, (rtx)0);
  regno = GP_ARG_FIRST;
  for (cur_arg = fnargs; cur_arg != (tree)0; cur_arg = next_arg)
    {
      tree type = DECL_ARG_TYPE (cur_arg);
      enum machine_mode passed_mode = TYPE_MODE (type);
      rtx entry_parm = FUNCTION_ARG (args_so_far,
				     passed_mode,
				     DECL_ARG_TYPE (cur_arg),
				     1);
      if (entry_parm)
	{
	  int words;
	  if (GET_MODE (entry_parm) == BLKmode)
	    words = (int_size_in_bytes (type) + 3) / 4;
	  else
	    words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
	  regno = REGNO (entry_parm) + words - 1;
	}
      else
	{
	  regno = GP_ARG_LAST+1;
	  break;
	}
      FUNCTION_ARG_ADVANCE (args_so_far,
			    passed_mode,
			    DECL_ARG_TYPE (cur_arg),
			    1);
      next_arg = TREE_CHAIN (cur_arg);
      if (next_arg == (tree)0)
	{
	  if (DECL_NAME (cur_arg))
	    arg_name = IDENTIFIER_POINTER (DECL_NAME (cur_arg));
	  break;
	}
    }
  next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1);
  if (next_arg_reg != (rtx)0 && GET_CODE (next_arg_reg) == PARALLEL)
    {
      rtvec adjust = XVEC (next_arg_reg, 0);
      int num = GET_NUM_ELEM (adjust);
      for (i = 0; i < num; i++)
	{
	  rtx pattern = RTVEC_ELT (adjust, i);
	  if (GET_CODE (pattern) != SET
	      || GET_CODE (SET_SRC (pattern)) != ASHIFT)
	    abort_with_insn (pattern, "Insn is not a shift");
	  PUT_CODE (SET_SRC (pattern), ASHIFTRT);
	  emit_insn (pattern);
	}
    }
  if ((TYPE_ARG_TYPES (fntype) != 0
       && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) != void_type_node))
      || (arg_name != (char *)0
	  && ((arg_name[0] == '_' && strcmp (arg_name, "__builtin_va_alist") == 0)
	      || (arg_name[0] == 'v' && strcmp (arg_name, "va_alist") == 0))))
    {
      for (; regno <= GP_ARG_LAST; regno++)
	{
	  rtx ptr = stack_pointer_rtx;
	  if (regno != GP_ARG_FIRST)
	    ptr = gen_rtx (PLUS, Pmode, ptr,
			   GEN_INT ((regno - GP_ARG_FIRST) * UNITS_PER_WORD));
	  emit_move_insn (gen_rtx (MEM, Pmode, ptr), gen_rtx (REG, Pmode, regno));
	}
    }
  tsize = compute_frame_size (get_frame_size ());
  if (tsize > 0)
    {
      rtx tsize_rtx = GEN_INT (tsize);
      if (tsize > 32767)
	{
	  tmp_rtx = gen_rtx (REG, SImode, MIPS_TEMP1_REGNUM);
	  emit_move_insn (tmp_rtx, tsize_rtx);
	  tsize_rtx = tmp_rtx;
	}
      emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tsize_rtx));
      save_restore_insns (TRUE, tmp_rtx, tsize, (FILE *)0);
      if (frame_pointer_needed)
	emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
    }
  if (profile_flag || profile_block_flag)
    emit_insn (gen_blockage ());
}
void mips_expand_prologue ( ) { int regno ; long tsize ; rtx tmp_rtx = ( rtx ) 0 ; char * arg_name = ( char * ) 0 ; tree fndecl = current_function_decl ; tree fntype = TREE_TYPE ( fndecl ) ; tree fnargs = ( TREE_CODE ( fntype ) != METHOD_TYPE ) ? DECL_ARGUMENTS ( fndecl ) : 0 ; rtx next_arg_reg ; int i ; tree next_arg ; tree cur_arg ; CUMULATIVE_ARGS args_so_far ; INIT_CUMULATIVE_ARGS ( args_so_far , fntype , ( rtx ) 0 ) ; regno = GP_ARG_FIRST ; for ( cur_arg = fnargs ; cur_arg != ( tree ) 0 ; cur_arg = next_arg ) { tree type = DECL_ARG_TYPE ( cur_arg ) ; enum machine_mode passed_mode = TYPE_MODE ( type ) ; rtx entry_parm = FUNCTION_ARG ( args_so_far , passed_mode , DECL_ARG_TYPE ( cur_arg ) , 1 ) ; if ( entry_parm ) { int words ; if ( GET_MODE ( entry_parm ) == BLKmode ) words = ( int_size_in_bytes ( type ) + 3 ) / 4 ; else words = ( GET_MODE_SIZE ( GET_MODE ( entry_parm ) ) + 3 ) / 4 ; regno = REGNO ( entry_parm ) + words - 1 ; } else { regno = GP_ARG_LAST + 1 ; break ; } FUNCTION_ARG_ADVANCE ( args_so_far , passed_mode , DECL_ARG_TYPE ( cur_arg ) , 1 ) ; next_arg = TREE_CHAIN ( cur_arg ) ; if ( next_arg == ( tree ) 0 ) { if ( DECL_NAME ( cur_arg ) ) arg_name = IDENTIFIER_POINTER ( DECL_NAME ( cur_arg ) ) ; break ; } } next_arg_reg = FUNCTION_ARG ( args_so_far , VOIDmode , void_type_node , 1 ) ; if ( next_arg_reg != ( rtx ) 0 && GET_CODE ( next_arg_reg ) == PARALLEL ) { rtvec adjust = XVEC ( next_arg_reg , 0 ) ; int num = GET_NUM_ELEM ( adjust ) ; for ( i = 0 ; i < num ; i ++ ) { rtx pattern = RTVEC_ELT ( adjust , i ) ; if ( GET_CODE ( pattern ) != SET || GET_CODE ( SET_SRC ( pattern ) ) != ASHIFT ) abort_with_insn ( pattern , " " ) ; PUT_CODE ( SET_SRC ( pattern ) , ASHIFTRT ) ; emit_insn ( pattern ) ; } } if ( ( TYPE_ARG_TYPES ( fntype ) != 0 && ( TREE_VALUE ( tree_last ( TYPE_ARG_TYPES ( fntype ) ) ) != void_type_node ) ) || ( arg_name != ( char * ) 0 && ( ( arg_name [ 0 ] == ' ' && strcmp ( arg_name , " " ) == 0 ) || ( arg_name [ 0 ] == ' ' && strcmp ( arg_name , " " ) == 0 ) ) ) ) { for ( ; regno <= GP_ARG_LAST ; regno ++ ) { rtx ptr = stack_pointer_rtx ; if ( regno != GP_ARG_FIRST ) ptr = gen_rtx ( PLUS , Pmode , ptr , GEN_INT ( ( regno - GP_ARG_FIRST ) * UNITS_PER_WORD ) ) ; emit_move_insn ( gen_rtx ( MEM , Pmode , ptr ) , gen_rtx ( REG , Pmode , regno ) ) ; } } tsize = compute_frame_size ( get_frame_size ( ) ) ; if ( tsize > 0 ) { rtx tsize_rtx = GEN_INT ( tsize ) ; if ( tsize > 32767 ) { tmp_rtx = gen_rtx ( REG , SImode , MIPS_TEMP1_REGNUM ) ; emit_move_insn ( tmp_rtx , tsize_rtx ) ; tsize_rtx = tmp_rtx ; } emit_insn ( gen_subsi3 ( stack_pointer_rtx , stack_pointer_rtx , tsize_rtx ) ) ; save_restore_insns ( TRUE , tmp_rtx , tsize , ( FILE * ) 0 ) ; if ( frame_pointer_needed ) emit_insn ( gen_movsi ( frame_pointer_rtx , stack_pointer_rtx ) ) ; } if ( profile_flag || profile_block_flag ) emit_insn ( gen_blockage ( ) ) ; }
Expand the prologue into a bunch of separate insns.
Expand the prologue into a bunch of separate insns .
/* Determine the last argument, and get its name.  */ /* passed in a register, so will get homed automatically */ /* In order to pass small structures by value in registers
     compatibly with the MIPS compiler, we need to shift the value
     into the high part of the register.  Function_arg has encoded a
     PARALLEL rtx, holding a vector of adjustments to be made as the
     next_arg_reg variable, so we split up the insns, and emit them
     separately.  */ /* If this function is a varargs function, store any registers that
     would normally hold arguments ($4 - $7) on the stack.  */ /* If we are profiling, make sure no instructions are scheduled before
     the call to mcount.  */