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

📄 tc-h8300.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 3 页
字号:
	  if (*src != ')' && '(')	    {	      as_bad (_("expected @(exp, reg16)"));	      return;	    }	  *ptr = src + 1;	  return;	}      len = parse_reg (src, &mode, &num, direction);      if (len)	{	  src += len;	  if (*src == '+')	    {	      src++;	      if ((mode & SIZE) != PSIZE)		as_bad (_("Wrong size pointer register for architecture."));	      op->mode = RSINC;	      op->reg = num;	      *ptr = src;	      return;	    }	  if ((mode & SIZE) != PSIZE)	    as_bad (_("Wrong size pointer register for architecture."));	  op->mode = direction | IND | PSIZE;	  op->reg = num;	  *ptr = src;	  return;	}      else	{	  /* must be a symbol */	  op->mode = ABS | direction;	  src = parse_exp (src, &op->exp);	  *ptr = colonmod24 (op, src);	  return;	}    }  if (*src == '#')    {      src++;      op->mode = IMM;      src = parse_exp (src, &op->exp);      *ptr = skip_colonthing (src, &op->exp, &op->mode);      return;    }  else if (strncmp (src, "mach", 4) == 0	   || strncmp (src, "macl", 4) == 0)    {      op->reg = src[3] == 'l';      op->mode = MACREG;      *ptr = src + 4;      return;    }  else    {      src = parse_exp (src, &op->exp);      /* Trailing ':' size ? */      if (*src == ':')	{	  if (src[1] == '1' && src[2] == '6')	    {	      op->mode = PCREL | L_16;	      src += 3;	    }	  else if (src[1] == '8')	    {	      op->mode = PCREL | L_8;	      src += 2;	    }	  else	    {	      as_bad (_("expect :8 or :16 here"));	    }	}      else	{	  op->mode = PCREL | bsize;	}      *ptr = src;    }}static char *get_operands (noperands, op_end, operand)     unsigned int noperands;     char *op_end;     struct h8_op *operand;{  char *ptr = op_end;  switch (noperands)    {    case 0:      operand[0].mode = 0;      operand[1].mode = 0;      break;    case 1:      ptr++;      get_operand (&ptr, operand + 0, 0, SRC);      if (*ptr == ',')	{	  ptr++;	  get_operand (&ptr, operand + 1, 1, DST);	}      else	{	  operand[1].mode = 0;	}      break;    case 2:      ptr++;      get_operand (&ptr, operand + 0, 0, SRC);      if (*ptr == ',')	ptr++;      get_operand (&ptr, operand + 1, 1, DST);      break;    default:      abort ();    }  return ptr;}/* Passed a pointer to a list of opcodes which use different   addressing modes, return the opcode which matches the opcodes   provided.  */static struct h8_opcode *get_specific (opcode, operands, size)     struct h8_opcode *opcode;     struct h8_op *operands;     int size;{  struct h8_opcode *this_try = opcode;  int found = 0;  unsigned int this_index = opcode->idx;  /* There's only one ldm/stm and it's easier to just     get out quick for them.  */  if (strcmp (opcode->name, "stm.l") == 0      || strcmp (opcode->name, "ldm.l") == 0)    return this_try;  while (this_index == opcode->idx && !found)    {      found = 1;      this_try = opcode++;      if (this_try->noperands == 0)	{	  int this_size;	  this_size = this_try->how & SN;	  if (this_size != size && (this_size != SB || size != SN))	    found = 0;	}      else	{	  unsigned int i;	  for (i = 0; i < this_try->noperands && found; i++)	    {	      op_type op = this_try->args.nib[i];	      int x = operands[i].mode;	      if ((op & (DISP | REG)) == (DISP | REG)		  && ((x & (DISP | REG)) == (DISP | REG)))		{		  dispreg = operands[i].reg;		}	      else if (op & REG)		{		  if (!(x & REG))		    found = 0;		  if (x & L_P)		    x = (x & ~L_P) | (Hmode ? L_32 : L_16);		  if (op & L_P)		    op = (op & ~L_P) | (Hmode ? L_32 : L_16);		  opsize = op & SIZE;		  /* The size of the reg is v important.  */		  if ((op & SIZE) != (x & SIZE))		    found = 0;		}	      else if ((op & ABSJMP) && (x & ABS))		{		  operands[i].mode &= ~ABS;		  operands[i].mode |= ABSJMP;		  /* But it may not be 24 bits long.  */		  if (!Hmode)		    {		      operands[i].mode &= ~SIZE;		      operands[i].mode |= L_16;		    }		}	      else if ((op & (KBIT | DBIT)) && (x & IMM))		{		  /* This is ok if the immediate value is sensible.  */		}	      else if (op & PCREL)		{		  /* The size of the displacement is important.  */		  if ((op & SIZE) != (x & SIZE))		    found = 0;		}	      else if ((op & (DISP | IMM | ABS))		       && (op & (DISP | IMM | ABS)) == (x & (DISP | IMM | ABS)))		{		  /* Promote a L_24 to L_32 if it makes us match.  */		  if ((x & L_24) && (op & L_32))		    {		      x &= ~L_24;		      x |= L_32;		    }		  /* Promote an L8 to L_16 if it makes us match.  */		  if (op & ABS && op & L_8 && op & DISP)		    {		      if (x & L_16)			found = 1;		    }		  else if ((x & SIZE) != 0			   && ((op & SIZE) != (x & SIZE)))		    found = 0;		}	      else if ((op & MACREG) != (x & MACREG))		{		  found = 0;		}	      else if ((op & MODE) != (x & MODE))		{		  found = 0;		}	    }	}    }  if (found)    return this_try;  else    return 0;}static voidcheck_operand (operand, width, string)     struct h8_op *operand;     unsigned int width;     char *string;{  if (operand->exp.X_add_symbol == 0      && operand->exp.X_op_symbol == 0)    {      /* No symbol involved, let's look at offset, it's dangerous if	 any of the high bits are not 0 or ff's, find out by oring or	 anding with the width and seeing if the answer is 0 or all	 fs.  */      if ((operand->exp.X_add_number & ~width) != 0 &&	  (operand->exp.X_add_number | width) != (~0))	{	  if (width == 255	      && (operand->exp.X_add_number & 0xff00) == 0xff00)	    {	      /* Just ignore this one - which happens when trying to		 fit a 16 bit address truncated into an 8 bit address		 of something like bset.  */	    }	  else	    {	      as_warn (_("operand %s0x%lx out of range."), string,		       (unsigned long) operand->exp.X_add_number);	    }	}    }}/* RELAXMODE has one of 3 values:   0 Output a "normal" reloc, no relaxing possible for this insn/reloc   1 Output a relaxable 24bit absolute mov.w address relocation     (may relax into a 16bit absolute address).   2 Output a relaxable 16/24 absolute mov.b address relocation     (may relax into an 8bit absolute address).  */static voiddo_a_fix_imm (offset, operand, relaxmode)     int offset;     struct h8_op *operand;     int relaxmode;{  int idx;  int size;  int where;  char *t = operand->mode & IMM ? "#" : "@";  if (operand->exp.X_add_symbol == 0)    {      char *bytes = frag_now->fr_literal + offset;      switch (operand->mode & SIZE)	{	case L_2:	  check_operand (operand, 0x3, t);	  bytes[0] |= (operand->exp.X_add_number) << 4;	  break;	case L_3:	  check_operand (operand, 0x7, t);	  bytes[0] |= (operand->exp.X_add_number) << 4;	  break;	case L_8:	  check_operand (operand, 0xff, t);	  bytes[0] = operand->exp.X_add_number;	  break;	case L_16:	  check_operand (operand, 0xffff, t);	  bytes[0] = operand->exp.X_add_number >> 8;	  bytes[1] = operand->exp.X_add_number >> 0;	  break;	case L_24:	  check_operand (operand, 0xffffff, t);	  bytes[0] = operand->exp.X_add_number >> 16;	  bytes[1] = operand->exp.X_add_number >> 8;	  bytes[2] = operand->exp.X_add_number >> 0;	  break;	case L_32:	  /* This should be done with bfd.  */	  bytes[0] = operand->exp.X_add_number >> 24;	  bytes[1] = operand->exp.X_add_number >> 16;	  bytes[2] = operand->exp.X_add_number >> 8;	  bytes[3] = operand->exp.X_add_number >> 0;	  if (relaxmode != 0)	    {	      idx = (relaxmode == 2) ? R_MOV24B1 : R_MOVL1;	      fix_new_exp (frag_now, offset, 4, &operand->exp, 0, idx);	    }	  break;	}    }  else    {      switch (operand->mode & SIZE)	{	case L_24:	case L_32:	  size = 4;	  where = (operand->mode & SIZE) == L_24 ? -1 : 0;	  if (relaxmode == 2)	    idx = R_MOV24B1;	  else if (relaxmode == 1)	    idx = R_MOVL1;	  else	    idx = R_RELLONG;	  break;	default:	  as_bad (_("Can't work out size of operand.\n"));	case L_16:	  size = 2;	  where = 0;	  if (relaxmode == 2)	    idx = R_MOV16B1;	  else	    idx = R_RELWORD;	  operand->exp.X_add_number =	    ((operand->exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;	  break;	case L_8:	  size = 1;	  where = 0;	  idx = R_RELBYTE;	  operand->exp.X_add_number =	    ((operand->exp.X_add_number & 0xff) ^ 0x80) - 0x80;	}      fix_new_exp (frag_now,		   offset + where,		   size,		   &operand->exp,		   0,		   idx);    }}/* Now we know what sort of opcodes it is, let's build the bytes.  */static voidbuild_bytes (this_try, operand)     struct h8_opcode *this_try;     struct h8_op *operand;{  unsigned int i;  char *output = frag_more (this_try->length);  op_type *nibble_ptr = this_try->data.nib;  op_type c;  unsigned int nibble_count = 0;  int absat;  int immat;  int nib;  int movb = 0;  char asnibbles[30];  char *p = asnibbles;  if (!(this_try->inbase || Hmode))    as_warn (_("Opcode `%s' with these operand types not available in H8/300 mode"),	     this_try->name);  while (*nibble_ptr != E)    {      int d;      c = *nibble_ptr++;      d = (c & (DST | SRC_IN_DST)) != 0;      if (c < 16)	{	  nib = c;	}      else	{	  if (c & (REG | IND | INC | DEC))	    {	      nib = operand[d].reg;	    }	  else if ((c & DISPREG) == (DISPREG))	    {	      nib = dispreg;	    }	  else if (c & ABS)	    {	      operand[d].mode = c;	      absat = nibble_count / 2;	      nib = 0;	    }	  else if (c & (IMM | PCREL | ABS | ABSJMP | DISP))	    {	      operand[d].mode = c;	      immat = nibble_count / 2;	      nib = 0;	    }	  else if (c & IGNORE)	    {	      nib = 0;	    }	  else if (c & DBIT)	    {	      switch (operand[0].exp.X_add_number)		{		case 1:		  nib = c;		  break;		case 2:		  nib = 0x8 | c;		  break;		default:		  as_bad (_("Need #1 or #2 here"));		}	    }	  else if (c & KBIT)	    {	      switch (operand[0].exp.X_add_number)		{		case 1:		  nib = 0;		  break;		case 2:		  nib = 8;		  break;		case 4:		  if (!Hmode)		    as_warn (_("#4 not valid on H8/300."));		  nib = 9;		  break;		default:		  as_bad (_("Need #1 or #2 here"));		  break;		}	      /* Stop it making a fix.  */	      operand[0].mode = 0;	    }	  if (c & MEMRELAX)	    {	      operand[d].mode |= MEMRELAX;	    }	  if (c & B31)	    {	      nib |= 0x8;	    }	  if (c & MACREG)	    {	      if (operand[0].mode == MACREG)		/* stmac has mac[hl] as the first operand.  */		nib = 2 + operand[0].reg;	      else		/* ldmac has mac[hl] as the second operand.  */		nib = 2 + operand[1].reg;	    }	}

⌨️ 快捷键说明

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