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

📄 tc-m68hc11.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
	      if (i == 0 && (format & M6811_OP_BITMASK))		break;	    }	  if (mode & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))	    {	      if (format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))		continue;	    }	  if (mode & M6812_OP_REG)	    {	      if (i == 0		  && (format & M6812_OP_REG)		  && (operands[i].reg2 == REG_NONE))		continue;	      if (i == 0		  && (format & M6812_OP_REG)		  && (format & M6812_OP_REG_2)		  && (operands[i].reg2 != REG_NONE))		continue;	      if (i == 0		  && (format & M6812_OP_IDX)		  && (operands[i].reg2 != REG_NONE))		continue;	      if (i == 0		  && (format & M6812_OP_D_IDX))		continue;	      if (i == 0		  && (format & M6812_OP_IDX)		  && (format & (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)))		continue;	      if (i == 1		  && (format & M6812_OP_IDX_P2))		continue;	      break;	    }	  if (mode & M6812_OP_IDX)	    {	      if (format & M6811_OP_IX && operands[i].reg1 == REG_X)		continue;	      if (format & M6811_OP_IY && operands[i].reg1 == REG_Y)		continue;	      if (i == 0		  && format & (M6812_OP_IDX | M6812_OP_IDX_1 | M6812_OP_IDX_2)		  && (operands[i].reg1 == REG_X		      || operands[i].reg1 == REG_Y		      || operands[i].reg1 == REG_SP		      || operands[i].reg1 == REG_PC))		continue;	      if (i == 1 && format & M6812_OP_IDX_P2)		continue;	    }	  if (mode & M6812_AUTO_INC_DEC)	    {	      if (i == 0		  && format & (M6812_OP_IDX | M6812_OP_IDX_1 |			       M6812_OP_IDX_2))		continue;	      if (i == 1 && format & M6812_OP_IDX_P2)		continue;	    }	  break;	}      match = i == nb_operands;      /* Operands are ok but an operand uses page 0 addressing mode         while the insn supports abs-16 mode.  Keep a reference to this         insns in case there is no insn supporting page 0 addressing.  */      if (match && poss_indirect)	{	  op_indirect = opcode;	  match = 0;	}      if (match)	break;    }  /* Page 0 addressing is used but not supported by any insn.     If absolute addresses are supported, we use that insn.  */  if (match == 0 && op_indirect)    {      opcode = op_indirect;      match = 1;    }  if (!match)    {      return (0);    }  return opcode;}/* Find the real opcode and its associated operands.  We use a progressive   approach here.  On entry, 'opc' points to the first opcode in the   table that matches the opcode name in the source line.  We try to   isolate an operand, find a possible match in the opcode table.   We isolate another operand if no match were found.  The table 'operands'   is filled while operands are recognized.   Returns the opcode pointer that matches the opcode name in the   source line and the associated operands.  */static struct m68hc11_opcode *find_opcode (opc, operands, nb_operands)     struct m68hc11_opcode_def *opc;     operand operands[];     int *nb_operands;{  struct m68hc11_opcode *opcode;  int i;  if (opc->max_operands == 0)    {      *nb_operands = 0;      return opc->opcode;    }  for (i = 0; i < opc->max_operands;)    {      int result;      result = get_operand (&operands[i], i, opc->format);      if (result <= 0)	return 0;      /* Special case where the bitmask of the bclr/brclr         instructions is not introduced by #.         Example: bclr 3,x $80.  */      if (i == 1 && (opc->format & M6811_OP_BITMASK)	  && (operands[i].mode & M6811_OP_IND16))	{	  operands[i].mode = M6811_OP_IMM16;	}      i += result;      *nb_operands = i;      if (i >= opc->min_operands)	{	  opcode = find (opc, operands, i);	  if (opcode)	    return opcode;	}      if (*input_line_pointer == ',')	input_line_pointer++;    }  return 0;}#define M6812_XBCC_MARKER (M6812_OP_TBCC_MARKER \                           | M6812_OP_DBCC_MARKER \                           | M6812_OP_IBCC_MARKER)/* Gas line assembler entry point.  *//* This is the main entry point for 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;{  struct m68hc11_opcode_def *opc;  struct m68hc11_opcode *opcode;  unsigned char *op_start, *save;  unsigned char *op_end;  char name[20];  int nlen = 0;  operand operands[M6811_MAX_OPERANDS];  int nb_operands;  int branch_optimize = 0;  int alias_id = -1;  /* Drop leading whitespace.  */  while (*str == ' ')    str++;  /* Find the opcode end and get the opcode in 'name'.  The opcode is forced     lower case (the opcode table only has lower case op-codes).  */  for (op_start = op_end = (unsigned char *) (str);       *op_end && nlen < 20 && !is_end_of_line[*op_end] && *op_end != ' ';       op_end++)    {      name[nlen] = tolower (op_start[nlen]);      nlen++;    }  name[nlen] = 0;  if (nlen == 0)    {      as_bad (_("No instruction or missing opcode."));      return;    }  /* Find the opcode definition given its name.  */  opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, name);  /* If it's not recognized, look for 'jbsr' and 'jbxx'.  These are     pseudo insns for relative branch.  For these branchs, we always     optimize them (turned into absolute branchs) even if --short-branchs     is given.  */  if (opc == NULL && name[0] == 'j' && name[1] == 'b')    {      opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash, &name[1]);      if (opc	  && (!(opc->format & M6811_OP_JUMP_REL)	      || (opc->format & M6811_OP_BITMASK)))	opc = 0;      if (opc)	branch_optimize = 1;    }  /* The following test should probably be removed.  This is not conform     to Motorola assembler specs.  */  if (opc == NULL && flag_mri)    {      if (*op_end == ' ' || *op_end == '\t')	{	  while (*op_end == ' ' || *op_end == '\t')	    op_end++;	  if (nlen < 19	      && (*op_end &&		  (is_end_of_line[op_end[1]]		   || op_end[1] == ' ' || op_end[1] == '\t'		   || !isalnum (op_end[1])))	      && (*op_end == 'a' || *op_end == 'b'		  || *op_end == 'A' || *op_end == 'B'		  || *op_end == 'd' || *op_end == 'D'		  || *op_end == 'x' || *op_end == 'X'		  || *op_end == 'y' || *op_end == 'Y'))	    {	      name[nlen++] = tolower (*op_end++);	      name[nlen] = 0;	      opc = (struct m68hc11_opcode_def *) hash_find (m68hc11_hash,							     name);	    }	}    }  /* Identify a possible instruction alias.  There are some on the     68HC12 to emulate a few 68HC11 instructions.  */  if (opc == NULL && (current_architecture & cpu6812))    {      int i;      for (i = 0; i < m68hc12_num_alias; i++)	if (strcmp (m68hc12_alias[i].name, name) == 0)	  {	    alias_id = i;	    break;	  }    }  if (opc == NULL && alias_id < 0)    {      as_bad (_("Opcode `%s' is not recognized."), name);      return;    }  save = input_line_pointer;  input_line_pointer = op_end;  if (opc)    {      opc->used++;      opcode = find_opcode (opc, operands, &nb_operands);    }  else    opcode = 0;  if ((opcode || alias_id >= 0) && !flag_mri)    {      char *p = input_line_pointer;      while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')	p++;      if (*p != '\n' && *p)	as_bad (_("Garbage at end of instruction: `%s'."), p);    }  input_line_pointer = save;  if (alias_id >= 0)    {      char *f = m68hc11_new_insn (m68hc12_alias[alias_id].size);      number_to_chars_bigendian (f, m68hc12_alias[alias_id].code1, 1);      if (m68hc12_alias[alias_id].size > 1)	number_to_chars_bigendian (f + 1, m68hc12_alias[alias_id].code2, 1);      return;    }  /* Opcode is known but does not have valid operands.  Print out the     syntax for this opcode.  */  if (opcode == 0)    {      if (flag_print_insn_syntax)	print_insn_format (name);      as_bad (_("Invalid operand for `%s'"), name);      return;    }  /* Treat dbeq/ibeq/tbeq instructions in a special way.  The branch is     relative and must be in the range -256..255 (9-bits).  */  if ((opcode->format & M6812_XBCC_MARKER)      && (opcode->format & M6811_OP_JUMP_REL))    build_dbranch_insn (opcode, operands, nb_operands);  /* Relative jumps instructions are taken care of separately.  We have to make     sure that the relative branch is within the range -128..127.  If it's out     of range, the instructions are changed into absolute instructions.     This is not supported for the brset and brclr instructions.  */  else if ((opcode->format & (M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))	   && !(opcode->format & M6811_OP_BITMASK))    build_jump_insn (opcode, operands, nb_operands, branch_optimize);  else    build_insn (opcode, operands, nb_operands);}/* Relocation, relaxation and frag conversions.  */longmd_pcrel_from_section (fixp, sec)     fixS *fixp;     segT sec;{  int adjust;  if (fixp->fx_addsy != (symbolS *) NULL      && (!S_IS_DEFINED (fixp->fx_addsy)	  || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))    return 0;  adjust = fixp->fx_pcrel_adjust;  return fixp->fx_frag->fr_address + fixp->fx_where + adjust;}/* If while processing a fixup, a reloc really needs to be created   then it is done here.  */arelent *tc_gen_reloc (section, fixp)     asection *section;     fixS *fixp;{  arelent *reloc;  reloc = (arelent *) xmalloc (sizeof (arelent));  reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;  if (fixp->fx_r_type == 0)    reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);  else    reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);  if (reloc->howto == (reloc_howto_type *) NULL)    {      as_bad_where (fixp->fx_file, fixp->fx_line,		    _("Relocation %d is not supported by object file format."),		    (int) fixp->fx_r_type);      return NULL;    }  if (!fixp->fx_pcrel)    reloc->addend = fixp->fx_addnumber;  else    reloc->addend = (section->vma		     + (fixp->fx_pcrel_adjust == 64			? -1 : fixp->fx_pcrel_adjust)		     + fixp->fx_addnumber		     + md_pcrel_from_section (fixp, section));  return reloc;}voidmd_convert_frag (abfd, sec, fragP)     bfd *abfd ATTRIBUTE_UNUSED;     asection *sec ATTRIBUTE_UNUSED;     fragS *fragP;{  fixS *fixp;  long value;  long disp;  char *buffer_address = fragP->fr_literal;  /* Address in object code of the displacement.  */  register int object_address = fragP->fr_fix + fragP->fr_address;  buffer_address += fragP->fr_fix;  /* The displacement of the address, from current location.  */  value = fragP->fr_symbol ? S_GET_VALUE (fragP->fr_symbol) : 0;  disp = (value + fragP->fr_offset) - object_address;  disp += symbol_get_frag (fragP->fr_symbol)->fr_address;  switch (fragP->fr_subtype)    {    case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):      fragP->fr_opcode[1] = disp;      break;    case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):      /* This relax is only for bsr and bra.  */      assert (IS_OPCODE (fragP->fr_opcode[0], M6811_BSR)	      || IS_OPCODE (fragP->fr_opcode[0], M6811_BRA)	      || IS_OPCODE (fragP->fr_opcode[0], M6812_BSR));      fragP->fr_opcode[0] = convert_branch (fragP->fr_opcode[0]);      fix_new (fragP, fragP->fr_fix - 1, 2,	       fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);      fragP->fr_fix += 1;      break;    case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):    case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_BYTE):      fragP->fr_opcode[1] = disp;      break;    case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):      /* Invert branch.  */      fragP->fr_opcode[0] ^= 1;      fragP->fr_opcode[1] = 3;	/* Branch offset.  */      buffer_address[0] = M6811_JMP;      fix_new (fragP, fragP->fr_fix + 1, 2,	       fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);      fragP->fr_fix += 3;      break;    case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH_6812, STATE_WORD):      /* Translate branch into a long branch.  */      fragP->fr_opcode[1] = fragP->fr_opcode[0];      fragP->fr_opcode[0] = M6811_OPCODE_PAGE2;      fixp = fix_new (fragP, fragP->fr_fix, 2,		      fragP->fr_symbol, fragP->fr_offset, 1,		      BFD_RELOC_16_PCREL);      fixp->fx_pcrel_adjust = 2;      fragP->fr_fix += 2;      break;    case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):      fragP->fr_opcode[0] = fragP->fr_opcode[0] << 6;      if ((fragP->fr_opcode[0] & 0x0ff) == 0x0c0)	fragP->fr_opcode[0] |= disp & 0x1f;      else	fragP->fr_opcode[0] |= value & 0x1f;      break;    case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):      fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);      fragP->fr_opcode[0] |= 0xE0;      fix_new (fragP, fragP->fr_fix, 1,	       fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_8);      fragP->fr_fix += 1;      break;    case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):      fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);      fragP->fr_opcode[0] |= 0xe2;      if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa)	{	  fixp = fix_new (fragP, fragP->fr_fix, 2,			  fragP->fr_symbol, fragP->fr_offset,			  1, BFD_RELOC_16_PCREL);	  fixp->fx_pcrel_adjust = 2;	}      else	{	  fix_new (fragP, fragP->fr_fix, 2,		   fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);	}      fragP->fr_fix += 2;      break;    case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):      if (disp < 0)	fragP->fr_opcode[0] |= 0x10;      fragP->fr_opcode[1] = disp & 0x0FF;      break;    case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_WORD):      /* Invert branch.  */      fragP->fr_opcode[0] ^= 0x20;      fragP->fr_opcode[1] = 3;	/* Branch offset.  */      buffer_address[0] = M6812_JMP;      fix_new (fragP, fragP->fr_fix + 1, 2,	       fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);      fragP->fr_fix += 3;      break;    default:      break;    }}/* On an ELF system, we can't relax a weak symbol.  The weak symbol   can be overridden at final link time by a non weak symbol.  We can   relax externally visible symbol because there is no shared library   and such symbol can't be overridden (unless they are weak).  */static intrelaxable_symbol (symbol)     symbolS *symbol;{  return ! S_IS_WEAK (symbol);}/* Force truly undefined symbols to their maximum size, and generally set up   the frag list to be relaxed.  */intmd_estim

⌨️ 快捷键说明

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