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

📄 m68k.c

📁 linux下编程用 编译软件
💻 C
📖 第 1 页 / 共 5 页
字号:
            {	      if (MOTOROLA)		asm_fprintf (stream, "\tmovm.l -%wd(%s),%I0x%x\n",			     current_frame.offset + fsize,			     M68K_REGNAME(FRAME_POINTER_REGNUM),			     current_frame.reg_mask);	      else		asm_fprintf (stream, "\tmoveml %s@(-%wd),%I0x%x\n",			     M68K_REGNAME(FRAME_POINTER_REGNUM),			     current_frame.offset + fsize,			     current_frame.reg_mask);	    }        }      else /* !TARGET_COLDFIRE */	{	  if (big)	    {	      if (MOTOROLA)		asm_fprintf (stream, "\tmovm.l -%wd(%s,%Ra1.l),%I0x%x\n",			     current_frame.offset + fsize,			     M68K_REGNAME(FRAME_POINTER_REGNUM),			     current_frame.reg_mask);	      else		asm_fprintf (stream, "\tmoveml %s@(-%wd,%Ra1:l),%I0x%x\n",			     M68K_REGNAME(FRAME_POINTER_REGNUM),			     current_frame.offset + fsize,			     current_frame.reg_mask);	    }	  else if (restore_from_sp)	    {	      asm_fprintf (stream, MOTOROLA ?				     "\tmovm.l (%Rsp)+,%I0x%x\n" :				     "\tmoveml %Rsp@+,%I0x%x\n",			   current_frame.reg_mask);	    }	  else	    {	      if (MOTOROLA)		asm_fprintf (stream, "\tmovm.l -%wd(%s),%I0x%x\n",			     current_frame.offset + fsize,			     M68K_REGNAME(FRAME_POINTER_REGNUM),			     current_frame.reg_mask);	      else		asm_fprintf (stream, "\tmoveml %s@(-%wd),%I0x%x\n",			     M68K_REGNAME(FRAME_POINTER_REGNUM),			     current_frame.offset + fsize,			     current_frame.reg_mask);	    }	}    }  if (current_frame.fpu_rev_mask)    {      if (big)	{	  if (MOTOROLA)	    asm_fprintf (stream, "\tfmovm -%wd(%s,%Ra1.l),%I0x%x\n",		         current_frame.foffset + fsize,		         M68K_REGNAME(FRAME_POINTER_REGNUM),		         current_frame.fpu_rev_mask);	  else	    asm_fprintf (stream, "\tfmovem %s@(-%wd,%Ra1:l),%I0x%x\n",			 M68K_REGNAME(FRAME_POINTER_REGNUM),			 current_frame.foffset + fsize,			 current_frame.fpu_rev_mask);	}      else if (restore_from_sp)	{	  if (MOTOROLA)	    asm_fprintf (stream, "\tfmovm (%Rsp)+,%I0x%x\n",			 current_frame.fpu_rev_mask);	  else	    asm_fprintf (stream, "\tfmovem %Rsp@+,%I0x%x\n",			 current_frame.fpu_rev_mask);	}      else	{	  if (MOTOROLA)	    asm_fprintf (stream, "\tfmovm -%wd(%s),%I0x%x\n",			 current_frame.foffset + fsize,			 M68K_REGNAME(FRAME_POINTER_REGNUM),			 current_frame.fpu_rev_mask);	  else	    asm_fprintf (stream, "\tfmovem %s@(-%wd),%I0x%x\n",			 M68K_REGNAME(FRAME_POINTER_REGNUM),			 current_frame.foffset + fsize,			 current_frame.fpu_rev_mask);	}    }  if (frame_pointer_needed)    fprintf (stream, "\tunlk %s\n", M68K_REGNAME(FRAME_POINTER_REGNUM));  else if (fsize_with_regs)    {      if (fsize_with_regs <= 8)	{	  if (!TARGET_COLDFIRE)	    asm_fprintf (stream, "\taddq" ASM_DOT "w %I%wd,%Rsp\n",			 fsize_with_regs);	  else	    asm_fprintf (stream, "\taddq" ASM_DOT "l %I%wd,%Rsp\n",			 fsize_with_regs);	}      else if (fsize_with_regs <= 16 && TARGET_CPU32)	{	  /* On the CPU32 it is faster to use two addqw instructions to	     add a small integer (8 < N <= 16) to a register.  */	  asm_fprintf (stream, "\taddq" ASM_DOT "w %I8,%Rsp\n"	  		       "\taddq" ASM_DOT "w %I%wd,%Rsp\n",		       fsize_with_regs - 8);	}      else if (fsize_with_regs < 0x8000)	{	  if (TARGET_68040)	    asm_fprintf (stream, "\tadd" ASM_DOT "w %I%wd,%Rsp\n",			 fsize_with_regs);	  else	    asm_fprintf (stream, MOTOROLA ?				   "\tlea (%wd,%Rsp),%Rsp\n" :				   "\tlea %Rsp@(%wd),%Rsp\n",			 fsize_with_regs);	}      else	asm_fprintf (stream, "\tadd" ASM_DOT "l %I%wd,%Rsp\n", fsize_with_regs);    }  if (current_function_calls_eh_return)    asm_fprintf (stream, "\tadd" ASM_DOT"l %Ra0,%Rsp\n");  if (m68k_interrupt_function_p (current_function_decl))    fprintf (stream, "\trte\n");  else if (current_function_pops_args)    asm_fprintf (stream, "\trtd %I%d\n", current_function_pops_args);  else    fprintf (stream, "\trts\n");}/* 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_2 (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED){  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;    }}/* Return nonzero if flags are currently in the 68881 flag register.  */intflags_in_68881 (void){  /* We could add support for these in the future */  return cc_status.flags & CC_IN_68881;}/* Output a BSR instruction suitable for PIC code.  */voidm68k_output_pic_call(rtx dest){  const char *out;  if (!(GET_CODE (dest) == MEM && GET_CODE (XEXP (dest, 0)) == SYMBOL_REF))    out = "jsr %0";      /* We output a BSR instruction if we're building for a target that         supports long branches.  Otherwise we generate one of two sequences:         a shorter one that uses a GOT entry or a longer one that doesn't.         We use the -Os command-line flag to decide which to generate.         Both sequences take the same time to execute on the ColdFire.  */  else if (TARGET_PCREL)    out = "bsr.l %o0";  else if (TARGET_68020)#if defined(USE_GAS)    out = "bsr.l %0@PLTPC";#else    out = "bsr %0@PLTPC";#endif  else if (optimize_size || TARGET_ID_SHARED_LIBRARY)    out = "move.l %0@GOT(%%a5), %%a1\n\tjsr (%%a1)";  else    out = "lea %0-.-8,%%a1\n\tjsr 0(%%pc,%%a1)";  output_asm_insn(out, &dest);}/* 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 and flags_in_68881 will   kick those out before we get here.  */voidoutput_dbcc_and_branch (rtx *operands){  switch (GET_CODE (operands[3]))    {      case EQ:	output_asm_insn (MOTOROLA ?			   "dbeq %0,%l1\n\tjbeq %l2" :			   "dbeq %0,%l1\n\tjeq %l2",			 operands);	break;      case NE:	output_asm_insn (MOTOROLA ?			   "dbne %0,%l1\n\tjbne %l2" :			   "dbne %0,%l1\n\tjne %l2",			 operands);	break;      case GT:	output_asm_insn (MOTOROLA ?			   "dbgt %0,%l1\n\tjbgt %l2" :			   "dbgt %0,%l1\n\tjgt %l2",			 operands);	break;      case GTU:	output_asm_insn (MOTOROLA ?			   "dbhi %0,%l1\n\tjbhi %l2" :			   "dbhi %0,%l1\n\tjhi %l2",			 operands);	break;      case LT:	output_asm_insn (MOTOROLA ?			   "dblt %0,%l1\n\tjblt %l2" :			   "dblt %0,%l1\n\tjlt %l2",			 operands);	break;      case LTU:	output_asm_insn (MOTOROLA ?			   "dbcs %0,%l1\n\tjbcs %l2" :			   "dbcs %0,%l1\n\tjcs %l2",			 operands);	break;      case GE:	output_asm_insn (MOTOROLA ?			   "dbge %0,%l1\n\tjbge %l2" :			   "dbge %0,%l1\n\tjge %l2",			 operands);	break;      case GEU:	output_asm_insn (MOTOROLA ?			   "dbcc %0,%l1\n\tjbcc %l2" :			   "dbcc %0,%l1\n\tjcc %l2",			 operands);	break;      case LE:	output_asm_insn (MOTOROLA ?			   "dble %0,%l1\n\tjble %l2" :			   "dble %0,%l1\n\tjle %l2",			 operands);	break;      case LEU:	output_asm_insn (MOTOROLA ?			   "dbls %0,%l1\n\tjbls %l2" : 			   "dbls %0,%l1\n\tjls %l2",			 operands);	break;      default:	gcc_unreachable ();    }  /* 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:        output_asm_insn (MOTOROLA ?			   "clr%.w %0\n\tsubq%.l #1,%0\n\tjbpl %l1" :			   "clr%.w %0\n\tsubq%.l #1,%0\n\tjpl %l1",			 operands);        break;      case HImode:        break;      default:        gcc_unreachable ();    }}const char *output_scc_di (rtx op, rtx operand1, rtx operand2, rtx dest){  rtx loperands[7];  enum rtx_code op_code = GET_CODE (op);  /* This does not produce a useful cc.  */  CC_STATUS_INIT;  /* 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] = adjust_address (operand1, SImode, 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] = adjust_address (operand2, SImode, 4);    }  loperands[4] = gen_label_rtx ();  if (operand2 != const0_rtx)    {      output_asm_insn (MOTOROLA ?	  "cmp%.l %2,%0\n\tjbne %l4\n\tcmp%.l %3,%1" :          "cmp%.l %2,%0\n\tjne %l4\n\tcmp%.l %3,%1",	loperands);    }  else    {      if (TARGET_68020 || TARGET_COLDFIRE || ! ADDRESS_REG_P (loperands[0]))	output_asm_insn ("tst%.l %0", loperands);      else	{	  output_asm_insn ("cmp%.w #0,%0", loperands);	}      output_asm_insn (MOTOROLA ? "jbne %l4" : "jne %l4", loperands);      if (TARGET_68020 || TARGET_COLDFIRE || ! ADDRESS_REG_P (loperands[1]))	output_asm_insn ("tst%.l %1", loperands);      else	output_asm_insn ("cmp%.w #0,%1", loperands);    }  loperands[5] = dest;  switch (op_code)    {      case EQ:        (*targetm.asm_out.internal_label) (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[4]));        output_asm_insn ("seq %5", loperands);        break;      case NE:        (*targetm.asm_out.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 ();        output_asm_insn (MOTOROLA ?			   "shi %5\n\tjbra %l6" :			   "shi %5\n\tjra %l6",			 loperands);        (*targetm.asm_out.internal_label) (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[4]));        output_asm_insn ("sgt %5", loperands);        (*targetm.asm_out.internal_label) (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[6]));        break;      case GTU:        (*targetm.asm_out.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 ();        output_asm_insn (MOTOROLA ?			   "scs %5\n\tjbra %l6" :			   "scs %5\n\tjra %l6",			 loperands);        (*targetm.asm_out.internal_label) (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[4]));        output_asm_insn ("slt %5", loperands);        (*targetm.asm_out.internal_label) (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[6]));        break;      case LTU:        (*targetm.asm_out.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 ();        output_asm_insn (MOTOROLA ?			   "scc %5\n\tjbra %l6" :			   "scc %5\n\tjra %l6",			   loperands);        (*targetm.asm_out.internal_label) (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[4]));        output_asm_insn ("sge %5", loperands);        (*targetm.asm_out.internal_label) (asm_out_file, "L",				    CODE_LABEL_NUMBER (loperands[6]));        break;      case GEU:        (*targetm.asm_out.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 ();        output_asm_insn (MOTOROLA ?			   "sls %5\n\tjbra %l6" :			   "sls %5\n\tjra %l6",			 loperands);

⌨️ 快捷键说明

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