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

📄 tc-m68k.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
		  if (opP->reg == PC)		    tmpreg = 0x3A;	/* 7.2 */		  else		    tmpreg = 0x28 + opP->reg - ADDR;	/* 5.areg */		  if (isvar (&opP->disp))		    {		      if (opP->reg == PC)			{			  add_fix ('w', &opP->disp, 1, 0);			}		      else			add_fix ('w', &opP->disp, 0, 0);		    }		}	      addword (nextword);	      break;	    case POST:	    case PRE:	    case BASE:	      nextword = 0;	      baseo = get_num (&opP->disp, 80);	      if (opP->mode == POST || opP->mode == PRE)		outro = get_num (&opP->odisp, 80);	      /* Figure out the `addressing mode'.		 Also turn on the BASE_DISABLE bit, if needed.  */	      if (opP->reg == PC || opP->reg == ZPC)		{		  tmpreg = 0x3b;	/* 7.3 */		  if (opP->reg == ZPC)		    nextword |= 0x80;		}	      else if (opP->reg == 0)		{		  nextword |= 0x80;		  tmpreg = 0x30;	/* 6.garbage */		}	      else if (opP->reg >= ZADDR0 && opP->reg <= ZADDR7)		{		  nextword |= 0x80;		  tmpreg = 0x30 + opP->reg - ZADDR0;		}	      else		tmpreg = 0x30 + opP->reg - ADDR;	/* 6.areg */	      siz1 = opP->disp.size;	      if (opP->mode == POST || opP->mode == PRE)		siz2 = opP->odisp.size;	      else		siz2 = SIZE_UNSPEC;	      /* Index register stuff */	      if (opP->index.reg != 0		  && opP->index.reg >= DATA		  && opP->index.reg <= ADDR7)		{		  nextword |= (opP->index.reg - DATA) << 12;		  if (opP->index.size == SIZE_LONG		      || (opP->index.size == SIZE_UNSPEC			  && m68k_index_width_default == SIZE_LONG))		    nextword |= 0x800;		  if ((opP->index.scale != 1		       && cpu_of_arch (current_architecture) < m68020)		      || (opP->index.scale == 8			  && arch_coldfire_p (current_architecture)))		    {		      opP->error =			_("scale factor invalid on this architecture; needs cpu32 or 68020 or higher");		    }		  if (arch_coldfire_p (current_architecture)		      && opP->index.size == SIZE_WORD)		    opP->error = _("invalid index size for coldfire");		  switch (opP->index.scale)		    {		    case 1:		      break;		    case 2:		      nextword |= 0x200;		      break;		    case 4:		      nextword |= 0x400;		      break;		    case 8:		      nextword |= 0x600;		      break;		    default:		      abort ();		    }		  /* IF its simple,		     GET US OUT OF HERE! */		  /* Must be INDEX, with an index register.  Address		     register cannot be ZERO-PC, and either :b was		     forced, or we know it will fit.  For a 68000 or		     68010, force this mode anyways, because the		     larger modes aren't supported.  */		  if (opP->mode == BASE		      && ((opP->reg >= ADDR0			   && opP->reg <= ADDR7)			  || opP->reg == PC))		    {		      if (siz1 == SIZE_BYTE			  || cpu_of_arch (current_architecture) < m68020			  || arch_coldfire_p (current_architecture)			  || (siz1 == SIZE_UNSPEC			      && ! isvar (&opP->disp)			      && issbyte (baseo)))			{ 			  nextword += baseo & 0xff; 			  addword (nextword); 			  if (isvar (&opP->disp))			    {			      /* Do a byte relocation.  If it doesn't				 fit (possible on m68000) let the				 fixup processing complain later.  */			      if (opP->reg == PC)				add_fix ('B', &opP->disp, 1, 1);			      else				add_fix ('B', &opP->disp, 0, 0);			    }			  else if (siz1 != SIZE_BYTE)			    {			      if (siz1 != SIZE_UNSPEC)				as_warn (_("Forcing byte displacement"));			      if (! issbyte (baseo))				opP->error = _("byte displacement out of range");			    }			  break;			}		      else if (siz1 == SIZE_UNSPEC			       && opP->reg == PC			       && isvar (&opP->disp)			       && subs (&opP->disp) == NULL#ifdef OBJ_ELF			       /* If the displacement needs pic				  relocation it cannot be relaxed.  */			       && opP->disp.pic_reloc == pic_none#endif			       )			{			  /* The code in md_convert_frag_1 needs to be                             able to adjust nextword.  Call frag_grow                             to ensure that we have enough space in                             the frag obstack to make all the bytes                             contiguous.  */			  frag_grow (14); 			  nextword += baseo & 0xff; 			  addword (nextword); 			  add_frag (adds (&opP->disp), offs (&opP->disp), 				    TAB (PCINDEX, SZ_UNDEF));			  break; 			}		    }		}	      else		{		  nextword |= 0x40;	/* No index reg */		  if (opP->index.reg >= ZDATA0		      && opP->index.reg <= ZDATA7)		    nextword |= (opP->index.reg - ZDATA0) << 12;		  else if (opP->index.reg >= ZADDR0			   || opP->index.reg <= ZADDR7)		    nextword |= (opP->index.reg - ZADDR0 + 8) << 12;		}	      /* It isn't simple.  */	      if (cpu_of_arch (current_architecture) < m68020		  || arch_coldfire_p (current_architecture))		opP->error =		  _("invalid operand mode for this architecture; needs 68020 or higher");	      nextword |= 0x100;	      /* If the guy specified a width, we assume that it is		 wide enough.  Maybe it isn't.  If so, we lose.  */	      switch (siz1)		{		case SIZE_UNSPEC:		  if (isvar (&opP->disp)		      ? m68k_rel32		      : ! issword (baseo))		    {		      siz1 = SIZE_LONG;		      nextword |= 0x30;		    }		  else if (! isvar (&opP->disp) && baseo == 0)		    nextword |= 0x10;		  else		    {		      nextword |= 0x20;		      siz1 = SIZE_WORD;		    }		  break;		case SIZE_BYTE:		  as_warn (_(":b not permitted; defaulting to :w"));		  /* Fall through.  */		case SIZE_WORD:		  nextword |= 0x20;		  break;		case SIZE_LONG:		  nextword |= 0x30;		  break;		}	      /* Figure out innner displacement stuff */	      if (opP->mode == POST || opP->mode == PRE)		{		  if (cpu_of_arch (current_architecture) & cpu32)		    opP->error = _("invalid operand mode for this architecture; needs 68020 or higher");		  switch (siz2)		    {		    case SIZE_UNSPEC:		      if (isvar (&opP->odisp)			  ? m68k_rel32			  : ! issword (outro))			{			  siz2 = SIZE_LONG;			  nextword |= 0x3;			}		      else if (! isvar (&opP->odisp) && outro == 0)			nextword |= 0x1;		      else			{			  nextword |= 0x2;			  siz2 = SIZE_WORD;			}		      break;		    case 1:		      as_warn (_(":b not permitted; defaulting to :w"));		      /* Fall through.  */		    case 2:		      nextword |= 0x2;		      break;		    case 3:		      nextword |= 0x3;		      break;		    }		  if (opP->mode == POST		      && (nextword & 0x40) == 0)		    nextword |= 0x04;		}	      addword (nextword);	      if (siz1 != SIZE_UNSPEC && isvar (&opP->disp))		{		  if (opP->reg == PC || opP->reg == ZPC)		    add_fix (siz1 == SIZE_LONG ? 'l' : 'w', &opP->disp, 1, 2);		  else		    add_fix (siz1 == SIZE_LONG ? 'l' : 'w', &opP->disp, 0, 0);		}	      if (siz1 == SIZE_LONG)		addword (baseo >> 16);	      if (siz1 != SIZE_UNSPEC)		addword (baseo);	      if (siz2 != SIZE_UNSPEC && isvar (&opP->odisp))		add_fix (siz2 == SIZE_LONG ? 'l' : 'w', &opP->odisp, 0, 0);	      if (siz2 == SIZE_LONG)		addword (outro >> 16);	      if (siz2 != SIZE_UNSPEC)		addword (outro);	      break;	    case ABSL:	      nextword = get_num (&opP->disp, 80);	      switch (opP->disp.size)		{		default:		  abort ();		case SIZE_UNSPEC:		  if (!isvar (&opP->disp) && issword (offs (&opP->disp)))		    {		      tmpreg = 0x38;	/* 7.0 */		      addword (nextword);		      break;		    }		  if (isvar (&opP->disp)		      && !subs (&opP->disp)		      && adds (&opP->disp)#ifdef OBJ_ELF		      /* If the displacement needs pic relocation it			 cannot be relaxed.  */		      && opP->disp.pic_reloc == pic_none#endif		      && !flag_long_jumps		      && !strchr ("~%&$?", s[0]))		    {		      tmpreg = 0x3A;	/* 7.2 */		      add_frag (adds (&opP->disp),				offs (&opP->disp),				TAB (ABSTOPCREL, SZ_UNDEF));		      break;		    }		  /* Fall through into long */		case SIZE_LONG:		  if (isvar (&opP->disp))		    add_fix ('l', &opP->disp, 0, 0);		  tmpreg = 0x39;/* 7.1 mode */		  addword (nextword >> 16);		  addword (nextword);		  break;		case SIZE_BYTE:		  as_bad (_("unsupported byte value; use a different suffix"));		  /* Fall through.  */		case SIZE_WORD:	/* Word */		  if (isvar (&opP->disp))		    add_fix ('w', &opP->disp, 0, 0);		  tmpreg = 0x38;/* 7.0 mode */		  addword (nextword);		  break;		}	      break;	    case CONTROL:	    case FPREG:	    default:	      as_bad (_("unknown/incorrect operand"));	      /* abort (); */	    }	  install_gen_operand (s[1], tmpreg);	  break;	case '#':	case '^':	  switch (s[1])	    {			/* JF: I hate floating point! */	    case 'j':	      tmpreg = 70;	      break;	    case '8':	      tmpreg = 20;	      break;	    case 'C':	      tmpreg = 50;	      break;	    case '3':	    default:	      tmpreg = 80;	      break;	    }	  tmpreg = get_num (&opP->disp, tmpreg);	  if (isvar (&opP->disp))	    add_fix (s[1], &opP->disp, 0, 0);	  switch (s[1])	    {	    case 'b':		/* Danger:  These do no check for				   certain types of overflow.				   user beware! */	      if (!isbyte (tmpreg))		opP->error = _("out of range");	      insop (tmpreg, opcode);	      if (isvar (&opP->disp))		the_ins.reloc[the_ins.nrel - 1].n =		  (opcode->m_codenum) * 2 + 1;	      break;	    case 'B':	      if (!issbyte (tmpreg))		opP->error = _("out of range");	      the_ins.opcode[the_ins.numo - 1] |= tmpreg & 0xff;	      if (isvar (&opP->disp))		the_ins.reloc[the_ins.nrel - 1].n = opcode->m_codenum * 2 - 1;	      break;	    case 'w':	      if (!isword (tmpreg))		opP->error = _("out of range");	      insop (tmpreg, opcode);	      if (isvar (&opP->disp))		the_ins.reloc[the_ins.nrel - 1].n = (opcode->m_codenum) * 2;	      break;	    case 'W':	      if (!issword (tmpreg))		opP->error = _("out of range");	      insop (tmpreg, opcode);	      if (isvar (&opP->disp))		the_ins.reloc[the_ins.nrel - 1].n = (opcode->m_codenum) * 2;	      break;	    case 'l':	      /* Because of the way insop works, we put these two out		 backwards.  */	      insop (tmpreg, opcode);	      insop (tmpreg >> 16, opcode);	      if (isvar (&opP->disp))		the_ins.reloc[the_ins.nrel - 1].n = (opcode->m_codenum) * 2;	      break;	    case '3':	      tmpreg &= 0xFF;	    case '8':	    case 'C':	    case 'j':	      install_operand (s[1], tmpreg);	      break;	    default:	      abort ();	    }	  break;	case '+':	case '-':	case 'A':	case 'a':	  install_operand (s[1], opP->reg - ADDR);	  break;	case 'B':	  tmpreg = get_num (&opP->disp, 80);	  switch (s[1])	    {	    case 'B':	      add_fix ('B', &opP->disp, 1, -1);	      break;	    case 'W':	      add_fix ('w', &opP->disp, 1, 0);	      addword (0);	      break;	    case 'L':	    long_branch:	      if (! HAVE_LONG_BRANCH (current_architecture))		as_warn (_("Can't use long branches on 68000/68010/5200"));	      the_ins.opcode[0] |= 0xff;	      add_fix ('l', &opP->disp, 1, 0);	      addword (0);	      addword (0);	      break;	    case 'g':	      if (subs (&opP->disp))	/* We can't relax it */		goto long_branch;#ifdef OBJ_ELF	      /* If the displacement needs pic relocation it cannot be		 relaxed.  */	      if (opP->disp.pic_reloc != pic_none)		goto long_branch;#endif	      /* This could either be a symbol, or an absolute		 address.  If it's an absolute address, turn it into		 an absolute jump right here and keep it out of the		 relaxer.  */	      if (adds (&opP->disp) == 0)		{		  if (the_ins.opcode[0] == 0x6000)	/* jbra */		    the_ins.opcode[0] = 0x4EF1;		  else if (the_ins.opcode[0] == 0x6100)	/* jbsr */		    the_ins.opcode[0] = 0x4EB1;		  else					/* jCC */		    {		      the_ins.opcode[0] ^= 0x0100;		      the_ins.opcode[0] |= 0x0006;		      addword (0x4EF1);		    }		  add_fix ('l', &opP->disp, 0, 0);		  addword (0);		  addword (0);		  break;		}	      /* Now we know it's going into the relaxer.  Now figure		 out which mode.  We try in this order of preference:		 long branch, absolute jump, byte/word branches only.  */	      if (HAVE_LONG_BRANCH (current_architecture))		add_frag (adds (&opP->disp), offs (&opP->disp),			  TAB (BRANCHBWL, SZ_UNDEF));	      else if (! flag_keep_pcrel)		{		  if ((the_ins.opcode[0] == 0x6000)		      || (the_ins.opcode[0] == 0x6100))		    add_frag (adds (&opP->disp), offs (&opP->disp),			      TAB (BRABSJUNC, SZ_UNDEF));		  else		    add_frag (adds (&opP->disp), offs (&opP->disp),			      TAB (BRABSJCOND, SZ_UNDEF));		}	      else		add_frag (adds (&opP->disp), offs (&opP->disp),			  TAB (BRANCHBW, SZ_UNDEF));	      break;	    case 'w':	      if (isvar (&opP->disp))		{		  /* Check for DBcc instructions.  We can relax them,		     but only if we have long branches and/or absolute		     jumps.  */		  if (((the_ins.opcode[0] & 0xf0f8) == 0x50c8)		      && (HAVE_LONG_BRANCH (current_architecture)			  || (! flag_keep_pcrel)))		    {		      if (HAVE_LONG_BRANCH (current_architecture))			add_frag (adds (&opP->disp), offs (&opP->disp),				  TAB (DBCCLBR, SZ_UNDEF));		      else			add_frag (adds (&opP->disp), offs (&opP->disp),				  TAB (DBCCABSJ, SZ_UNDEF));		      break;		    }		  add_fix ('w', &opP->disp, 1, 0);		}	      addword (0);	      break;	    case 'C':		/* Fixed size LONG coproc branches */	      add_fix ('l', &opP->disp, 1, 0);	      addword (0);	      addword (0);	      break;	    case 'c':		/* Var size Coprocesssor branches */	      if (subs (&opP->disp) || (adds (&opP->disp) == 0))		{		  the_ins.opcode[the_ins.numo - 1] |= 0x40;		  add_fix ('l', &opP->disp, 1, 0);		  addword (0);		  addword (0);		}	      else		add_frag (adds (&opP->disp), offs (&opP->disp),			  TAB (FBRANCH, SZ_UNDEF));	      break;	    default:	      abort ();	    }	  break;	

⌨️ 快捷键说明

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