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

📄 pdp11.c

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
          else /* worst case */            *total = COSTS_N_INSNS (18);        }      return false;    default:      return false;    }}const char *output_jump(const char *pos, const char *neg, int length){    static int x = 0;        static char buf[1000];#if 0/* currently we don't need this, because the tstdf and cmpdf    copy the condition code immediately, and other float operations are not    yet recognized as changing the FCC - if so, then the length-cost of all   jump insns increases by one, because we have to potentially copy the    FCC! */    if (cc_status.flags & CC_IN_FPU)	output_asm_insn("cfcc", NULL);#endif	    switch (length)    {      case 1:		strcpy(buf, pos);	strcat(buf, " %l0");		return buf;	      case 3:		sprintf(buf, "%s JMP_%d\n\tjmp %%l0\nJMP_%d:", neg, x, x);		x++;		return buf;	      default:		abort();    }    }voidnotice_update_cc_on_set(rtx exp, rtx insn ATTRIBUTE_UNUSED){    if (GET_CODE (SET_DEST (exp)) == CC0)    { 	cc_status.flags = 0;						cc_status.value1 = SET_DEST (exp);				cc_status.value2 = SET_SRC (exp);			/*	if (GET_MODE(SET_SRC(exp)) == DFmode)	    cc_status.flags |= CC_IN_FPU;*/	    }							    else if ((GET_CODE (SET_DEST (exp)) == REG			      || GET_CODE (SET_DEST (exp)) == MEM)			     && GET_CODE (SET_SRC (exp)) != PC			     && (GET_MODE (SET_DEST(exp)) == HImode				 || GET_MODE (SET_DEST(exp)) == QImode)			&& (GET_CODE (SET_SRC(exp)) == PLUS				    || GET_CODE (SET_SRC(exp)) == MINUS			    || GET_CODE (SET_SRC(exp)) == AND			    || GET_CODE (SET_SRC(exp)) == IOR			    || GET_CODE (SET_SRC(exp)) == XOR			    || GET_CODE (SET_SRC(exp)) == NOT			    || GET_CODE (SET_SRC(exp)) == NEG				|| GET_CODE (SET_SRC(exp)) == REG			    || GET_CODE (SET_SRC(exp)) == MEM))	    { 	cc_status.flags = 0;						cc_status.value1 = SET_SRC (exp);   				cc_status.value2 = SET_DEST (exp);					if (cc_status.value1 && GET_CODE (cc_status.value1) == REG		    && cc_status.value2						    && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))    	    cc_status.value2 = 0;						if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM		    && cc_status.value2						    && GET_CODE (cc_status.value2) == MEM)				    cc_status.value2 = 0; 					    }							    else if (GET_CODE (SET_SRC (exp)) == CALL)		    { 	CC_STATUS_INIT;     }    else if (GET_CODE (SET_DEST (exp)) == REG)       			/* what's this ? */					    { 	if ((cc_status.value1						     && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1)))	    cc_status.value1 = 0;					if ((cc_status.value2						     && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2)))	    cc_status.value2 = 0;				    }							    else if (SET_DEST(exp) == pc_rtx)    { 	/* jump */    }    else /* if (GET_CODE (SET_DEST (exp)) == MEM)	*/	    {  	/* the last else is a bit paranoiac, but since nearly all instructions 	   play with condition codes, it's reasonable! */	CC_STATUS_INIT; /* paranoia*/     }		        }intsimple_memory_operand(rtx op, enum machine_mode mode ATTRIBUTE_UNUSED){    rtx addr;    /* Eliminate non-memory operations */    if (GET_CODE (op) != MEM)	return FALSE;#if 0    /* dword operations really put out 2 instructions, so eliminate them.  */    if (GET_MODE_SIZE (GET_MODE (op)) > (HAVE_64BIT_P () ? 8 : 4))	return FALSE;#endif    /* Decode the address now.  */  indirection:        addr = XEXP (op, 0);    switch (GET_CODE (addr))    {      case REG:	/* (R0) - no extra cost */	return 1;	      case PRE_DEC:      case POST_INC:	/* -(R0), (R0)+ - cheap! */	return 0;	      case MEM:	/* cheap - is encoded in addressing mode info! 	   -- except for @(R0), which has to be @0(R0) !!! */	if (GET_CODE (XEXP (addr, 0)) == REG)	    return 0;		op=addr;	goto indirection;	      case CONST_INT:      case LABEL_REF:	             case CONST:      case SYMBOL_REF:	/* @#address - extra cost */	return 0;      case PLUS:	/* X(R0) - extra cost */	return 0;      default:	break;    }        return FALSE;}/* * output a block move: * * operands[0]	... to * operands[1]  ... from * operands[2]  ... length * operands[3]  ... alignment * operands[4]  ... scratch register */ const char *output_block_move(rtx *operands){    static int count = 0;    char buf[200];        if (GET_CODE(operands[2]) == CONST_INT	&& ! optimize_size)    {	if (INTVAL(operands[2]) < 16	    && INTVAL(operands[3]) == 1)	{	    register int i;	    	    for (i = 1; i <= INTVAL(operands[2]); i++)		output_asm_insn("movb (%1)+, (%0)+", operands);	    return "";	}	else if (INTVAL(operands[2]) < 32)	{	    register int i;	    	    for (i = 1; i <= INTVAL(operands[2])/2; i++)		output_asm_insn("mov (%1)+, (%0)+", operands);	    	    /* may I assume that moved quantity is 	       multiple of alignment ???	       I HOPE SO !	    */	    return "";	}		/* can do other clever things, maybe... */    }    if (CONSTANT_P(operands[2]) )    {	/* just move count to scratch */	output_asm_insn("mov %2, %4", operands);    }    else    {	/* just clobber the register */	operands[4] = operands[2];    }        /* switch over alignment */    switch (INTVAL(operands[3]))    {      case 1:		/* 	  x:	  movb (%1)+, (%0)+	  	  if (TARGET_45)	     sob %4,x	  else	     dec %4	     bgt x	*/	sprintf(buf, "\nmovestrhi%d:", count);	output_asm_insn(buf, NULL);		output_asm_insn("movb (%1)+, (%0)+", operands);		if (TARGET_45)	{	    sprintf(buf, "sob %%4, movestrhi%d", count);	    output_asm_insn(buf, operands);	}	else	{	    output_asm_insn("dec %4", operands);	    	    sprintf(buf, "bgt movestrhi%d", count);	    output_asm_insn(buf, NULL);	}		count ++;	break;	      case 2:		/* 	   asr %4	   x:	   mov (%1)+, (%0)+	   if (TARGET_45)	     sob %4, x	   else	     dec %4	     bgt x	*/      generate_compact_code:	output_asm_insn("asr %4", operands);	sprintf(buf, "\nmovestrhi%d:", count);	output_asm_insn(buf, NULL);		output_asm_insn("mov (%1)+, (%0)+", operands);		if (TARGET_45)	{	    sprintf(buf, "sob %%4, movestrhi%d", count);	    output_asm_insn(buf, operands);	}	else	{	    output_asm_insn("dec %4", operands);	    	    sprintf(buf, "bgt movestrhi%d", count);	    output_asm_insn(buf, NULL);	}		count ++;	break;      case 4:		/*	   asr %4	   asr %4	   x:	   mov (%1)+, (%0)+	   mov (%1)+, (%0)+	   if (TARGET_45)	     sob %4, x	   else	     dec %4	     bgt x	*/	if (optimize_size)	    goto generate_compact_code;		output_asm_insn("asr %4", operands);	output_asm_insn("asr %4", operands);	sprintf(buf, "\nmovestrhi%d:", count);	output_asm_insn(buf, NULL);		output_asm_insn("mov (%1)+, (%0)+", operands);	output_asm_insn("mov (%1)+, (%0)+", operands);		if (TARGET_45)	{	    sprintf(buf, "sob %%4, movestrhi%d", count);	    output_asm_insn(buf, operands);	}	else	{	    output_asm_insn("dec %4", operands);	    	    sprintf(buf, "bgt movestrhi%d", count);	    output_asm_insn(buf, NULL);	}		count ++;	break;             default:		/*	   	   asr %4	   asr %4	   asr %4	   x:	   mov (%1)+, (%0)+	   mov (%1)+, (%0)+	   mov (%1)+, (%0)+	   mov (%1)+, (%0)+	   	   if (TARGET_45)	     sob %4, x	   else	     dec %4	     bgt x	*/	if (optimize_size)	    goto generate_compact_code;		output_asm_insn("asr %4", operands);	output_asm_insn("asr %4", operands);	output_asm_insn("asr %4", operands);	sprintf(buf, "\nmovestrhi%d:", count);	output_asm_insn(buf, NULL);		output_asm_insn("mov (%1)+, (%0)+", operands);	output_asm_insn("mov (%1)+, (%0)+", operands);	output_asm_insn("mov (%1)+, (%0)+", operands);	output_asm_insn("mov (%1)+, (%0)+", operands);		if (TARGET_45)	{	    sprintf(buf, "sob %%4, movestrhi%d", count);	    output_asm_insn(buf, operands);	}	else	{	    output_asm_insn("dec %4", operands);	    	    sprintf(buf, "bgt movestrhi%d", count);	    output_asm_insn(buf, NULL);	}		count ++;	break;		;	    }        return "";}intlegitimate_address_p (enum machine_mode mode, rtx address){/* #define REG_OK_STRICT */    GO_IF_LEGITIMATE_ADDRESS(mode, address, win);        return 0;      win:    return 1;/* #undef REG_OK_STRICT */}/* This function checks whether a real value can be encoded as   a literal, i.e., addressing mode 27.  In that mode, real values   are one word values, so the remaining 48 bits have to be zero.  */intlegitimate_const_double_p (rtx address){  REAL_VALUE_TYPE r;  long sval[2];  REAL_VALUE_FROM_CONST_DOUBLE (r, address);  REAL_VALUE_TO_TARGET_DOUBLE (r, sval);  if ((sval[0] & 0xffff) == 0 && sval[1] == 0)    return 1;  return 0;}/* A copy of output_addr_const modified for pdp11 expression syntax.   output_addr_const also gets called for %cDIGIT and %nDIGIT, which we don't   use, and for debugging output, which we don't support with this port either.   So this copy should get called whenever needed.*/voidoutput_addr_const_pdp11 (FILE *file, rtx x){  char buf[256]; restart:  switch (GET_CODE (x))    {    case PC:      if (flag_pic)	putc ('.', file);      else	abort ();      break;    case SYMBOL_REF:      assemble_name (file, XSTR (x, 0));      break;    case LABEL_REF:      ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));      assemble_name (file, buf);      break;    case CODE_LABEL:      ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));      assemble_name (file, buf);      break;    case CONST_INT:      /* Should we check for constants which are too big?  Maybe cutting	 them off to 16 bits is OK?  */      fprintf (file, "%#ho", (unsigned short) INTVAL (x));      break;    case CONST:      /* This used to output parentheses around the expression,	 but that does not work on the 386 (either ATT or BSD assembler).  */      output_addr_const_pdp11 (file, XEXP (x, 0));      break;    case CONST_DOUBLE:      if (GET_MODE (x) == VOIDmode)	{	  /* We can use %o if the number is one word and positive.  */	  if (CONST_DOUBLE_HIGH (x))	    abort (); /* Should we just silently drop the high part?  */	  else	    fprintf (file, "%#ho", (unsigned short) CONST_DOUBLE_LOW (x));	}      else	/* We can't handle floating point constants;	   PRINT_OPERAND must handle them.  */	output_operand_lossage ("floating constant misused");      break;    case PLUS:      /* Some assemblers need integer constants to appear last (e.g. masm).  */      if (GET_CODE (XEXP (x, 0)) == CONST_INT)	{	  output_addr_const_pdp11 (file, XEXP (x, 1));	  if (INTVAL (XEXP (x, 0)) >= 0)	    fprintf (file, "+");	  output_addr_const_pdp11 (file, XEXP (x, 0));	}      else	{	  output_addr_const_pdp11 (file, XEXP (x, 0));	  if (INTVAL (XEXP (x, 1)) >= 0)	    fprintf (file, "+");	  output_addr_const_pdp11 (file, XEXP (x, 1));	}      break;    case MINUS:      /* Avoid outputting things like x-x or x+5-x,	 since some assemblers can't handle that.  */      x = simplify_subtraction (x);      if (GET_CODE (x) != MINUS)	goto restart;      output_addr_const_pdp11 (file, XEXP (x, 0));      fprintf (file, "-");      if (GET_CODE (XEXP (x, 1)) == CONST_INT	  && INTVAL (XEXP (x, 1)) < 0)	{	  fprintf (file, targetm.asm_out.open_paren);	  output_addr_const_pdp11 (file, XEXP (x, 1));	  fprintf (file, targetm.asm_out.close_paren);	}      else	output_addr_const_pdp11 (file, XEXP (x, 1));      break;    case ZERO_EXTEND:    case SIGN_EXTEND:      output_addr_const_pdp11 (file, XEXP (x, 0));      break;    default:      output_operand_lossage ("invalid expression as operand");    }}/* Worker function for TARGET_RETURN_IN_MEMORY.  */static boolpdp11_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED){  /* Should probably return DImode and DFmode in memory, lest     we fill up all regs!     have to, else we crash - exception: maybe return result in      ac0 if DFmode and FPU present - compatibility problem with     libraries for non-floating point....  */  return (TYPE_MODE (type) == DImode	  || (TYPE_MODE (type) == DFmode && ! TARGET_AC0));}

⌨️ 快捷键说明

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