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

📄 pa.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
      rtx base = XEXP (XEXP (x, 0), 0);      switch (GET_CODE (XEXP (x, 0)))	{	case PRE_DEC:	case POST_DEC:	  fprintf (file, "-%d(0,%s)", size, reg_names [REGNO (base)]);	  break;	case PRE_INC:	case POST_INC:	  fprintf (file, "%d(0,%s)", size, reg_names [REGNO (base)]);	  break;	default:	  output_address (XEXP (x, 0));	  break;	}    }  else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)    {      union { double d; int i[2]; } u;      union { float f; int i; } u1;      u.i[0] = XINT (x, 0); u.i[1] = XINT (x, 1);      u1.f = u.d;      if (code == 'f')	fprintf (file, "0r%.9g", u1.f);      else	fprintf (file, "0x%x", u1.i);    }  else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != DImode)    {      union { double d; int i[2]; } u;      u.i[0] = XINT (x, 0); u.i[1] = XINT (x, 1);      fprintf (file, "0r%.20g", u.d);    }  else    output_addr_const (file, x);}/* output a SYMBOL_REF or a CONST expression involving a SYMBOL_REF. */voidoutput_global_address (file, x)     FILE *file;     rtx x;{  if (GET_CODE (x) == SYMBOL_REF && read_only_operand (x))    assemble_name (file, XSTR (x, 0));  else if (GET_CODE (x) == SYMBOL_REF)    {      assemble_name (file, XSTR (x, 0));      fprintf (file, "-$global$");    }  else if (GET_CODE (x) == CONST)    {      char *sep = "";      int offset = 0;		/* assembler wants -$global$ at end */      rtx base;	        if (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)	{	  base = XEXP (XEXP (x, 0), 0);	  output_addr_const (file, base);	}      else if (GET_CODE (XEXP (XEXP (x, 0), 0)) == CONST_INT)	offset = INTVAL (XEXP (XEXP (x, 0), 0));      else abort ();      if (GET_CODE (XEXP (XEXP (x, 0), 1)) == SYMBOL_REF)	{	  base = XEXP (XEXP (x, 0), 1);	  output_addr_const (file, base);	}      else if (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)	offset = INTVAL (XEXP (XEXP (x, 0),1));      else abort ();      if (GET_CODE (XEXP (x, 0)) == PLUS)	{	  if (offset < 0)	    {	      offset = -offset;	      sep = "-";	    }	  else	    sep = "+";	}      else if (GET_CODE (XEXP (x, 0)) == MINUS	       && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF))	sep = "-";      else abort ();      if (!read_only_operand (base))	fprintf (file, "-$global$");      fprintf (file, "%s", sep);      if (offset) fprintf (file,"%d", offset);    }  else    output_addr_const (file, x);}/* MEM rtls here are never SYMBOL_REFs (I think), so fldws is safe. */char *output_floatsisf2 (operands)     rtx *operands;{  if (GET_CODE (operands[1]) == MEM)    return "fldws %1,%0\n\tfcnvxf,sgl,sgl %0,%0";  else if (FP_REG_P (operands[1]))    return "fcnvxf,sgl,sgl %1,%0";  return "stwm %r1,4(0,30)\n\tfldws,mb -4(0,30),%0\n\tfcnvxf,sgl,sgl %0,%0";}char *output_floatsidf2 (operands)     rtx *operands;{  if (GET_CODE (operands[1]) == MEM)    return "fldws %1,%0\n\tfcnvxf,sgl,dbl %0,%0";  else if (FP_REG_P (operands[1]))    return "fcnvxf,sgl,dbl %1,%0";  return "stwm %r1,4(0,30)\n\tfldws,mb -4(0,30),%0\n\tfcnvxf,sgl,dbl %0,%0";}enum rtx_codereverse_relop (code)     enum rtx_code code;{  switch (code)    {    case GT:      return LT;    case LT:      return GT;    case GE:      return LE;    case LE:      return GE;    case LTU:      return GTU;    case GTU:      return LTU;    case GEU:      return LEU;    case LEU:      return GEU;    default:      abort ();    }}/* HP's millicode routines mean something special to the assembler.   Keep track of which ones we have used.  */enum millicodes { remI, remU, divI, divU, mulI, mulU, end1000 };static char imported[(int)end1000];static char *milli_names[] = {"remI", "remU", "divI", "divU", "mulI", "mulU"};static char import_string[] = ".IMPORT $$....,MILLICODE";#define MILLI_START 10static intimport_milli (code)     enum millicodes code;{  char str[sizeof (import_string)];    if (!imported[(int)code])    {      imported[(int)code] = 1;      strcpy (str, import_string);      strncpy (str + MILLI_START, milli_names[(int)code], 4);      output_asm_insn (str, 0);    }}/* The register constraints have put the operands and return value in    the proper registers. */char *output_mul_insn (unsignedp)     int unsignedp;{  if (unsignedp)    {      import_milli (mulU);      return "bl $$mulU,31%#";    }  else    {      import_milli (mulI);      return "bl $$mulI,31%#";    }}/* If operands isn't NULL, then it's a CONST_INT with which we can do   something *//* Emit the rtl for doing a division by a constant. */ /* Do magic division millicodes exist for this value? */static int magic_milli[]= {0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0,			     1, 1};/* We'll use an array to keep track of the magic millicodes and    whether or not we've used them already. [n][0] is signed, [n][1] is   unsigned. */static int div_milli[16][2];intdiv_operand (op, mode)     rtx op;     enum machine_mode mode;{  return (mode == SImode	  && ((GET_CODE (op) == REG && REGNO (op) == 25)	      || (GET_CODE (op) == CONST_INT && INTVAL (op) > 0		  && INTVAL (op) < 16 && magic_milli[INTVAL (op)])));}intemit_hpdiv_const (operands, unsignedp)     rtx *operands;     int unsignedp;{  if (GET_CODE (operands[2]) == CONST_INT      && INTVAL (operands[2]) > 0      && INTVAL (operands[2]) < 16      && magic_milli[INTVAL (operands[2])])    {      emit_move_insn ( gen_rtx (REG, SImode, 26), operands[1]);      emit	(gen_rtx	 (PARALLEL, VOIDmode,	  gen_rtvec (5, gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 29),				 gen_rtx (unsignedp ? UDIV : DIV, SImode,					  gen_rtx (REG, SImode, 26),					  operands[2])),		     gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, SImode, 0)),		     gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 26)),		     gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 25)),		     gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 31)))));      emit_move_insn (operands[0], gen_rtx (REG, SImode, 29));      return 1;    }  return 0;}char *output_div_insn (operands, unsignedp)     rtx *operands;     int unsignedp;{  int divisor;    /* If the divisor is a constant, try to use one of the special      opcodes .*/  if (GET_CODE (operands[0]) == CONST_INT)    {      divisor = INTVAL (operands[0]);      if (!div_milli[divisor][unsignedp])	{	  if (unsignedp)	    output_asm_insn (".IMPORT $$divU_%0,MILLICODE", operands);	  else	    output_asm_insn (".IMPORT $$divI_%0,MILLICODE", operands);	  div_milli[divisor][unsignedp] = 1;	}      if (unsignedp)	return "bl $$divU_%0,31%#";      return "bl $$divI_%0,31%#";    }  /* Divisor isn't a special constant. */  else    {      if (unsignedp)	{	  import_milli (divU);	  return "bl $$divU,31%#";	}      else	{	  import_milli (divI);	  return "bl $$divI,31%#";	}    }}/* Output a $$rem millicode to do mod. */char *output_mod_insn (unsignedp)     int unsignedp;{  if (unsignedp)    {      import_milli (remU);      return "bl $$remU,31%#";    }  else    {      import_milli (remI);      return "bl $$remI,31%#";    }}voidoutput_arg_descriptor (insn)     rtx insn;{  char *arg_regs[4];  enum machine_mode arg_mode;  rtx prev_insn;  int i, output_flag = 0;  int regno;    for (i = 0; i < 4; i++)    arg_regs[i] = 0;  for (prev_insn = PREV_INSN (insn); GET_CODE (prev_insn) == INSN;       prev_insn = PREV_INSN (prev_insn))    {      if (!(GET_CODE (PATTERN (prev_insn)) == USE &&	    GET_CODE (XEXP (PATTERN (prev_insn), 0)) == REG &&	    FUNCTION_ARG_REGNO_P (REGNO (XEXP (PATTERN (prev_insn), 0)))))	break;      arg_mode = GET_MODE (XEXP (PATTERN (prev_insn), 0));      regno = REGNO (XEXP (PATTERN (prev_insn), 0));      if (regno >= 23 && regno <= 26)	{	  arg_regs[26 - regno] = "GR";	  if (arg_mode == DImode)	    arg_regs[25 - regno] = "GR";	}      else if (!TARGET_SNAKE)	/* fp args */	{	  if (arg_mode == SFmode)	    arg_regs[regno - 36] = "FR";	  else	    {#ifdef HP_FP_ARG_DESCRIPTOR_REVERSED	      arg_regs[regno - 37] = "FR";	      arg_regs[regno - 36] = "FU";#else	      arg_regs[regno - 37] = "FU";	      arg_regs[regno - 36] = "FR";#endif	    }	}      else	{	  if (arg_mode == SFmode)	    arg_regs[(regno - 56) / 2] = "FR";	  else	    {#ifdef HP_FP_ARG_DESCRIPTOR_REVERSED	      arg_regs[(regno - 58) / 2] = "FR";	      arg_regs[(regno - 58) / 2 + 1] = "FU";#else	      arg_regs[(regno - 58) / 2] = "FU";	      arg_regs[(regno - 58) / 2 + 1] = "FR";#endif	    }	}    }  fputs ("\t.CALL ", asm_out_file);  for (i = 0; i < 4; i++)    {      if (arg_regs[i])	{	  if (output_flag++)	    fputc (',', asm_out_file);	  fprintf (asm_out_file, "ARGW%d=%s", i, arg_regs[i]);	}    }  fputc ('\n', asm_out_file);}/* Memory loads/stores to/from the shift need to go through   the general registers.  */enum reg_classsecondary_reload_class (class, mode, in)     enum reg_class class;     enum machine_mode mode;     rtx in;{  int regno = true_regnum (in);  if ((TARGET_SHARED_LIBS && function_label_operand (in, mode))      || ((regno >= FIRST_PSEUDO_REGISTER || regno == -1)	  && ((mode == QImode || mode == HImode || mode == SImode	       || mode == DImode) 	      && (class == FP_REGS || class == SNAKE_FP_REGS		  || class == HI_SNAKE_FP_REGS)))      || (class == SHIFT_REGS && (regno <= 0 || regno >= 32)))    return GENERAL_REGS;  return NO_REGS;}enum directionfunction_arg_padding (mode, type)     enum machine_mode mode;     tree type;{  int size;  if (mode == BLKmode)    {      if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)	size = int_size_in_bytes (type) * BITS_PER_UNIT;      else	return upward;		/* Don't know if this is right, but */				/* same as old definition. */    }  else    size = GET_MODE_BITSIZE (mode);  if (size < PARM_BOUNDARY)    return downward;  else if (size % PARM_BOUNDARY)    return upward;  else    return none;}/* Do what is necessary for `va_start'.  The argument is ignored;   We look at the current function to determine if stdargs or varargs   is used and fill in an initial va_list.  A pointer to this constructor   is returned.  */struct rtx_def *hppa_builtin_saveregs (arglist)     tree arglist;{  rtx block, float_addr, offset, float_mem;  tree fntype = TREE_TYPE (current_function_decl);  int argadj = ((!(TYPE_ARG_TYPES (fntype) != 0		   && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))		       != void_type_node)))		? UNITS_PER_WORD : 0);  if (argadj)    offset = plus_constant (current_function_arg_offset_rtx, argadj);  else    offset = current_function_arg_offset_rtx;  /* Store general registers on the stack. */  move_block_from_reg (23,		       gen_rtx (MEM, BLKmode,				plus_constant				(current_function_internal_arg_pointer, -16)),		       4);   return copy_to_reg (expand_binop (Pmode, add_optab,				    current_function_internal_arg_pointer,				    offset, 0, 0, OPTAB_LIB_WIDEN));}extern struct obstack *saveable_obstack;/* In HPUX 8.0's shared library scheme, special relocations are needed   for function labels if they might be passed to a function    in a shared library (because shared libraries don't live in code   space), and special magic is needed to construct their address. */voidhppa_encode_label (sym)     rtx sym;{  char *str = XSTR (sym, 0);  int len = strlen (str);  char *newstr = obstack_alloc (saveable_obstack, len + 2) ;  if (str[0] == '*')    *newstr++ = *str++;  strcpy (newstr + 1, str);  *newstr = '@';  XSTR (sym,0) = newstr;}  intfunction_label_operand  (op, mode)     rtx op;     enum machine_mode mode;{  return GET_CODE (op) == SYMBOL_REF && FUNCTION_NAME_P (XSTR (op, 0));}/* Return 1 if OP is suitable for the second add operand (the unshifed    operand) in an shadd instruction.   Allow CONST_INT to work around   a reload bug.  */intshadd_operand (op, mode)     rtx op;     enum machine_mode mode;{  if (GET_CODE (op) == REG)    return 1;  if (GET_CODE (op) == CONST_INT)    return 1;  return 0;}

⌨️ 快捷键说明

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