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

📄 tc-m68k.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
			      opP->mask = 1 << (opP->reg - FP0 + 16);			      break;			    default:			      abort ();			    }			  opP->mode = REGLST;			}		    }		  else if (opP->mode == CONTROL)		    {		      if (s[1] != '8')			losing++;		      else			{			  switch (opP->reg)			    {			    case FPI:			      opP->mask = 1 << 24;			      break;			    case FPS:			      opP->mask = 1 << 25;			      break;			    case FPC:			      opP->mask = 1 << 26;			      break;			    default:			      losing++;			      break;			    }			  opP->mode = REGLST;			}		    }		  else if (opP->mode != REGLST)		    losing++;		  else if (s[1] == '8' && (opP->mask & 0x0ffffff) != 0)		    losing++;		  else if (s[1] == '3' && (opP->mask & 0x7000000) != 0)		    losing++;		  break;		case 'M':		  if (opP->mode != IMMED)		    losing++;		  else if (opP->disp.exp.X_op != O_constant			   || ! issbyte (opP->disp.exp.X_add_number))		    losing++;		  else if (! m68k_quick			   && instring[3] != 'q'			   && instring[4] != 'q')		    losing++;		  break;		case 'O':		  if (opP->mode != DREG		      && opP->mode != IMMED		      && opP->mode != ABSL)		    losing++;		  break;		case 'Q':		  if (opP->mode != IMMED)		    losing++;		  else if (opP->disp.exp.X_op != O_constant			   || opP->disp.exp.X_add_number < 1			   || opP->disp.exp.X_add_number > 8)		    losing++;		  else if (! m68k_quick			   && (strncmp (instring, "add", 3) == 0			       || strncmp (instring, "sub", 3) == 0)			   && instring[3] != 'q')		    losing++;		  break;		case 'R':		  if (opP->mode != DREG && opP->mode != AREG)		    losing++;		  break;		case 'r':		  if (opP->mode != AINDR		      && (opP->mode != BASE			  || (opP->reg != 0			      && opP->reg != ZADDR0)			  || opP->disp.exp.X_op != O_absent			  || ((opP->index.reg < DATA0			       || opP->index.reg > DATA7)			      && (opP->index.reg < ADDR0				  || opP->index.reg > ADDR7))			  || opP->index.size != SIZE_UNSPEC			  || opP->index.scale != 1))		    losing++;		  break;		case 's':		  if (opP->mode != CONTROL		      || ! (opP->reg == FPI			    || opP->reg == FPS			    || opP->reg == FPC))		    losing++;		  break;		case 'S':		  if (opP->mode != CONTROL || opP->reg != SR)		    losing++;		  break;		case 't':		  if (opP->mode != IMMED)		    losing++;		  else if (opP->disp.exp.X_op != O_constant			   || opP->disp.exp.X_add_number < 0			   || opP->disp.exp.X_add_number > 7)		    losing++;		  break;		case 'U':		  if (opP->mode != CONTROL || opP->reg != USP)		    losing++;		  break;		  /* JF these are out of order.  We could put them		     in order if we were willing to put up with		     bunches of #ifdef m68851s in the code.		     Don't forget that you need these operands		     to use 68030 MMU instructions.  */#ifndef NO_68851		  /* Memory addressing mode used by pflushr */		case '|':		  if (opP->mode == CONTROL		      || opP->mode == FPREG		      || opP->mode == DREG		      || opP->mode == AREG		      || opP->mode == REGLST)		    losing++;		  /* We should accept immediate operands, but they                     supposedly have to be quad word, and we don't                     handle that.  I would like to see what a Motorola                     assembler does before doing something here.  */		  if (opP->mode == IMMED)		    losing++;		  break;		case 'f':		  if (opP->mode != CONTROL		      || (opP->reg != SFC && opP->reg != DFC))		    losing++;		  break;		case '0':		  if (opP->mode != CONTROL || opP->reg != TC)		    losing++;		  break;		case '1':		  if (opP->mode != CONTROL || opP->reg != AC)		    losing++;		  break;		case '2':		  if (opP->mode != CONTROL		      || (opP->reg != CAL			  && opP->reg != VAL			  && opP->reg != SCC))		    losing++;		  break;		case 'V':		  if (opP->mode != CONTROL		      || opP->reg != VAL)		    losing++;		  break;		case 'W':		  if (opP->mode != CONTROL		      || (opP->reg != DRP			  && opP->reg != SRP			  && opP->reg != CRP))		    losing++;		  break;		case 'X':		  if (opP->mode != CONTROL		      || (!(opP->reg >= BAD && opP->reg <= BAD + 7)			  && !(opP->reg >= BAC && opP->reg <= BAC + 7)))		    losing++;		  break;		case 'Y':		  if (opP->mode != CONTROL || opP->reg != PSR)		    losing++;		  break;		case 'Z':		  if (opP->mode != CONTROL || opP->reg != PCSR)		    losing++;		  break;#endif		case 'c':		  if (opP->mode != CONTROL		      || (opP->reg != NC			  && opP->reg != IC			  && opP->reg != DC			  && opP->reg != BC))		    {		      losing++;		    }		/* not a cache specifier.  */		  break;		case '_':		  if (opP->mode != ABSL)		    ++losing;		  break;		case 'u':		  if (opP->reg < DATA0L || opP->reg > ADDR7U)		    losing++;		  /* FIXME: kludge instead of fixing parser:                     upper/lower registers are *not* CONTROL                     registers, but ordinary ones.  */		  if ((opP->reg >= DATA0L && opP->reg <= DATA7L)		      || (opP->reg >= DATA0U && opP->reg <= DATA7U))		    opP->mode = DREG;		  else		    opP->mode = AREG;		  break;		default:		  abort ();		}		/* switch on type of operand */	      if (losing)		break;	    }			/* for each operand */	}			/* if immediately wrong */      if (!losing)	{	  break;	}			/* got it.  */      opcode = opcode->m_next;      if (!opcode)	{	  if (ok_arch	      && !(ok_arch & current_architecture))	    {	      char buf[200], *cp;	      strcpy (buf,		      _("invalid instruction for this architecture; needs "));	      cp = buf + strlen (buf);	      switch (ok_arch)		{		case mfloat:		  strcpy (cp, _("fpu (68040, 68060 or 68881/68882)"));		  break;		case mmmu:		  strcpy (cp, _("mmu (68030 or 68851)"));		  break;		case m68020up:		  strcpy (cp, _("68020 or higher"));		  break;		case m68000up:		  strcpy (cp, _("68000 or higher"));		  break;		case m68010up:		  strcpy (cp, _("68010 or higher"));		  break;		default:		  {		    int got_one = 0, idx;		    for (idx = 0;			 idx < (int) (sizeof (archs) / sizeof (archs[0]));			 idx++)		      {			if ((archs[idx].arch & ok_arch)			    && ! archs[idx].alias)			  {			    if (got_one)			      {				strcpy (cp, " or ");				cp += strlen (cp);			      }			    got_one = 1;			    strcpy (cp, archs[idx].name);			    cp += strlen (cp);			  }		      }		  }		}	      cp = xmalloc (strlen (buf) + 1);	      strcpy (cp, buf);	      the_ins.error = cp;	    }	  else	    the_ins.error = _("operands mismatch");	  return;	}			/* Fell off the end */      losing = 0;    }  /* now assemble it */  the_ins.args = opcode->m_operands;  the_ins.numargs = opcode->m_opnum;  the_ins.numo = opcode->m_codenum;  the_ins.opcode[0] = getone (opcode);  the_ins.opcode[1] = gettwo (opcode);  for (s = the_ins.args, opP = &the_ins.operands[0]; *s; s += 2, opP++)    {      /* This switch is a doozy.       Watch the first step; its a big one! */      switch (s[0])	{	case '*':	case '~':	case '%':	case ';':	case '@':	case '!':	case '&':	case '$':	case '?':	case '/':	case '<':	case '>':	case 'm':	case 'n':	case 'o':	case 'p':	case 'q':	case 'v':#ifndef NO_68851	case '|':#endif	  switch (opP->mode)	    {	    case IMMED:	      tmpreg = 0x3c;	/* 7.4 */	      if (strchr ("bwl", s[1]))		nextword = get_num (&opP->disp, 80);	      else		nextword = get_num (&opP->disp, 0);	      if (isvar (&opP->disp))		add_fix (s[1], &opP->disp, 0, 0);	      switch (s[1])		{		case 'b':		  if (!isbyte (nextword))		    opP->error = _("operand out of range");		  addword (nextword);		  baseo = 0;		  break;		case 'w':		  if (!isword (nextword))		    opP->error = _("operand out of range");		  addword (nextword);		  baseo = 0;		  break;		case 'W':		  if (!issword (nextword))		    opP->error = _("operand out of range");		  addword (nextword);		  baseo = 0;		  break;		case 'l':		  addword (nextword >> 16);		  addword (nextword);		  baseo = 0;		  break;		case 'f':		  baseo = 2;		  outro = 8;		  break;		case 'F':		  baseo = 4;		  outro = 11;		  break;		case 'x':		  baseo = 6;		  outro = 15;		  break;		case 'p':		  baseo = 6;		  outro = -1;		  break;		default:		  abort ();		}	      if (!baseo)		break;	      /* We gotta put out some float */	      if (op (&opP->disp) != O_big)		{		  valueT val;		  int gencnt;		  /* Can other cases happen here?  */		  if (op (&opP->disp) != O_constant)		    abort ();		  val = (valueT) offs (&opP->disp);		  gencnt = 0;		  do		    {		      generic_bignum[gencnt] = (LITTLENUM_TYPE) val;		      val >>= LITTLENUM_NUMBER_OF_BITS;		      ++gencnt;		    }		  while (val != 0);		  offs (&opP->disp) = gencnt;		}	      if (offs (&opP->disp) > 0)		{		  if (offs (&opP->disp) > baseo)		    {		      as_warn (_("Bignum too big for %c format; truncated"),			       s[1]);		      offs (&opP->disp) = baseo;		    }		  baseo -= offs (&opP->disp);		  while (baseo--)		    addword (0);		  for (wordp = generic_bignum + offs (&opP->disp) - 1;		       offs (&opP->disp)--;		       --wordp)		    addword (*wordp);		  break;		}	      gen_to_words (words, baseo, (long) outro);	      for (wordp = words; baseo--; wordp++)		addword (*wordp);	      break;	    case DREG:	      tmpreg = opP->reg - DATA;	/* 0.dreg */	      break;	    case AREG:	      tmpreg = 0x08 + opP->reg - ADDR;	/* 1.areg */	      break;	    case AINDR:	      tmpreg = 0x10 + opP->reg - ADDR;	/* 2.areg */	      break;	    case ADEC:	      tmpreg = 0x20 + opP->reg - ADDR;	/* 4.areg */	      break;	    case AINC:	      tmpreg = 0x18 + opP->reg - ADDR;	/* 3.areg */	      break;	    case DISP:	      nextword = get_num (&opP->disp, 80);	      if (opP->reg == PC		  && ! isvar (&opP->disp)		  && m68k_abspcadd)		{		  opP->disp.exp.X_op = O_symbol;#ifndef BFD_ASSEMBLER		  opP->disp.exp.X_add_symbol = &abs_symbol;#else		  opP->disp.exp.X_add_symbol =		    section_symbol (absolute_section);#endif		}	      /* Force into index mode.  Hope this works */	      /* We do the first bit for 32-bit displacements, and the		 second bit for 16 bit ones.  It is possible that we		 should make the default be WORD instead of LONG, but		 I think that'd break GCC, so we put up with a little		 inefficiency for the sake of working output.  */	      if (!issword (nextword)		  || (isvar (&opP->disp)		      && ((opP->disp.size == SIZE_UNSPEC			   && flag_short_refs == 0			   && cpu_of_arch (current_architecture) >= m68020			   && ! arch_coldfire_p (current_architecture))			  || opP->disp.size == SIZE_LONG)))		{		  if (cpu_of_arch (current_architecture) < m68020		      || arch_coldfire_p (current_architecture))		    opP->error =		      _("displacement too large for this architecture; needs 68020 or higher");		  if (opP->reg == PC)		    tmpreg = 0x3B;	/* 7.3 */		  else		    tmpreg = 0x30 + opP->reg - ADDR;	/* 6.areg */		  if (isvar (&opP->disp))		    {		      if (opP->reg == PC)			{			  if (opP->disp.size == SIZE_LONG#ifdef OBJ_ELF			      /* If the displacement needs pic				 relocation it cannot be relaxed.  */			      || opP->disp.pic_reloc != pic_none#endif			      )			    {			      addword (0x0170);			      add_fix ('l', &opP->disp, 1, 2);			    }			  else			    {			      add_frag (adds (&opP->disp),					offs (&opP->disp),					TAB (PCREL1632, SZ_UNDEF));			      break;			    }			}		      else			{			  addword (0x0170);			  add_fix ('l', &opP->disp, 0, 0);			}		    }		  else		    addword (0x0170);		  addword (nextword >> 16);		}	      else		{

⌨️ 快捷键说明

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