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

📄 tc-h8500.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 3 页
字号:
	  return;	}      else	{	  /* must be a symbol */	  *ptr =	    skip_colonthing (exp_unsigned, src, op,			     ispage ? ABS24 : ABS16, ABS8, ABS16, ABS24);	  return;	}    }  if (*src == '#')    {      src++;      *ptr = skip_colonthing (exp_sandu, src, op, IMM16, IMM8, IMM16, ABS24);      return;    }  else    {      *ptr = skip_colonthing (exp_signed, src, op,			      ispage ? ABS24 : PCREL8, PCREL8, PCREL16, ABS24);    }}static char *get_operands (info, args, operand)     h8500_opcode_info *info;     char *args;     h8500_operand_info *operand;{  char *ptr = args;  switch (info->nargs)    {    case 0:      operand[0].type = 0;      operand[1].type = 0;      break;    case 1:      ptr++;      get_operand (&ptr, operand + 0, info->name[0] == 'p');      operand[1].type = 0;      break;    case 2:      ptr++;      get_operand (&ptr, operand + 0, 0);      if (*ptr == ',')	ptr++;      get_operand (&ptr, operand + 1, 0);      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.  */int pcrel8;			/* Set when we've seen a pcrel operand */static h8500_opcode_info *get_specific (opcode, operands)     h8500_opcode_info *opcode;     h8500_operand_info *operands;{  h8500_opcode_info *this_try = opcode;  int found = 0;  unsigned int noperands = opcode->nargs;  unsigned int this_index = opcode->idx;  while (this_index == opcode->idx && !found)    {      unsigned int i;      this_try = opcode++;      /* look at both operands needed by the opcodes and provided by       the user*/      for (i = 0; i < noperands; i++)	{	  h8500_operand_info *user = operands + i;	  switch (this_try->arg_type[i])	    {	    case FPIND_D8:	      /* Opcode needs (disp:8,fp) */	      if (user->type == RNIND_D8 && user->reg == 6)		{		  displacement = user->exp;		  continue;		}	      break;	    case RDIND_D16:	      if (user->type == RNIND_D16)		{		  displacement = user->exp;		  rd = user->reg;		  continue;		}	      break;	    case RDIND_D8:	      if (user->type == RNIND_D8)		{		  displacement = user->exp;		  rd = user->reg;		  continue;		}	      break;	    case RNIND_D16:	    case RNIND_D8:	      if (user->type == this_try->arg_type[i])		{		  displacement = user->exp;		  rn = user->reg;		  continue;		}	      break;	    case SPDEC:	      if (user->type == RNDEC && user->reg == 7)		{		  continue;		}	      break;	    case SPINC:	      if (user->type == RNINC && user->reg == 7)		{		  continue;		}	      break;	    case ABS16:	      if (user->type == ABS16)		{		  absolute = user->exp;		  continue;		}	      break;	    case ABS8:	      if (user->type == ABS8)		{		  absolute = user->exp;		  continue;		}	      break;	    case ABS24:	      if (user->type == ABS24)		{		  absolute = user->exp;		  continue;		}	      break;	    case CRB:	      if ((user->type == CRB || user->type == CR) && user->reg != 0)		{		  crb = user->reg;		  continue;		}	      break;	    case CRW:	      if ((user->type == CRW || user->type == CR) && user->reg == 0)		{		  crw = user->reg;		  continue;		}	      break;	    case DISP16:	      if (user->type == DISP16)		{		  displacement = user->exp;		  continue;		}	      break;	    case DISP8:	      if (user->type == DISP8)		{		  displacement = user->exp;		  continue;		}	      break;	    case FP:	      if (user->type == RN && user->reg == 6)		{		  continue;		}	      break;	    case PCREL16:	      if (user->type == PCREL16)		{		  displacement = user->exp;		  continue;		}	      break;	    case PCREL8:	      if (user->type == PCREL8)		{		  displacement = user->exp;		  pcrel8 = 1;		  continue;		}	      break;	    case IMM16:	      if (user->type == IMM16		  || user->type == IMM8)		{		  immediate_inpage = user->page;		  immediate = user->exp;		  continue;		}	      break;	    case RLIST:	    case IMM8:	      if (user->type == IMM8)		{		  immediate_inpage = user->page;		  immediate = user->exp;		  continue;		}	      break;	    case IMM4:	      if (user->type == IMM8)		{		  immediate_inpage = user->page;		  immediate = user->exp;		  continue;		}	      break;	    case QIM:	      if (user->type == IMM8		  && user->exp.X_op == O_constant		  &&		  (user->exp.X_add_number == -2		   || user->exp.X_add_number == -1		   || user->exp.X_add_number == 1		   || user->exp.X_add_number == 2))		{		  immediate_inpage = user->page;		  immediate = user->exp;		  continue;		}	      break;	    case RD:	      if (user->type == RN)		{		  rd = user->reg;		  continue;		}	      break;	    case RS:	      if (user->type == RN)		{		  rs = user->reg;		  continue;		}	      break;	    case RDIND:	      if (user->type == RNIND)		{		  rd = user->reg;		  continue;		}	      break;	    case RNINC:	    case RNIND:	    case RNDEC:	    case RN:	      if (user->type == this_try->arg_type[i])		{		  rn = user->reg;		  continue;		}	      break;	    case SP:	      if (user->type == RN && user->reg == 7)		{		  continue;		}	      break;	    default:	      printf (_("unhandled %d\n"), this_try->arg_type[i]);	      break;	    }	  /* If we get here this didn't work out */	  goto fail;	}      found = 1;    fail:;    }  if (found)    return this_try;  else    return 0;}intcheck (operand, low, high)     expressionS *operand;     int low;     int high;{  if (operand->X_op != O_constant      || operand->X_add_number < low      || operand->X_add_number > high)    {      as_bad (_("operand must be absolute in range %d..%d"), low, high);    }  return operand->X_add_number;}static voidinsert (output, index, exp, reloc, pcrel)     char *output;     int index;     expressionS *exp;     int reloc;     int pcrel;{  fix_new_exp (frag_now,	       output - frag_now->fr_literal + index,	       4,	       	/* always say size is 4, but we know better */	       exp,	       pcrel,	       reloc);}voidbuild_relaxable_instruction (opcode, operand)     h8500_opcode_info *opcode;     h8500_operand_info *operand;{  /* All relaxable instructions start life as two bytes but can become     three bytes long if a lonely branch and up to 9 bytes if long     scb.  */  char *p;  int len;  int type;  if (opcode->bytes[0].contents == 0x01)    {      type = SCB_F;    }  else if (opcode->bytes[0].contents == 0x06	   || opcode->bytes[0].contents == 0x07)    {      type = SCB_TST;    }  else    {      type = BRANCH;    }  p = frag_var (rs_machine_dependent,		md_relax_table[C (type, WORD_DISP)].rlx_length,		len = md_relax_table[C (type, BYTE_DISP)].rlx_length,		C (type, UNDEF_BYTE_DISP),		displacement.X_add_symbol,		displacement.X_add_number,		0);  p[0] = opcode->bytes[0].contents;  if (type != BRANCH)    {      p[1] = opcode->bytes[1].contents | rs;    }}/* Now we know what sort of opcodes it is, let's build the bytes.  */static voidbuild_bytes (opcode, operand)     h8500_opcode_info *opcode;     h8500_operand_info *operand;{  int index;  if (pcrel8)    {      pcrel8 = 0;      build_relaxable_instruction (opcode, operand);    }  else    {      char *output = frag_more (opcode->length);      memset (output, 0, opcode->length);      for (index = 0; index < opcode->length; index++)	{	  output[index] = opcode->bytes[index].contents;	  switch (opcode->bytes[index].insert)	    {	    default:	      printf (_("failed for %d\n"), opcode->bytes[index].insert);	      break;	    case 0:	      break;	    case RN:	      output[index] |= rn;	      break;	    case RD:	    case RDIND:	      output[index] |= rd;	      break;	    case RS:	      output[index] |= rs;	      break;	    case DISP16:	      insert (output, index, &displacement, R_H8500_IMM16, 0);	      index++;	      break;	    case DISP8:	    case FPIND_D8:	      insert (output, index, &displacement, R_H8500_IMM8, 0);	      break;	    case IMM16:	      {		int p;		switch (immediate_inpage)		  {		  case 'p':		    p = R_H8500_HIGH16;		    break;		  case 'h':		    p = R_H8500_HIGH16;		    break;		  default:		    p = R_H8500_IMM16;		    break;		  }		insert (output, index, &immediate, p, 0);	      }	      index++;	      break;	    case RLIST:	    case IMM8:	      if (immediate_inpage)		insert (output, index, &immediate, R_H8500_HIGH8, 0);	      else		insert (output, index, &immediate, R_H8500_IMM8, 0);	      break;	    case PCREL16:	      insert (output, index, &displacement, R_H8500_PCREL16, 1);	      index++;	      break;	    case PCREL8:	      insert (output, index, &displacement, R_H8500_PCREL8, 1);	      break;	    case IMM4:	      output[index] |= check (&immediate, 0, 15);	      break;	    case CR:	      output[index] |= cr;	      if (cr == 0)		output[0] |= 0x8;	      else		output[0] &= ~0x8;	      break;	    case CRB:	      output[index] |= crb;	      output[0] &= ~0x8;	      break;	    case CRW:	      output[index] |= crw;	      output[0] |= 0x8;	      break;	    case ABS24:	      insert (output, index, &absolute, R_H8500_IMM24, 0);	      index += 2;	      break;	    case ABS16:	      insert (output, index, &absolute, R_H8500_IMM16, 0);	      index++;	      break;	    case ABS8:	      insert (output, index, &absolute, R_H8500_IMM8, 0);	      break;	    case QIM:	      switch (immediate.X_add_number)		{		case -2:		  output[index] |= 0x5;		  break;		case -1:		  output[index] |= 0x4;		  break;		case 1:		  output[index] |= 0;		  break;		case 2:		  output[index] |= 1;		  break;		}	      break;	    }	}    }}/* This is the guts of the machine-dependent assembler.  STR points to   a machine dependent instruction.  This function is supposed to emit   the frags/bytes it assembles to.  */voidmd_assemble (str)     char *str;{  char *op_start;  char *op_end;  h8500_operand_info operand[2];  h8500_opcode_info *opcode;  h8500_opcode_info *prev_opcode;  char name[11];  int nlen = 0;  /* Drop leading whitespace.  */  while (*str == ' ')    str++;

⌨️ 快捷键说明

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