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

📄 m68k.md

📁 早期freebsd实现
💻 MD
📖 第 1 页 / 共 5 页
字号:
	  /* clr insns on 68000 read before writing.	     This isn't so on the 68010, but we have no alternative for it.  */	  && (TARGET_68020	      || !(GET_CODE (operands[0]) == MEM		   && MEM_VOLATILE_P (operands[0]))))	return \"clr%.w %0\";      else if (DATA_REG_P (operands[0])	       && INTVAL (operands[1]) < 128	       && INTVAL (operands[1]) >= -128)        {#if defined(MOTOROLA) && !defined(CRDS)          return \"moveq%.l %1,%0\";#else	  return \"moveq %1,%0\";#endif	}      else if (INTVAL (operands[1]) < 0x8000	       && INTVAL (operands[1]) >= -0x8000)	return \"move%.w %1,%0\";    }  else if (CONSTANT_P (operands[1]))    return \"move%.l %1,%0\";#ifndef SGS_NO_LI  /* Recognize the insn before a tablejump, one that refers     to a table of offsets.  Such an insn will need to refer     to a label on the insn.  So output one.  Use the label-number     of the table of offsets to generate this label.  */  if (GET_CODE (operands[1]) == MEM      && GET_CODE (XEXP (operands[1], 0)) == PLUS      && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF	  || GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF)      && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS      && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) != PLUS)    {      rtx labelref;      if (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF)	labelref = XEXP (XEXP (operands[1], 0), 0);      else	labelref = XEXP (XEXP (operands[1], 0), 1);#if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES)#ifdef SGS      asm_fprintf (asm_out_file, \"\\tset %LLI%d,.+2\\n\",		   CODE_LABEL_NUMBER (XEXP (labelref, 0)));#else /* not SGS */      asm_fprintf (asm_out_file, \"\\t.set %LLI%d,.+2\\n\",	           CODE_LABEL_NUMBER (XEXP (labelref, 0)));#endif /* not SGS */#else /* SGS_SWITCH_TABLES or not MOTOROLA */      ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LI\",				 CODE_LABEL_NUMBER (XEXP (labelref, 0)));#ifdef SGS_SWITCH_TABLES      /* Set flag saying we need to define the symbol	 LD%n (with value L%n-LI%n) at the end of the switch table.  */      switch_table_difference_label_flag = 1;#endif /* SGS_SWITCH_TABLES */#endif /* SGS_SWITCH_TABLES or not MOTOROLA */    }#endif /* SGS_NO_LI */  return \"move%.w %1,%0\";}")(define_insn "movstricthi"  [(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))	(match_operand:HI 1 "general_operand" "rmn"))]  ""  "*{  if (GET_CODE (operands[1]) == CONST_INT)    {      if (operands[1] == const0_rtx	  && (DATA_REG_P (operands[0])	      || GET_CODE (operands[0]) == MEM)	  /* clr insns on 68000 read before writing.	     This isn't so on the 68010, but we have no alternative for it.  */	  && (TARGET_68020	      || !(GET_CODE (operands[0]) == MEM		   && MEM_VOLATILE_P (operands[0]))))	return \"clr%.w %0\";    }  return \"move%.w %1,%0\";}")(define_insn "movqi"  [(set (match_operand:QI 0 "general_operand" "=d,*a,m,m,?*a")	(match_operand:QI 1 "general_operand" "dmi*a,d*a,dmi,?*a,m"))]  ""  "*{  rtx xoperands[4];  /* This is probably useless, since it loses for pushing a struct     of several bytes a byte at a time.  */  if (GET_CODE (operands[0]) == MEM      && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC      && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx)    {      xoperands[1] = operands[1];      xoperands[2]        = gen_rtx (MEM, QImode,		   gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx));      /* Just pushing a byte puts it in the high byte of the halfword.  */      /* We must put it in the low-order, high-numbered byte.  */      output_asm_insn (\"move%.b %1,%-\;move%.b %@,%2\", xoperands);      return \"\";    }  /* HACK Alert.  This is a quick fix while RMS makes up his     mind about what he wants to do about this case.  */  /* if d0 is used in the address calculation, use d1 */  if (refers_to_regno_p (0, 1, PATTERN (insn), NULL_PTR))    {      /* Moving a byte into an address register is not possible.  */      /* Use d1 as an intermediate, but don't clobber its contents.  */      if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM)	return \"exg %/d1,%0\;move%.b %1,%/d1\;exg %/d1,%0\";      /* Likewise for moving from an address reg.  */      if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM)	return \"exg %/d1,%1\;move%.b %/d1,%0\;exg %/d1,%1\";    }  else    {      /* Moving a byte into an address register is not possible.  */      /* Use d0 as an intermediate, but don't clobber its contents.  */      if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM)	return \"exg %/d0,%0\;move%.b %1,%/d0\;exg %/d0,%0\";      /* Likewise for moving from an address reg.  */      if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM)	return \"exg %/d0,%1\;move%.b %/d0,%0\;exg %/d0,%1\";    }  /* clr and st insns on 68000 read before writing.     This isn't so on the 68010, but we have no alternative for it.  */  if (TARGET_68020      || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))    {      if (operands[1] == const0_rtx)	return \"clr%.b %0\";      if (GET_CODE (operands[1]) == CONST_INT	  && INTVAL (operands[1]) == -1)	{	  CC_STATUS_INIT;	  return \"st %0\";	}    }  if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1]))    return \"move%.l %1,%0\";  if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))    return \"move%.w %1,%0\";  return \"move%.b %1,%0\";}")(define_insn "movstrictqi"  [(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))	(match_operand:QI 1 "general_operand" "dmn"))]  ""  "*{  if (operands[1] == const0_rtx      /* clr insns on 68000 read before writing.         This isn't so on the 68010, but we have no alternative for it.  */      && (TARGET_68020          || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))    return \"clr%.b %0\";  return \"move%.b %1,%0\";}")(define_insn "movsf"  [(set (match_operand:SF 0 "general_operand" "=rmf,x,y,rm,!x,!rm")	(match_operand:SF 1 "general_operand" "rmfF,xH,rmF,y,rm,x"))];  [(set (match_operand:SF 0 "general_operand" "=rmf");	(match_operand:SF 1 "general_operand" "rmfF"))]  ""  "*{  if (which_alternative >= 4)    return \"fpmove%.s %1,fpa0\;fpmove%.s fpa0,%0\";  if (FPA_REG_P (operands[0]))    {      if (FPA_REG_P (operands[1]))	return \"fpmove%.s %x1,%x0\";      else if (GET_CODE (operands[1]) == CONST_DOUBLE)	return output_move_const_single (operands);      else if (FP_REG_P (operands[1]))        return \"fmove%.s %1,sp@-\;fpmove%.d sp@+, %0\";      return \"fpmove%.s %x1,%x0\";    }  if (FPA_REG_P (operands[1]))    {      if (FP_REG_P (operands[0]))	return \"fpmove%.s %x1,sp@-\;fmove%.s sp@+,%0\";      else	return \"fpmove%.s %x1,%x0\";    }  if (FP_REG_P (operands[0]))    {      if (FP_REG_P (operands[1]))	return \"f%$move%.x %1,%0\";      else if (ADDRESS_REG_P (operands[1]))	return \"move%.l %1,%-\;f%$move%.s %+,%0\";      else if (GET_CODE (operands[1]) == CONST_DOUBLE)	return output_move_const_single (operands);      return \"f%$move%.s %f1,%0\";    }  if (FP_REG_P (operands[1]))    {      if (ADDRESS_REG_P (operands[0]))	return \"fmove%.s %1,%-\;move%.l %+,%0\";      return \"fmove%.s %f1,%0\";    }  return \"move%.l %1,%0\";}")(define_insn "movdf"  [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>,y,rm,x,!x,!rm")	(match_operand:DF 1 "general_operand" "rf,m,rofE<>,rmE,y,xH,rm,x"))];  [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>");	(match_operand:DF 1 "general_operand" "rf,m,rofF<>"))]  ""  "*{  if (which_alternative == 6)    return \"fpmove%.d %x1,fpa0\;fpmove%.d fpa0,%x0\";  if (FPA_REG_P (operands[0]))    {      if (GET_CODE (operands[1]) == CONST_DOUBLE)	return output_move_const_double (operands);      if (FP_REG_P (operands[1]))        return \"fmove%.d %1,sp@-\;fpmove%.d sp@+,%x0\";      return \"fpmove%.d %x1,%x0\";    }  else if (FPA_REG_P (operands[1]))    {      if (FP_REG_P(operands[0]))        return \"fpmove%.d %x1,sp@-\;fmoved sp@+,%0\";      else        return \"fpmove%.d %x1,%x0\";    }  if (FP_REG_P (operands[0]))    {      if (FP_REG_P (operands[1]))	return \"f%&move%.x %1,%0\";      if (REG_P (operands[1]))	{	  rtx xoperands[2];	  xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);	  output_asm_insn (\"move%.l %1,%-\", xoperands);	  output_asm_insn (\"move%.l %1,%-\", operands);	  return \"f%&move%.d %+,%0\";	}      if (GET_CODE (operands[1]) == CONST_DOUBLE)	return output_move_const_double (operands);      return \"f%&move%.d %f1,%0\";    }  else if (FP_REG_P (operands[1]))    {      if (REG_P (operands[0]))	{	  output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);	  operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);	  return \"move%.l %+,%0\";	}      else        return \"fmove%.d %f1,%0\";    }  return output_move_double (operands);}");; movdi can apply to fp regs in some cases(define_insn "movdi"  ;; Let's see if it really still needs to handle fp regs, and, if so, why.  [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>,y,rm,!*x,!rm")	(match_operand:DI 1 "general_operand" "rF,m,roi<>F,rmiF,y,rmF,*x"))];  [(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro<>,!&rm,!&f,y,rm,x,!x,!rm");	(match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfmF,rmi,y,rm,x"))];  [(set (match_operand:DI 0 "general_operand" "=rm,&rf,&ro<>,!&rm,!&f");	(match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfF"))]  ""  "*{  if (which_alternative == 8)    return \"fpmove%.d %x1,fpa0\;fpmove%.d fpa0,%x0\";  if (FPA_REG_P (operands[0]) || FPA_REG_P (operands[1]))    return \"fpmove%.d %x1,%x0\";  if (FP_REG_P (operands[0]))    {      if (FP_REG_P (operands[1]))	return \"fmove%.x %1,%0\";      if (REG_P (operands[1]))	{	  rtx xoperands[2];	  xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);	  output_asm_insn (\"move%.l %1,%-\", xoperands);	  output_asm_insn (\"move%.l %1,%-\", operands);	  return \"fmove%.d %+,%0\";	}      if (GET_CODE (operands[1]) == CONST_DOUBLE)	return output_move_const_double (operands);      return \"fmove%.d %f1,%0\";    }  else if (FP_REG_P (operands[1]))    {      if (REG_P (operands[0]))	{	  output_asm_insn (\"fmove%.d %f1,%-\;move%.l %+,%0\", operands);	  operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);	  return \"move%.l %+,%0\";	}      else        return \"fmove%.d %f1,%0\";    }  return output_move_double (operands);}");; Thus goes after the move instructions;; because the move instructions are better (require no spilling);; when they can apply.  It goes before the add/sub insns;; so we will prefer it to them.(define_insn "pushasi"  [(set (match_operand:SI 0 "push_operand" "=m")	(match_operand:SI 1 "address_operand" "p"))]  ""  "pea %a1");; truncation instructions(define_insn "truncsiqi2"  [(set (match_operand:QI 0 "general_operand" "=dm,d")	(truncate:QI	 (match_operand:SI 1 "general_operand" "doJ,i")))]  ""  "*{  if (GET_CODE (operands[0]) == REG)    {      /* Must clear condition codes, since the move.l bases them on	 the entire 32 bits, not just the desired 8 bits.  */      CC_STATUS_INIT;      return \"move%.l %1,%0\";    }  if (GET_CODE (operands[1]) == MEM)    operands[1] = adj_offsettable_operand (operands[1], 3);  return \"move%.b %1,%0\";}")(define_insn "trunchiqi2"  [(set (match_operand:QI 0 "general_operand" "=dm,d")	(truncate:QI	 (match_operand:HI 1 "general_operand" "doJ,i")))]  ""  "*{  if (GET_CODE (operands[0]) == REG      && (GET_CODE (operands[1]) == MEM	  || GET_CODE (operands[1]) == CONST_INT))    {      /* Must clear condition codes, since the move.w bases them on	 the entire 16 bits, not just the desired 8 bits.  */      CC_STATUS_INIT;      return \"move%.w %1,%0\";    }  if (GET_CODE (operands[0]) == REG)    {      /* Must clear condition codes, since the move.l bases them on	 the entire 32 bits, not just the desired 8 bits.  */      CC_STATUS_INIT;      return \"move%.l %1,%0\";    }  if (GET_CODE (operands[1]) == MEM)    operands[1] = adj_offsettable_operand (operands[1], 1);  return \"move%.b %1,%0\";}")(define_insn "truncsihi2"  [(set (match_operand:HI 0 "general_operand" "=dm,d")	(truncate:HI	 (match_operand:SI 1 "general_operand" "roJ,i")))]  ""  "*{  if (GET_CODE (operands[0]) == REG)    {      /* Must clear condition codes, since the move.l bases them on	 the entire 32 bits, not just the desired 8 bits.  */      CC_STATUS_INIT;      return \"move%.l %1,%0\";    }  if (GET_CODE (operands[1]) == MEM)    operands[1] = adj_offsettable_operand (operands[1], 2);  return \"move%.w %1,%0\";}");; zero extension instructions(define_expand "zero_extendhisi2"  [(set (match_operand:SI 0 "register_operand" "")	(const_int 0))   (set (strict_low_part (match_dup 2))	(match_operand:HI 1 "general_operand" ""))]  ""  "{  operands[1] = make_safe_from (operands[1], operands[0]);  if (GET_CODE (operands[0]) == SUBREG)    operands[2] = gen_rtx (SUBREG, HImode, SUBREG_REG (operands[0]),			   SUBREG_WORD (operands[0]));  else    operands[2] = gen_rtx (SUBREG, HImode, operands[0], 0);}")

⌨️ 快捷键说明

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