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

📄 sh.c

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
#define TARGET_EXPAND_BUILTIN_SAVEREGS sh_builtin_saveregs#undef TARGET_SETUP_INCOMING_VARARGS#define TARGET_SETUP_INCOMING_VARARGS sh_setup_incoming_varargs#undef TARGET_STRICT_ARGUMENT_NAMING#define TARGET_STRICT_ARGUMENT_NAMING sh_strict_argument_naming#undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED#define TARGET_PRETEND_OUTGOING_VARARGS_NAMED sh_pretend_outgoing_varargs_named#undef TARGET_MUST_PASS_IN_STACK#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size#undef TARGET_PASS_BY_REFERENCE#define TARGET_PASS_BY_REFERENCE sh_pass_by_reference#undef TARGET_CALLEE_COPIES#define TARGET_CALLEE_COPIES sh_callee_copies#undef TARGET_ARG_PARTIAL_BYTES#define TARGET_ARG_PARTIAL_BYTES sh_arg_partial_bytes#undef TARGET_BUILD_BUILTIN_VA_LIST#define TARGET_BUILD_BUILTIN_VA_LIST sh_build_builtin_va_list#undef TARGET_GIMPLIFY_VA_ARG_EXPR#define TARGET_GIMPLIFY_VA_ARG_EXPR sh_gimplify_va_arg_expr#undef TARGET_VECTOR_MODE_SUPPORTED_P#define TARGET_VECTOR_MODE_SUPPORTED_P sh_vector_mode_supported_p#undef TARGET_PCH_VALID_P#define TARGET_PCH_VALID_P sh_pch_valid_p#undef TARGET_DWARF_CALLING_CONVENTION#define TARGET_DWARF_CALLING_CONVENTION sh_dwarf_calling_convention/* Return regmode weight for insn.  */#define INSN_REGMODE_WEIGHT(INSN, MODE)  regmode_weight[((MODE) == SImode) ? 0 : 1][INSN_UID (INSN)]/* Return current register pressure for regmode.  */#define CURR_REGMODE_PRESSURE(MODE) 	curr_regmode_pressure[((MODE) == SImode) ? 0 : 1]#ifdef SYMBIAN#undef  TARGET_ENCODE_SECTION_INFO#define TARGET_ENCODE_SECTION_INFO	sh_symbian_encode_section_info#undef  TARGET_STRIP_NAME_ENCODING#define TARGET_STRIP_NAME_ENCODING	sh_symbian_strip_name_encoding#undef  TARGET_CXX_IMPORT_EXPORT_CLASS#define TARGET_CXX_IMPORT_EXPORT_CLASS  symbian_import_export_class#endif /* SYMBIAN */struct gcc_target targetm = TARGET_INITIALIZER;/* Print the operand address in x to the stream.  */voidprint_operand_address (FILE *stream, rtx x){  switch (GET_CODE (x))    {    case REG:    case SUBREG:      fprintf (stream, "@%s", reg_names[true_regnum (x)]);      break;    case PLUS:      {	rtx base = XEXP (x, 0);	rtx index = XEXP (x, 1);	switch (GET_CODE (index))	  {	  case CONST_INT:	    fprintf (stream, "@(%d,%s)", (int) INTVAL (index),		     reg_names[true_regnum (base)]);	    break;	  case REG:	  case SUBREG:	    {	      int base_num = true_regnum (base);	      int index_num = true_regnum (index);	      fprintf (stream, "@(r0,%s)",		       reg_names[MAX (base_num, index_num)]);	      break;	    }	  default:	    debug_rtx (x);	    abort ();	  }      }      break;    case PRE_DEC:      fprintf (stream, "@-%s", reg_names[true_regnum (XEXP (x, 0))]);      break;    case POST_INC:      fprintf (stream, "@%s+", reg_names[true_regnum (XEXP (x, 0))]);      break;    default:      x = mark_constant_pool_use (x);      output_addr_const (stream, x);      break;    }}/* Print operand x (an rtx) in assembler syntax to file stream   according to modifier code.   '.'  print a .s if insn needs delay slot   ','  print LOCAL_LABEL_PREFIX   '@'  print trap, rte or rts depending upon pragma interruptness   '#'  output a nop if there is nothing to put in the delay slot   '''  print likelihood suffix (/u for unlikely).   'O'  print a constant without the #   'R'  print the LSW of a dp value - changes if in little endian   'S'  print the MSW of a dp value - changes if in little endian   'T'  print the next word of a dp value - same as 'R' in big endian mode.   'M'  print an `x' if `m' will print `base,index'.   'N'  print 'r63' if the operand is (const_int 0).   'd'  print a V2SF reg as dN instead of fpN.   'm'  print a pair `base,offset' or `base,index', for LD and ST.   'u'  prints the lowest 16 bits of CONST_INT, as an unsigned value.   'o'  output an operator.  */voidprint_operand (FILE *stream, rtx x, int code){  switch (code)    {    case '.':      if (final_sequence	  && ! INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0))	  && get_attr_length (XVECEXP (final_sequence, 0, 1)))	fprintf (stream, ASSEMBLER_DIALECT ? "/s" : ".s");      break;    case ',':      fprintf (stream, "%s", LOCAL_LABEL_PREFIX);      break;    case '@':      if (trap_exit)	fprintf (stream, "trapa #%d", trap_exit);      else if (sh_cfun_interrupt_handler_p ())	fprintf (stream, "rte");      else	fprintf (stream, "rts");      break;    case '#':      /* Output a nop if there's nothing in the delay slot.  */      if (dbr_sequence_length () == 0)	fprintf (stream, "\n\tnop");      break;    case '\'':      {	rtx note = find_reg_note (current_output_insn, REG_BR_PROB, 0);	if (note && INTVAL (XEXP (note, 0)) * 2 < REG_BR_PROB_BASE)	  fputs ("/u", stream);	break;      }    case 'O':      x = mark_constant_pool_use (x);      output_addr_const (stream, x);      break;    case 'R':      fputs (reg_names[REGNO (x) + LSW], (stream));      break;    case 'S':      fputs (reg_names[REGNO (x) + MSW], (stream));      break;    case 'T':      /* Next word of a double.  */      switch (GET_CODE (x))	{	case REG:	  fputs (reg_names[REGNO (x) + 1], (stream));	  break;	case MEM:	  if (GET_CODE (XEXP (x, 0)) != PRE_DEC	      && GET_CODE (XEXP (x, 0)) != POST_INC)	    x = adjust_address (x, SImode, 4);	  print_operand_address (stream, XEXP (x, 0));	  break;	default:	  break;	}      break;    case 'o':      switch (GET_CODE (x))	{	case PLUS:  fputs ("add", stream); break;	case MINUS: fputs ("sub", stream); break;	case MULT:  fputs ("mul", stream); break;	case DIV:   fputs ("div", stream); break;	case EQ:    fputs ("eq",  stream); break;	case NE:    fputs ("ne",  stream); break;	case GT:  case LT:  fputs ("gt",  stream); break;	case GE:  case LE:  fputs ("ge",  stream); break;	case GTU: case LTU: fputs ("gtu", stream); break;	case GEU: case LEU: fputs ("geu", stream); break;	default:	  break;	}      break;    case 'M':      if (GET_CODE (x) == MEM	  && GET_CODE (XEXP (x, 0)) == PLUS	  && (GET_CODE (XEXP (XEXP (x, 0), 1)) == REG	      || GET_CODE (XEXP (XEXP (x, 0), 1)) == SUBREG))	fputc ('x', stream);      break;    case 'm':      if (GET_CODE (x) != MEM)	abort ();      x = XEXP (x, 0);      switch (GET_CODE (x))	{	case REG:	case SUBREG:	  print_operand (stream, x, 0);	  fputs (", 0", stream);	  break;	case PLUS:	  print_operand (stream, XEXP (x, 0), 0);	  fputs (", ", stream);	  print_operand (stream, XEXP (x, 1), 0);	  break;	default:	  abort ();	}      break;    case 'd':      if (GET_CODE (x) != REG || GET_MODE (x) != V2SFmode)	abort ();      fprintf ((stream), "d%s", reg_names[REGNO (x)] + 1);      break;    case 'N':      if (x == CONST0_RTX (GET_MODE (x)))	{	  fprintf ((stream), "r63");	  break;	}      goto default_output;    case 'u':      if (GET_CODE (x) == CONST_INT)	{	  fprintf ((stream), "%u", (unsigned) INTVAL (x) & (0x10000 - 1));	  break;	}      /* Fall through.  */    default_output:    default:      switch (GET_CODE (x))	{	  /* FIXME: We need this on SHmedia32 because reload generates	     some sign-extended HI or QI loads into DImode registers	     but, because Pmode is SImode, the address ends up with a	     subreg:SI of the DImode register.  Maybe reload should be	     fixed so as to apply alter_subreg to such loads?  */	case SUBREG:	  if (SUBREG_BYTE (x) != 0	      || GET_CODE (SUBREG_REG (x)) != REG)	    abort ();	  x = SUBREG_REG (x);	  /* Fall through.  */	case REG:	  if (FP_REGISTER_P (REGNO (x))	      && GET_MODE (x) == V16SFmode)	    fprintf ((stream), "mtrx%s", reg_names[REGNO (x)] + 2);	  else if (FP_REGISTER_P (REGNO (x))		   && GET_MODE (x) == V4SFmode)	    fprintf ((stream), "fv%s", reg_names[REGNO (x)] + 2);	  else if (GET_CODE (x) == REG		   && GET_MODE (x) == V2SFmode)	    fprintf ((stream), "fp%s", reg_names[REGNO (x)] + 2);	  else if (FP_REGISTER_P (REGNO (x))		   && GET_MODE_SIZE (GET_MODE (x)) > 4)	    fprintf ((stream), "d%s", reg_names[REGNO (x)] + 1);	  else	    fputs (reg_names[REGNO (x)], (stream));	  break;	case MEM:	  output_address (XEXP (x, 0));	  break;	case CONST:	  if (TARGET_SHMEDIA	      && GET_CODE (XEXP (x, 0)) == SIGN_EXTEND	      && GET_MODE (XEXP (x, 0)) == DImode	      && GET_CODE (XEXP (XEXP (x, 0), 0)) == TRUNCATE	      && GET_MODE (XEXP (XEXP (x, 0), 0)) == HImode)	    {	      rtx val = XEXP (XEXP (XEXP (x, 0), 0), 0);	      fputc ('(', stream);	      if (GET_CODE (val) == ASHIFTRT)		{		  fputc ('(', stream);		  if (GET_CODE (XEXP (val, 0)) == CONST)		    fputc ('(', stream);		  output_addr_const (stream, XEXP (val, 0));		  if (GET_CODE (XEXP (val, 0)) == CONST)		    fputc (')', stream);		  fputs (" >> ", stream);		  output_addr_const (stream, XEXP (val, 1));		  fputc (')', stream);		}	      else		{		  if (GET_CODE (val) == CONST)		    fputc ('(', stream);		  output_addr_const (stream, val);		  if (GET_CODE (val) == CONST)		    fputc (')', stream);		}	      fputs (" & 65535)", stream);	      break;	    }	  /* Fall through.  */	default:	  if (TARGET_SH1)	    fputc ('#', stream);	  output_addr_const (stream, x);	  break;	}      break;    }}/* Like force_operand, but guarantees that VALUE ends up in TARGET.  */static voidforce_into (rtx value, rtx target){  value = force_operand (value, target);  if (! rtx_equal_p (value, target))    emit_insn (gen_move_insn (target, value));}/* Emit code to perform a block move.  Choose the best method.   OPERANDS[0] is the destination.   OPERANDS[1] is the source.   OPERANDS[2] is the size.   OPERANDS[3] is the alignment safe to use.  */intexpand_block_move (rtx *operands){  int align = INTVAL (operands[3]);  int constp = (GET_CODE (operands[2]) == CONST_INT);  int bytes = (constp ? INTVAL (operands[2]) : 0);  if (! constp)    return 0;  /* If we could use mov.l to move words and dest is word-aligned, we     can use movua.l for loads and still generate a relatively short     and efficient sequence.  */  if (TARGET_SH4A_ARCH && align < 4      && MEM_ALIGN (operands[0]) >= 32      && can_move_by_pieces (bytes, 32))    {      rtx dest = copy_rtx (operands[0]);      rtx src = copy_rtx (operands[1]);      /* We could use different pseudos for each copied word, but	 since movua can only load into r0, it's kind of	 pointless.  */      rtx temp = gen_reg_rtx (SImode);      rtx src_addr = copy_addr_to_reg (XEXP (src, 0));      int copied = 0;      while (copied + 4 <= bytes)	{	  rtx to = adjust_address (dest, SImode, copied);	  rtx from = adjust_automodify_address (src, SImode, src_addr, copied);	  emit_insn (gen_movua (temp, from));	  emit_move_insn (src_addr, plus_constant (src_addr, 4));	  emit_move_insn (to, temp);	  copied += 4;	}      if (copied < bytes)	move_by_pieces (adjust_address (dest, BLKmode, copied),			adjust_automodify_address (src, BLKmode,						   src_addr, copied),			bytes - copied, align, 0);      return 1;    }  /* If it isn't a constant number of bytes, or if it doesn't have 4 byte     alignment, or if it isn't a multiple of 4 bytes, then fail.  */  if (align < 4 || (bytes % 4 != 0))    return 0;  if (TARGET_HARD_SH4)    {      if (bytes < 12)	return 0;      else if (bytes == 12)	{	  tree entry_name;	  rtx sym;	  rtx func_addr_rtx;	  rtx r4 = gen_rtx_REG (SImode, 4);	  rtx r5 = gen_rtx_REG (SImode, 5);	  entry_name = get_identifier ("__movmemSI12_i4");	  sym = function_symbol (IDENTIFIER_POINTER (entry_name));	  func_addr_rtx = copy_to_mode_reg (Pmode, sym);	  force_into (XEXP (operands[0], 0), r4);	  force_into (XEXP (operands[1], 0), r5);	  emit_insn (gen_block_move_real_i4 (func_addr_rtx));	  return 1;	}      else if (! TARGET_SMALLCODE)	{	  tree entry_name;	  rtx sym;	  rtx func_addr_rtx;	  int dwords;	  rtx r4 = gen_rtx_REG (SImode, 4);

⌨️ 快捷键说明

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