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

📄 pa.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
  actual_fsize = compute_frame_size (size, leaf_function, &save_fregs) + 32;  if (TARGET_SNAKE)    actual_fsize = (actual_fsize + 63) & ~63;  /* Let's not try to bullshit more than we need to here. */  /* This might be right a lot of the time */  fprintf (file, "\t.PROC\n\t.CALLINFO FRAME=%d", actual_fsize);    if (regs_ever_live[2] || profile_flag)      fprintf (file, ",CALLS,SAVE_RP\n");    else      fprintf (file, ",NO_CALLS\n");  fprintf (file, "\t.ENTRY\n");  /* Some registers have places to go in the current stack     structure.  */  if (regs_ever_live[2] || profile_flag)    fprintf (file, "\tstw 2,-20(0,30)\n");  /* Reserve space for local variables.  */  if (frame_pointer_needed)    {      if (VAL_14_BITS_P (actual_fsize))	fprintf (file, "\tcopy 4,1\n\tcopy 30,4\n\tstwm 1,%d(0,30)\n",		 actual_fsize);      else	{	  fprintf (file, "\tcopy 4,1\n\tcopy 30,4\n\tstw 1,0(0,4)\n");	  fprintf (file, "\taddil L'%d,30\n\tldo R'%d(1),30\n",		   actual_fsize, actual_fsize);	}    }  else    /* Used to be abort ();  */    {      if (VAL_14_BITS_P (actual_fsize))	fprintf (file, "\tldo %d(30),30\n", actual_fsize);      else	fprintf (file, "\taddil L'%d,30\n\tldo R'%d(1),30\n",		 actual_fsize, actual_fsize);    }  /* The hppa calling conventions say that that %r19, the pic offset      register, is saved at sp - 32 (in this function's frame) */  if (flag_pic)    {      fprintf (file, "\tstw %%r19,-32(%%r30)\n");    }  /* Instead of taking one argument, the counter label, as most normal     mcounts do, _mcount appears to behave differently on the HPPA. It     takes the return address of the caller, the address of this     routine, and the address of the label. Also, it isn't magic, so     argument registers have to be preserved. */  if (profile_flag)    {      unsigned int pc_offset =	(4 + (frame_pointer_needed	      ? (VAL_14_BITS_P (actual_fsize) ? 12 : 20)	      : (VAL_14_BITS_P (actual_fsize) ? 4 : 8)));      int i, arg_offset;      int basereg, offsetadj;      /* When the function has a frame pointer, use that as the base 	 register for saving/restoring registers.  Else use the stack	 pointer.  Adjust the offset according to the frame size if this	 function does not have a frame pointer.  */      basereg = frame_pointer_needed ? FRAME_POINTER_REGNUM				     : STACK_POINTER_REGNUM;      offsetadj = frame_pointer_needed ? 0 : actual_fsize;      if (current_function_returns_struct)	print_stw (file, STRUCT_VALUE_REGNUM, - 12 - offsetadj, basereg);      for (i = 26, arg_offset = -36 - offsetadj; i >= 23; i--, arg_offset -= 4)	if (regs_ever_live[i])	  {	    print_stw (file, i, arg_offset, basereg);	    /* It is possible for the arg_offset not to fit in 14 bits                when profiling a function without a frame pointer.  Deal	       with such cases.  */	    pc_offset += VAL_14_BITS_P (arg_offset) ? 4 : 8;	  }      fprintf (file,	       "\tcopy %%r2,%%r26\n\taddil L'LP$%04d-$global$,%%r27\n\\tldo R'LP$%04d-$global$(%%r1),%%r24\n\tbl _mcount,%%r2\n\\tldo %d(%%r2),%%r25\n",	       hp_profile_labelno, hp_profile_labelno, -pc_offset - 12 - 8);      for (i = 26, arg_offset = -36 - offsetadj; i >= 23; i--, arg_offset -= 4)	if (regs_ever_live[i])	  print_ldw (file, i, arg_offset, basereg);      if (current_function_returns_struct)	print_ldw (file, STRUCT_VALUE_REGNUM, - 12 - offsetadj, basereg);    }  /* Normal register save. */  if (frame_pointer_needed)    {      for (i = 18, offset = local_fsize; i >= 5; i--)	if (regs_ever_live[i] && ! call_used_regs[i])	  {	    print_stw (file, i, offset, 4);  offset += 4;	  }      if (regs_ever_live[3] && ! call_used_regs[3])	{	  print_stw (file, 3, offset, 4);  offset += 4;	}    }  else    {      for (i = 18, offset = local_fsize - actual_fsize; i >= 5; i--)      	if (regs_ever_live[i] && ! call_used_regs[i])	  {	    print_stw (file, i, offset, 30);  offset += 4;	  }      if (regs_ever_live[3] && ! call_used_regs[3])	{	  print_stw (file, 3, offset, 30);  offset += 4;	}    }        /* Align pointer properly (doubleword boundary).  */  offset = (offset + 7) & ~7;  /* Floating point register store.  */  if (save_fregs)    if (frame_pointer_needed)      {	if (VAL_14_BITS_P (offset))	  fprintf (file, "\tldo %d(4),1\n", offset);	else	  fprintf (file, "\taddil L'%d,4\n\tldo R'%d(1),1\n", offset, offset);      }    else      {	if (VAL_14_BITS_P (offset))	  fprintf (file, "\tldo %d(30),1\n", offset);	else	  fprintf (file, "\taddil L'%d,30\n\tldo R'%d(1),1\n", offset, offset);      }  if (!TARGET_SNAKE)    {      for (i = 47; i >= 44; i--)	{	  if (regs_ever_live[i])	    fprintf (file, "\tfstds,ma %s,8(0,1)\n", reg_names[i]);	}    }  else    {      for (i = 90; i >= 72; i -= 2)	if (regs_ever_live[i] || regs_ever_live[i + 1])	  {	    fprintf (file, "\tfstds,ma %s,8(0,1)\n", reg_names[i]);	  }    }}voidoutput_function_epilogue (file, size, leaf_function)     FILE *file;     int size;     int leaf_function;{  extern char call_used_regs[];  extern int frame_pointer_needed;  int  i, offset;  if (frame_pointer_needed)    {      for (i = 18, offset = local_fsize; i >= 5; i--)	if (regs_ever_live[i] && ! call_used_regs[i])	  {	    print_ldw (file, i, offset, 4);  offset += 4;	  }      if (regs_ever_live[3] && ! call_used_regs[3])	{	  print_ldw (file, 3, offset, 4);  offset += 4;	  	}    }  else    {      for (i = 18, offset = local_fsize - actual_fsize; i >= 5; i--)      	if (regs_ever_live[i] && ! call_used_regs[i])	  {	    print_ldw (file, i, offset, 30);  offset += 4;	  }      if (regs_ever_live[3] && ! call_used_regs[3])	{	  print_ldw (file, 3, offset, 30);  offset += 4;	}    }        /* Align pointer properly (doubleword boundary).  */  offset = (offset + 7) & ~7;  /* Floating point register restore.  */  if (save_fregs)    if (frame_pointer_needed)      {	if (VAL_14_BITS_P (offset))	  fprintf (file, "\tldo %d(4),1\n", offset);	else	  fprintf (file, "\taddil L'%d,4\n\tldo R'%d(1),1\n", offset, offset);      }    else      {	if (VAL_14_BITS_P (offset))	  fprintf (file, "\tldo %d(30),1\n", offset);	else	  fprintf (file, "\taddil L'%d,30\n\tldo R'%d(1),1\n", offset, offset);      }  if (!TARGET_SNAKE)    {      for (i = 47; i >= 44; i--)	{	  if (regs_ever_live[i])	    fprintf (file, "\tfldds,ma 8(0,1),%s\n", reg_names[i]);	}    }  else    {      for (i = 90; i >= 72; i -= 2)	if (regs_ever_live[i] || regs_ever_live[i + 1])	  {	    fprintf (file, "\tfldds,ma 8(0,1),%s\n", reg_names[i]);	  }    }  /* Reset stack pointer (and possibly frame pointer).  The stack */  /* pointer is initially set to fp + 8 to avoid a race condition. */  if (frame_pointer_needed)    {      fprintf (file, "\tldo 8(4),30\n");      if (regs_ever_live[2] || profile_flag)	fprintf (file, "\tldw -28(0,30),2\n");      fprintf (file, "\tbv 0(2)\n\tldwm -8(30),4\n");    }  else if (actual_fsize)    {      if ((regs_ever_live[2] || profile_flag)          && VAL_14_BITS_P (actual_fsize + 20))	fprintf (file, "\tldw %d(30),2\n\tbv 0(2)\n\tldo %d(30),30\n",		 -(actual_fsize + 20), -actual_fsize);      else if (regs_ever_live[2] || profile_flag)	fprintf (file,		 "\taddil L'%d,30\n\tldw %d(1),2\n\tbv 0(2)\n\tldo R'%d(1),30\n",		 - actual_fsize,		 - (actual_fsize + 20 + ((-actual_fsize) & ~0x7ff)),		 /* - ((actual_fsize + 20) - (actual_fsize & ~0x7ff)), */		 - actual_fsize);      else if (VAL_14_BITS_P (actual_fsize))	fprintf (file, "\tbv 0(2)\n\tldo %d(30),30\n", - actual_fsize);      else	fprintf (file, "\taddil L'%d,30\n\tbv 0(2)\n\tldo R'%d(1),30\n");    }  else if (current_function_epilogue_delay_list)    {      fprintf (file, "\tbv 0(2)\n");      final_scan_insn (XEXP (current_function_epilogue_delay_list, 0),		       file, write_symbols, 1, 0, 1);    }  else    fprintf (file, "\tbv,n 0(2)\n");  fprintf (file, "\t.EXIT\n\t.PROCEND\n");}rtxgen_compare_reg (code, x, y)     enum rtx_code code;     rtx x, y;{  enum machine_mode mode = SELECT_CC_MODE (code, x, y);  rtx cc_reg = gen_rtx (REG, mode, 0);  emit_insn (gen_rtx (SET, VOIDmode, cc_reg,		      gen_rtx (COMPARE, mode, x, y)));  return cc_reg;}/* Return nonzero if TRIAL can go into the function epilogue's   delay slot.  SLOT is the slot we are trying to fill.  */inteligible_for_epilogue_delay (trial, slot)     rtx trial;     int slot;{  if (slot >= 1)    return 0;  if (GET_CODE (trial) != INSN      || GET_CODE (PATTERN (trial)) != SET)    return 0;  if (get_attr_length (trial) != 1)    return 0;  return (leaf_function &&	  get_attr_in_branch_delay (trial) == IN_BRANCH_DELAY_TRUE);}rtxgen_scond_fp (code, operand0)     enum rtx_code code;     rtx operand0;{  return gen_rtx (SET, VOIDmode, operand0,		  gen_rtx (code, CCFPmode,			   gen_rtx (REG, CCFPmode, 0), const0_rtx));}voidemit_bcond_fp (code, operand0)     enum rtx_code code;     rtx operand0;{  emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,			   gen_rtx (IF_THEN_ELSE, VOIDmode,				    gen_rtx (code, VOIDmode, 					     gen_rtx (REG, CCFPmode, 0),					     const0_rtx),				    gen_rtx (LABEL_REF, VOIDmode, operand0),				    pc_rtx)));}rtxgen_cmp_fp (code, operand0, operand1)     enum rtx_code code;     rtx operand0, operand1;{  return gen_rtx (SET, VOIDmode, gen_rtx (REG, CCFPmode, 0),		  gen_rtx (code, CCFPmode, operand0, operand1));}/* Print operand X (an rtx) in assembler syntax to file FILE.   CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.   For `%' followed by punctuation, CODE is the punctuation and X is null.  */voidprint_operand (file, x, code)     FILE *file;     rtx x;     int code;{  switch (code)    {    case '#':      /* Output a 'nop' if there's nothing for the delay slot.  */      if (dbr_sequence_length () == 0)	fputs ("\n\tnop", file);      return;    case '*':      /* Output an nullification completer if there's nothing for the */      /* delay slot or nullification is requested.  */       if (dbr_sequence_length () == 0 ||	  (final_sequence &&	   INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0))))        fputs (",n", file);      return;    case 'R':      /* Print out the second register name of a register pair.	 I.e., R (6) => 7.  */      fputs (reg_names[REGNO (x)+1], file);      return;    case 'r':      /* A register or zero. */      if (x == const0_rtx)	{	  fputs ("0", file);	  return;	}      else	break;    case 'O':      switch (GET_CODE (x))	{	case PLUS:	  fprintf (file, "add%s",		   GET_CODE (XEXP (x, 1)) == CONST_INT ? "i" : "");  break;	case MINUS:	  fprintf (file, "sub%s",		   GET_CODE (XEXP (x, 0)) == CONST_INT ? "i" : "");  break;	case AND:	  fprintf (file, "and%s",		   GET_CODE (XEXP (x, 1)) == NOT ? "cm" : "");  break;	case IOR:	  fprintf (file, "or");  break;	case XOR:	  fprintf (file, "xor");  break;	case ASHIFT:	  fprintf (file, "sh%dadd", INTVAL (XEXP (x, 1)));  break;	  /* Too lazy to handle bitfield conditions yet.  */	default:	  printf ("Can't grok '%c' operator:\n", code);	  debug_rtx (x);	  abort ();	}      return;    case 'C':    case 'X':      switch (GET_CODE (x))	{		case EQ:	  fprintf (file, "=");  break;	case NE:	  if (code == 'C')	    fprintf (file, "<>");	  else	    fprintf (file, "!=");	  break;	case GT:	  fprintf (file, ">");  break;	case GE:	  fprintf (file, ">=");  break;	case GEU:	  fprintf (file, ">>=");  break;	case GTU:	  fprintf (file, ">>");  break;	case LT:	  fprintf (file, "<");  break;	case LE:	  fprintf (file, "<=");  break;	case LEU:	  fprintf (file, "<<=");  break;	case LTU:	  fprintf (file, "<<");  break;	default:	  printf ("Can't grok '%c' operator:\n", code);	  debug_rtx (x);	  abort ();	}      return;    case 'N':    case 'Y':      switch (GET_CODE (x))	{	case EQ:	  if (code == 'N')	    fprintf (file, "<>");	  else	    fprintf (file, "!=");	  break;	case NE:	  fprintf (file, "=");  break;	case GT:	  fprintf (file, "<=");  break;	case GE:	  fprintf (file, "<");  break;	case GEU:	  fprintf (file, "<<");  break;	case GTU:	  fprintf (file, "<<=");  break;	case LT:	  fprintf (file, ">=");  break;	case LE:	  fprintf (file, ">");  break;	case LEU:	  fprintf (file, ">>");  break;	case LTU:	  fprintf (file, ">>=");  break;	default:	  printf ("Can't grok '%c' operator:\n", code);	  debug_rtx (x);	  abort ();	}      return;    case 'M':      switch (GET_CODE (XEXP (x, 0)))	{	case PRE_DEC:	case PRE_INC:	  fprintf (file, "s,mb");	  break;	case POST_DEC:	case POST_INC:	  fprintf (file, "s,ma");	  break;	default:	  break;	}      return;    case 'F':      switch (GET_CODE (XEXP (x, 0)))	{	case PRE_DEC:	case PRE_INC:	  fprintf (file, ",mb");	  break;	case POST_DEC:	case POST_INC:	  fprintf (file, ",ma");	  break;	default:	  break;	}      return;    case 'G':      output_global_address (file, x);      return;    case 0:			/* Don't do anything special */      break;    default:      abort ();    }  if (GET_CODE (x) == REG)    fprintf (file, "%s", reg_names [REGNO (x)]);  else if (GET_CODE (x) == MEM)    {      int size = GET_MODE_SIZE (GET_MODE (x));

⌨️ 快捷键说明

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