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

📄 m68k.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
			   fpoffset + fsize,			   reg_names[FRAME_POINTER_REGNUM],			   reg_names[regno]);#else	      asm_fprintf (stream, "\tfpmoved %s@(-%d), %s\n",			   reg_names[FRAME_POINTER_REGNUM],			   fpoffset + fsize, reg_names[regno]);#endif	    }	  fpoffset -= 8;	}  if (frame_pointer_needed)    fprintf (stream, "\tunlk %s\n",	     reg_names[FRAME_POINTER_REGNUM]);  else if (fsize)    {      if (fsize + 4 < 0x8000)	{	/* asm_fprintf() cannot handle %. */#ifdef MOTOROLA	  asm_fprintf (stream, "\tadd.w %0I%d,%Rsp\n", fsize + 4);#else	  asm_fprintf (stream, "\taddw %0I%d,%Rsp\n", fsize + 4);#endif	}      else	{	/* asm_fprintf() cannot handle %. */#ifdef MOTOROLA	  asm_fprintf (stream, "\tadd.l %0I%d,%Rsp\n", fsize + 4);#else	  asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", fsize + 4);#endif	}    }  if (current_function_pops_args)    asm_fprintf (stream, "\trtd %0I%d\n", current_function_pops_args);  else    fprintf (stream, "\trts\n");}/* Similar to general_operand, but exclude stack_pointer_rtx.  */intnot_sp_operand (op, mode)     register rtx op;     enum machine_mode mode;{  return op != stack_pointer_rtx && general_operand (op, mode);}/* Return TRUE if X is a valid comparison operator for the dbcc    instruction.     Note it rejects floating point comparison operators.   (In the future we could use Fdbcc).   It also rejects some comparisons when CC_NO_OVERFLOW is set.  */   intvalid_dbcc_comparison_p (x, mode)     rtx x;     enum machine_mode mode;{  /* We could add support for these in the future */  if (cc_prev_status.flags & CC_IN_68881)    return 0;  switch (GET_CODE (x))    {      case EQ: case NE: case GTU: case LTU:      case GEU: case LEU:        return 1;      /* Reject some when CC_NO_OVERFLOW is set.  This may be over         conservative */      case GT: case LT: case GE: case LE:        return ! (cc_prev_status.flags & CC_NO_OVERFLOW);      default:        return 0;    }}/* Output a dbCC; jCC sequence.  Note we do not handle the    floating point version of this sequence (Fdbcc).  We also   do not handle alternative conditions when CC_NO_OVERFLOW is   set.  It is assumed that valid_dbcc_comparison_p will kick   those out before we get here.  */output_dbcc_and_branch (operands)     rtx *operands;{   switch (GET_CODE (operands[3]))    {      case EQ:#ifdef MOTOROLA        output_asm_insn ("dbeq %0,%l1\n\tjbeq %l2", operands);#else        output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands);#endif        break;      case NE:#ifdef MOTOROLA        output_asm_insn ("dbne %0,%l1\n\tjbne %l2", operands);#else        output_asm_insn ("dbne %0,%l1\n\tjne %l2", operands);#endif        break;      case GT:#ifdef MOTOROLA        output_asm_insn ("dbgt %0,%l1\n\tjbgt %l2", operands);#else        output_asm_insn ("dbgt %0,%l1\n\tjgt %l2", operands);#endif        break;      case GTU:#ifdef MOTOROLA        output_asm_insn ("dbhi %0,%l1\n\tjbhi %l2", operands);#else        output_asm_insn ("dbhi %0,%l1\n\tjhi %l2", operands);#endif        break;      case LT:#ifdef MOTOROLA        output_asm_insn ("dblt %0,%l1\n\tjblt %l2", operands);#else        output_asm_insn ("dblt %0,%l1\n\tjlt %l2", operands);#endif        break;      case LTU:#ifdef MOTOROLA        output_asm_insn ("dbcs %0,%l1\n\tjbcs %l2", operands);#else        output_asm_insn ("dbcs %0,%l1\n\tjcs %l2", operands);#endif        break;      case GE:#ifdef MOTOROLA        output_asm_insn ("dbge %0,%l1\n\tjbge %l2", operands);#else        output_asm_insn ("dbge %0,%l1\n\tjge %l2", operands);#endif        break;      case GEU:#ifdef MOTOROLA        output_asm_insn ("dbcc %0,%l1\n\tjbcc %l2", operands);#else        output_asm_insn ("dbcc %0,%l1\n\tjcc %l2", operands);#endif        break;      case LE:#ifdef MOTOROLA        output_asm_insn ("dble %0,%l1\n\tjble %l2", operands);#else        output_asm_insn ("dble %0,%l1\n\tjle %l2", operands);#endif        break;      case LEU:#ifdef MOTOROLA        output_asm_insn ("dbls %0,%l1\n\tjbls %l2", operands);#else        output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands);#endif        break;      default:	abort ();    }  /* If the decrement is to be done in SImode, then we have     to compensate for the fact that dbcc decrements in HImode. */  switch (GET_MODE (operands[0]))    {      case SImode:#ifdef MOTOROLA        output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjbpl %l1", operands);#else        output_asm_insn ("clr%.w %0\n\tsubq%.l %#1,%0\n\tjpl %l1", operands);#endif        break;      case HImode:        break;      default:        abort ();    }}char *output_scc_di(op, operand1, operand2, dest)     rtx op;     rtx operand1;     rtx operand2;     rtx dest;{  rtx loperands[7];  enum rtx_code op_code = GET_CODE (op);  /* The m68k cmp.l instruction requires operand1 to be a reg as used     below.  Swap the operands and change the op if these requirements     are not fulfilled.  */  if (GET_CODE (operand2) == REG && GET_CODE (operand1) != REG)    {      rtx tmp = operand1;      operand1 = operand2;      operand2 = tmp;      op_code = swap_condition (op_code);    }  loperands[0] = operand1;  if (GET_CODE (operand1) == REG)    loperands[1] = gen_rtx (REG, SImode, REGNO (operand1) + 1);  else    loperands[1] = adj_offsettable_operand (operand1, 4);  if (operand2 != const0_rtx)    {      loperands[2] = operand2;      if (GET_CODE (operand2) == REG)	loperands[3] = gen_rtx (REG, SImode, REGNO (operand2) + 1);      else	loperands[3] = adj_offsettable_operand (operand2, 4);    }  loperands[4] = gen_label_rtx();  if (operand2 != const0_rtx)#ifdef MOTOROLA#ifdef SGS_CMP_ORDER    output_asm_insn ("cmp%.l %0,%2\n\tjbne %l4\n\tcmp%.l %1,%3", loperands);#else    output_asm_insn ("cmp%.l %2,%0\n\tjbne %l4\n\tcmp%.l %3,%1", loperands);#endif#else#ifdef SGS_CMP_ORDER    output_asm_insn ("cmp%.l %0,%2\n\tjne %l4\n\tcmp%.l %1,%3", loperands);#else    output_asm_insn ("cmp%.l %2,%0\n\tjne %l4\n\tcmp%.l %3,%1", loperands);#endif#endif  else#ifdef MOTOROLA    output_asm_insn ("tst%.l %0\n\tjbne %l4\n\ttst%.l %1", loperands);#else    output_asm_insn ("tst%.l %0\n\tjne %l4\n\ttst%.l %1", loperands);#endif  loperands[5] = dest;    switch (op_code)    {      case EQ:        ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[4]));        output_asm_insn ("seq %5", loperands);        break;      case NE:        ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[4]));        output_asm_insn ("sne %5", loperands);        break;      case GT:        loperands[6] = gen_label_rtx();#ifdef MOTOROLA        output_asm_insn ("shi %5\n\tjbra %l6", loperands);#else        output_asm_insn ("shi %5\n\tjra %l6", loperands);#endif        ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[4]));        output_asm_insn ("sgt %5", loperands);        ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[6]));        break;      case GTU:        ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[4]));        output_asm_insn ("shi %5", loperands);        break;      case LT:        loperands[6] = gen_label_rtx();#ifdef MOTOROLA        output_asm_insn ("scs %5\n\tjbra %l6", loperands);#else        output_asm_insn ("scs %5\n\tjra %l6", loperands);#endif        ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[4]));        output_asm_insn ("slt %5", loperands);        ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[6]));        break;      case LTU:        ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[4]));        output_asm_insn ("scs %5", loperands);        break;      case GE:        loperands[6] = gen_label_rtx();#ifdef MOTOROLA        output_asm_insn ("scc %5\n\tjbra %l6", loperands);#else        output_asm_insn ("scc %5\n\tjra %l6", loperands);#endif        ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[4]));        output_asm_insn ("sge %5", loperands);        ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[6]));        break;      case GEU:        ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[4]));        output_asm_insn ("scc %5", loperands);        break;      case LE:        loperands[6] = gen_label_rtx();#ifdef MOTOROLA        output_asm_insn ("sls %5\n\tjbra %l6", loperands);#else        output_asm_insn ("sls %5\n\tjra %l6", loperands);#endif        ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[4]));        output_asm_insn ("sle %5", loperands);        ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[6]));        break;      case LEU:        ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[4]));        output_asm_insn ("sls %5", loperands);        break;      default:	abort ();    }  return "";}char *output_btst (operands, countop, dataop, insn, signpos)     rtx *operands;     rtx countop, dataop;     rtx insn;     int signpos;{  operands[0] = countop;  operands[1] = dataop;  if (GET_CODE (countop) == CONST_INT)    {      register int count = INTVAL (countop);      /* If COUNT is bigger than size of storage unit in use,	 advance to the containing unit of same size.  */      if (count > signpos)	{	  int offset = (count & ~signpos) / 8;	  count = count & signpos;	  operands[1] = dataop = adj_offsettable_operand (dataop, offset);	}      if (count == signpos)	cc_status.flags = CC_NOT_POSITIVE | CC_Z_IN_NOT_N;      else	cc_status.flags = CC_NOT_NEGATIVE | CC_Z_IN_NOT_N;      /* These three statements used to use next_insns_test_no...	 but it appears that this should do the same job.  */      if (count == 31	  && next_insn_tests_no_inequality (insn))	return "tst%.l %1";      if (count == 15	  && next_insn_tests_no_inequality (insn))	return "tst%.w %1";      if (count == 7	  && next_insn_tests_no_inequality (insn))	return "tst%.b %1";      cc_status.flags = CC_NOT_NEGATIVE;    }  return "btst %0,%1";}/* Returns 1 if OP is either a symbol reference or a sum of a symbol   reference and a constant.  */intsymbolic_operand (op, mode)     register rtx op;     enum machine_mode mode;{  switch (GET_CODE (op))    {    case SYMBOL_REF:    case LABEL_REF:      return 1;    case CONST:      op = XEXP (op, 0);      return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF	       || GET_CODE (XEXP (op, 0)) == LABEL_REF)	      && GET_CODE (XEXP (op, 1)) == CONST_INT);#if 0 /* Deleted, with corresponding change in m68k.h,	 so as to fit the specs.  No CONST_DOUBLE is ever symbolic.  */    case CONST_DOUBLE:      return GET_MODE (op) == mode;#endif    default:      return 0;    }}/* Check for sign_extend or zero_extend.  Used for bit-count operands. */intextend_operator(x, mode)     rtx x;     enum machine_mode mode;{    if (mode != VOIDmode && GET_MODE(x) != mode)	return 0;    switch (GET_CODE(x))	{	case SIGN_EXTEND :	case ZERO_EXTEND :	    return 1;	default :	    return 0;	}}/* Legitimize PIC addresses.  If the address is already   position-independent, we return ORIG.  Newly generated   position-independent addresses go to REG.  If we need more   than one register, we lose.     An address is legitimized by making an indirect reference   through the Global Offset Table with the name of the symbol   used as an offset.     The assembler and linker are responsible for placing the    address of the symbol in the GOT.  The function prologue   is responsible for initializing a5 to the starting address   of the GOT.   The assembler is also responsible for translating a symbol name   into a constant displacement from the start of the GOT.     A quick example may make things a little clearer:   When not generating PIC code to store the value 12345 into _foo   we would generate the following code:	movel #12345, _foo   When generating PIC two transformations are made.  First, the compiler   loads the address of foo into a register.  So the first transformation makes:	lea	_foo, a0	movel   #12345, a0@   The code in movsi will intercept the lea instruction and call this   routine which will transform the instructions into:	movel   a5@(_foo:w), a0	movel   #12345, a0@      That (in a nutshell) is how *all* symbol and label references are    handled.  */rtxlegitimize_pic_address (orig, mode, reg)     rtx orig, reg;     enum machine_mode mode;{  rtx pic_ref = orig;  /* First handle a simple SYMBOL_REF or LABEL_REF */  if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)

⌨️ 快捷键说明

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