&& subs (&opP->disp) == NULL)
&& subs (&opP->disp) == NULL #ifdef OBJ_ELF  && opP->disp.pic_reloc == pic_none #endif )
m68k_ip (instring)     char *instring;{  register char *p;  register struct m68k_op *opP;  register struct m68k_incant *opcode;  register const char *s;  register int tmpreg = 0, baseo = 0, outro = 0, nextword;  char *pdot, *pdotmove;  enum m68k_size siz1, siz2;  char c;  int losing;  int opsfound;  char *crack_operand ();  LITTLENUM_TYPE words[6];  LITTLENUM_TYPE *wordp;  unsigned long ok_arch = 0;  if (*instring == ' ')    instring++;			/* skip leading whitespace */  /* Scan up to end of operation-code, which MUST end in end-of-string     or exactly 1 space. */  pdot = 0;  for (p = instring; *p != '\0'; p++)    {      if (*p == ' ')	break;      if (*p == '.')	pdot = p;    }  if (p == instring)    {      the_ins.error = "No operator";      return;    }  /* p now points to the end of the opcode name, probably whitespace.     Make sure the name is null terminated by clobbering the     whitespace, look it up in the hash table, then fix it back.     Remove a dot, first, since the opcode tables have none.  */  if (pdot != NULL)    {      for (pdotmove = pdot; pdotmove < p; pdotmove++)	*pdotmove = pdotmove[1];      p--;    }  c = *p;  *p = '\0';  opcode = (struct m68k_incant *) hash_find (op_hash, instring);  *p = c;  if (pdot != NULL)    {      for (pdotmove = p; pdotmove > pdot; pdotmove--)	*pdotmove = pdotmove[-1];      *pdot = '.';      ++p;    }  if (opcode == NULL)    {      the_ins.error = "Unknown operator";      return;    }  /* found a legitimate opcode, start matching operands */  while (*p == ' ')    ++p;  if (opcode->m_operands == 0)    {      char *old = input_line_pointer;      *old = '\n';      input_line_pointer = p;      /* Ahh - it's a motorola style psuedo op */      mote_pseudo_table[opcode->m_opnum].poc_handler	(mote_pseudo_table[opcode->m_opnum].poc_val);      input_line_pointer = old;      *old = 0;      return;    }  if (flag_mri && opcode->m_opnum == 0)    {      /* In MRI mode, random garbage is allowed after an instruction         which accepts no operands.  */      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);      return;    }  for (opP = &the_ins.operands[0]; *p; opP++)    {      p = crack_operand (p, opP);      if (opP->error)	{	  the_ins.error = opP->error;	  return;	}    }  opsfound = opP - &the_ins.operands[0];  /* This ugly hack is to support the floating pt opcodes in their     standard form.  Essentially, we fake a first enty of type COP#1 */  if (opcode->m_operands[0] == 'I')    {      int n;      for (n = opsfound; n > 0; --n)	the_ins.operands[n] = the_ins.operands[n - 1];      memset ((char *) (&the_ins.operands[0]), '\0',	      sizeof (the_ins.operands[0]));      the_ins.operands[0].mode = CONTROL;      the_ins.operands[0].reg = m68k_float_copnum;      opsfound++;    }  /* We've got the operands.  Find an opcode that'll accept them */  for (losing = 0;;)    {      /* If we didn't get the right number of ops, or we have no	 common model with this pattern then reject this pattern. */      if (opsfound != opcode->m_opnum	  || ((opcode->m_arch & current_architecture) == 0))	{	  ++losing;	  ok_arch |= opcode->m_arch;	}      else	{	  for (s = opcode->m_operands, opP = &the_ins.operands[0];	       *s && !losing;	       s += 2, opP++)	    {	      /* Warning: this switch is huge! */	      /* I've tried to organize the cases into this order:		 non-alpha first, then alpha by letter.  Lower-case		 goes directly before uppercase counterpart.  */	      /* Code with multiple case ...: gets sorted by the lowest		 case ... it belongs to.  I hope this makes sense.  */	      switch (*s)		{		case '!':		  switch (opP->mode)		    {		    case IMMED:		    case DREG:		    case AREG:		    case FPREG:		    case CONTROL:		    case AINC:		    case ADEC:		    case REGLST:		      losing++;		      break;		    default:		      break;		    }		  break;		case '`':		  switch (opP->mode)		    {		    case IMMED:		    case DREG:		    case AREG:		    case FPREG:		    case CONTROL:		    case AINC:		    case REGLST:		    case AINDR:		      losing++;		      break;		    default:		      break;		    }		  break;		case '#':		  if (opP->mode != IMMED)		    losing++;		  else if (s[1] == 'b'			   && ! isvar (&opP->disp)			   && (opP->disp.exp.X_op != O_constant			       || ! isbyte (opP->disp.exp.X_add_number)))		    losing++;		  else if (s[1] == 'w'			   && ! isvar (&opP->disp)			   && (opP->disp.exp.X_op != O_constant			       || ! isword (opP->disp.exp.X_add_number)))		    losing++;		  else if (s[1] == 'W'			   && ! isvar (&opP->disp)			   && (opP->disp.exp.X_op != O_constant			       || ! issword (opP->disp.exp.X_add_number)))		    losing++;		  break;		case '^':		case 'T':		  if (opP->mode != IMMED)		    losing++;		  break;		case '$':		  if (opP->mode == AREG		      || opP->mode == CONTROL		      || opP->mode == FPREG		      || opP->mode == IMMED		      || opP->mode == REGLST		      || (opP->mode != ABSL			  && (opP->reg == PC			      || opP->reg == ZPC)))		    losing++;		  break;		case '%':		  if (opP->mode == CONTROL		      || opP->mode == FPREG		      || opP->mode == REGLST		      || opP->mode == IMMED		      || (opP->mode != ABSL			  && (opP->reg == PC			      || opP->reg == ZPC)))		    losing++;		  break;		case '&':		  switch (opP->mode)		    {		    case DREG:		    case AREG:		    case FPREG:		    case CONTROL:		    case IMMED:		    case AINC:		    case ADEC:		    case REGLST:		      losing++;		      break;		    case ABSL:		      break;		    default:		      if (opP->reg == PC			  || opP->reg == ZPC)			losing++;		      break;		    }		  break;		case '*':		  if (opP->mode == CONTROL		      || opP->mode == FPREG		      || opP->mode == REGLST)		    losing++;		  break;		case '+':		  if (opP->mode != AINC)		    losing++;		  break;		case '-':		  if (opP->mode != ADEC)		    losing++;		  break;		case '/':		  switch (opP->mode)		    {		    case AREG:		    case CONTROL:		    case FPREG:		    case AINC:		    case ADEC:		    case IMMED:		    case REGLST:		      losing++;		      break;		    default:		      break;		    }		  break;		case ';':		  switch (opP->mode)		    {		    case AREG:		    case CONTROL:		    case FPREG:		    case REGLST:		      losing++;		      break;		    default:		      break;		    }		  break;		case '?':		  switch (opP->mode)		    {		    case AREG:		    case CONTROL:		    case FPREG:		    case AINC:		    case ADEC:		    case IMMED:		    case REGLST:		      losing++;		      break;		    case ABSL:		      break;		    default:		      if (opP->reg == PC || opP->reg == ZPC)			losing++;		      break;		    }		  break;		case '@':		  switch (opP->mode)		    {		    case AREG:		    case CONTROL:		    case FPREG:		    case IMMED:		    case REGLST:		      losing++;		      break;		    default:		      break;		    }		  break;		case '~':	/* For now! (JF FOO is this right?) */		  switch (opP->mode)		    {		    case DREG:		    case AREG:		    case CONTROL:		    case FPREG:		    case IMMED:		    case REGLST:		      losing++;		      break;		    case ABSL:		      break;		    default:		      if (opP->reg == PC			  || opP->reg == ZPC)			losing++;		      break;		    }		  break;		case '3':		  if (opP->mode != CONTROL		      || (opP->reg != TT0 && opP->reg != TT1))		    losing++;		  break;		case 'A':		  if (opP->mode != AREG)		    losing++;		  break;		case 'a':		  if (opP->mode != AINDR)		    ++losing;		  break;		case 'B':	/* FOO */		  if (opP->mode != ABSL		      || (flag_long_jumps			  && strncmp (instring, "jbsr", 4) == 0))		    losing++;		  break;		case 'C':		  if (opP->mode != CONTROL || opP->reg != CCR)		    losing++;		  break;		case 'd':		  if (opP->mode != DISP		      || opP->reg < ADDR0		      || opP->reg > ADDR7)		    losing++;		  break;		case 'D':		  if (opP->mode != DREG)		    losing++;		  break;		case 'F':		  if (opP->mode != FPREG)		    losing++;		  break;		case 'I':		  if (opP->mode != CONTROL		      || opP->reg < COP0		      || opP->reg > COP7)		    losing++;		  break;		case 'J':		  if (opP->mode != CONTROL		      || opP->reg < USP		      || opP->reg > last_movec_reg)		    losing++;		  else		    {		      const enum m68k_register *rp;		      for (rp = control_regs; *rp; rp++)			if (*rp == opP->reg)			  break;		      if (*rp == 0)			losing++;		    }		  break;		case 'k':		  if (opP->mode != IMMED)		    losing++;		  break;		case 'l':		case 'L':		  if (opP->mode == DREG		      || opP->mode == AREG		      || opP->mode == FPREG)		    {		      if (s[1] == '8')			losing++;		      else			{			  switch (opP->mode)			    {			    case DREG:			      opP->mask = 1 << (opP->reg - DATA0);			      break;			    case AREG:			      opP->mask = 1 << (opP->reg - ADDR0 + 8);			      break;			    case FPREG:			      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 == ABSL			   && opP->disp.size == SIZE_UNSPEC			   && opP->disp.exp.X_op == O_constant)		    {		      /* This is what the MRI REG pseudo-op generates.  */		      opP->mode = REGLST;		      opP->mask = opP->disp.exp.X_add_number;		    }		  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)		    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;		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;	      int len;	      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 < sizeof (archs) / sizeof (archs[0]);			 idx++)		      {			if (archs[idx].arch & ok_arch)			  {			    if (got_one)			      {				strcpy (cp, " or ");				cp += strlen (cp);			      }			    got_one = 1;			    strcpy (cp, archs[idx].name);			    cp += strlen (cp);			  }		      }		  }		}	      len = cp - buf + 1;	      cp = malloc (len);	      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 '`':#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)			  || opP->disp.size == SIZE_LONG)))		{		  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 0			  addword (0x0170);			  add_fix ('l', &opP->disp, 1, 2);			  addword (0), addword (0);#else			  add_frag (adds (&opP->disp),				    offs (&opP->disp),				    TAB (PCLEA, SZ_UNDEF));#endif			  break;			}		      else			{			  addword (0x0170);			  add_fix ('l', &opP->disp, 0, 0);			}		    }		  else		    addword (0x0170);		  addword (nextword >> 16);		}	      else		{		  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_UNSPEC		      || opP->index.size == SIZE_LONG)		    nextword |= 0x800;		  if (cpu_of_arch (current_architecture) < m68020)		    {		      if (opP->index.scale != 1)			{			  opP->error =			    "scale factor invalid on this architecture; needs 68020 or higher";			}		    }		  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			  || (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)			{ 			  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)		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)		{		  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;		    }		  /* Don't generate pc relative code on 68010 and		     68000.  */		  if (isvar (&opP->disp)		      && !subs (&opP->disp)		      && adds (&opP->disp)		      && S_GET_SEGMENT (adds (&opP->disp)) == now_seg		      && cpu_of_arch (current_architecture) >= m68020		      && !flag_long_jumps		      && !strchr ("~%&$?", s[0]))		    {		      tmpreg = 0x3A;	/* 7.2 */		      add_frag (adds (&opP->disp),				offs (&opP->disp),				TAB (PCREL, 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_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;	      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':	      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':	      /* The pc_fix argument winds up in fx_pcrel_adjust,                 which is a char, and may therefore be unsigned.  We                 want to pass -1, but we pass 64 instead, and convert                 back in md_pcrel_from.  */	      add_fix ('B', &opP->disp, 1, 64);	      break;	    case 'W':	      add_fix ('w', &opP->disp, 1, 0);	      addword (0);	      break;	    case 'L':	    long_branch:	      if (cpu_of_arch (current_architecture) < m68020)		as_warn ("Can't use long branches on 68000/68010");	      the_ins.opcode[the_ins.numo - 1] |= 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;	      /* This could either be a symbol, or an absolute		 address.  No matter, the frag hacking will finger it		 out.  Not quite: it can't switch from BRANCH to		 BCC68000 for the case where opnd is absolute (it		 needs to use the 68000 hack since no conditional abs		 jumps).  */	      if (((cpu_of_arch (current_architecture) < m68020)		   || (0 == adds (&opP->disp)))		  && (the_ins.opcode[0] >= 0x6200)		  && (the_ins.opcode[0] <= 0x6f00))		add_frag (adds (&opP->disp), offs (&opP->disp),			  TAB (BCC68000, SZ_UNDEF));	      else		add_frag (adds (&opP->disp), offs (&opP->disp),			  TAB (ABRANCH, SZ_UNDEF));	      break;	    case 'w':	      if (isvar (&opP->disp))		{#if 1		  /* check for DBcc instruction */		  if ((the_ins.opcode[0] & 0xf0f8) == 0x50c8)		    {		      /* size varies if patch */		      /* needed for long form */		      add_frag (adds (&opP->disp), offs (&opP->disp),				TAB (DBCC, SZ_UNDEF));		      break;		    }#endif		  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))		{		  add_fix ('l', &opP->disp, 1, 0);		  add_frag ((symbolS *) 0, (long) 0, TAB (FBRANCH, LONG));		}	      else if (adds (&opP->disp))		add_frag (adds (&opP->disp), offs (&opP->disp),			  TAB (FBRANCH, SZ_UNDEF));	      else		{		  /* add_frag((symbolS *) 0, offs(&opP->disp),		     TAB(FBRANCH,SHORT)); */		  the_ins.opcode[the_ins.numo - 1] |= 0x40;		  add_fix ('l', &opP->disp, 1, 0);		  addword (0);		  addword (0);		}	      break;	    default:	      abort ();	    }	  break;	case 'C':		/* Ignore it */	  break;	case 'd':		/* JF this is a kludge */	  install_operand ('s', opP->reg - ADDR);	  tmpreg = get_num (&opP->disp, 80);	  if (!issword (tmpreg))	    {	      as_warn ("Expression out of range, using 0");	      tmpreg = 0;	    }	  addword (tmpreg);	  break;	case 'D':	  install_operand (s[1], opP->reg - DATA);	  break;	case 'F':	  install_operand (s[1], opP->reg - FP0);	  break;	case 'I':	  tmpreg = opP->reg - COP0;	  install_operand (s[1], tmpreg);	  break;	case 'J':		/* JF foo */	  switch (opP->reg)	    {	    case SFC:	      tmpreg = 0x000;	      break;	    case DFC:	      tmpreg = 0x001;	      break;	    case CACR:	      tmpreg = 0x002;	      break;	    case TC:	      tmpreg = 0x003;	      break;	    case ITT0:	      tmpreg = 0x004;	      break;	    case ITT1:	      tmpreg = 0x005;	      break;	    case DTT0:	      tmpreg = 0x006;	      break;	    case DTT1:	      tmpreg = 0x007;	      break;	    case BUSCR:	      tmpreg = 0x008;	      break;	    case USP:	      tmpreg = 0x800;	      break;	    case VBR:	      tmpreg = 0x801;	      break;	    case CAAR:	      tmpreg = 0x802;	      break;	    case MSP:	      tmpreg = 0x803;	      break;	    case ISP:	      tmpreg = 0x804;	      break;	    case MMUSR:	      tmpreg = 0x805;	      break;	    case URP:	      tmpreg = 0x806;	      break;	    case SRP:	      tmpreg = 0x807;	      break;	    case PCR:	      tmpreg = 0x808;	      break;	    default:	      abort ();	    }	  install_operand (s[1], tmpreg);	  break;	case 'k':	  tmpreg = get_num (&opP->disp, 55);	  install_operand (s[1], tmpreg & 0x7f);	  break;	case 'l':	  tmpreg = opP->mask;	  if (s[1] == 'w')	    {	      if (tmpreg & 0x7FF0000)		as_bad ("Floating point register in register list");	      insop (reverse_16_bits (tmpreg), opcode);	    }	  else	    {	      if (tmpreg & 0x700FFFF)		as_bad ("Wrong register in floating-point reglist");	      install_operand (s[1], reverse_8_bits (tmpreg >> 16));	    }	  break;	case 'L':	  tmpreg = opP->mask;	  if (s[1] == 'w')	    {	      if (tmpreg & 0x7FF0000)		as_bad ("Floating point register in register list");	      insop (tmpreg, opcode);	    }	  else if (s[1] == '8')	    {	      if (tmpreg & 0x0FFFFFF)		as_bad ("incorrect register in reglist");	      install_operand (s[1], tmpreg >> 24);	    }	  else	    {	      if (tmpreg & 0x700FFFF)		as_bad ("wrong register in floating-point reglist");	      else		install_operand (s[1], tmpreg >> 16);	    }	  break;	case 'M':	  install_operand (s[1], get_num (&opP->disp, 60));	  break;	case 'O':	  tmpreg = ((opP->mode == DREG)		    ? 0x20 + opP->reg - DATA		    : (get_num (&opP->disp, 40) & 0x1F));	  install_operand (s[1], tmpreg);	  break;	case 'Q':	  tmpreg = get_num (&opP->disp, 10);	  if (tmpreg == 8)	    tmpreg = 0;	  install_operand (s[1], tmpreg);	  break;	case 'R':	  /* This depends on the fact that ADDR registers are eight	     more than their corresponding DATA regs, so the result	     will have the ADDR_REG bit set */	  install_operand (s[1], opP->reg - DATA);	  break;	case 'r':	  if (opP->mode == AINDR)	    install_operand (s[1], opP->reg - DATA);	  else	    install_operand (s[1], opP->index.reg - DATA);	  break;	case 's':	  if (opP->reg == FPI)	    tmpreg = 0x1;	  else if (opP->reg == FPS)	    tmpreg = 0x2;	  else if (opP->reg == FPC)	    tmpreg = 0x4;	  else	    abort ();	  install_operand (s[1], tmpreg);	  break;	case 'S':		/* Ignore it */	  break;	case 'T':	  install_operand (s[1], get_num (&opP->disp, 30));	  break;	case 'U':		/* Ignore it */	  break;	case 'c':	  switch (opP->reg)	    {	    case NC:	      tmpreg = 0;	      break;	    case DC:	      tmpreg = 1;	      break;	    case IC:	      tmpreg = 2;	      break;	    case BC:	      tmpreg = 3;	      break;	    default:	      as_fatal ("failed sanity check");	    }			/* switch on cache token */	  install_operand (s[1], tmpreg);	  break;#ifndef NO_68851	  /* JF: These are out of order, I fear. */	case 'f':	  switch (opP->reg)	    {	    case SFC:	      tmpreg = 0;	      break;	    case DFC:	      tmpreg = 1;	      break;	    default:	      abort ();	    }	  install_operand (s[1], tmpreg);	  break;	case '0':	case '1':	case '2':	  switch (opP->reg)	    {	    case TC:	      tmpreg = 0;	      break;	    case CAL:	      tmpreg = 4;	      break;	    case VAL:	      tmpreg = 5;	      break;	    case SCC:	      tmpreg = 6;	      break;	    case AC:	      tmpreg = 7;	      break;	    default:	      abort ();	    }	  install_operand (s[1], tmpreg);	  break;	case 'V':	  if (opP->reg == VAL)	    break;	  abort ();	case 'W':	  switch (opP->reg)	    {	    case DRP:	      tmpreg = 1;	      break;	    case SRP:	      tmpreg = 2;	      break;	    case CRP:	      tmpreg = 3;	      break;	    default:	      abort ();	    }	  install_operand (s[1], tmpreg);	  break;	case 'X':	  switch (opP->reg)	    {	    case BAD:	    case BAD + 1:	    case BAD + 2:	    case BAD + 3:	    case BAD + 4:	    case BAD + 5:	    case BAD + 6:	    case BAD + 7:	      tmpreg = (4 << 10) | ((opP->reg - BAD) << 2);	      break;	    case BAC:	    case BAC + 1:	    case BAC + 2:	    case BAC + 3:	    case BAC + 4:	    case BAC + 5:	    case BAC + 6:	    case BAC + 7:	      tmpreg = (5 << 10) | ((opP->reg - BAC) << 2);	      break;	    default:	      abort ();	    }	  install_operand (s[1], tmpreg);	  break;	case 'Y':	  know (opP->reg == PSR);	  break;	case 'Z':	  know (opP->reg == PCSR);	  break;#endif /* m68851 */	case '3':	  switch (opP->reg)	    {	    case TT0:	      tmpreg = 2;	      break;	    case TT1:	      tmpreg = 3;	      break;	    default:	      abort ();	    }	  install_operand (s[1], tmpreg);	  break;	case 't':	  tmpreg = get_num (&opP->disp, 20);	  install_operand (s[1], tmpreg);	  break;	case '_':	/* used only for move16 absolute 32-bit address */	  tmpreg = get_num (&opP->disp, 80);	  addword (tmpreg >> 16);	  addword (tmpreg & 0xFFFF);	  break;	default:	  abort ();	}    }  /* By the time whe get here (FINALLY) the_ins contains the complete     instruction, ready to be emitted. . . */}