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

📄 tc-z8k.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 2 页
字号:
	}      if (ptr == 0)	return NULL;      if (*ptr == ',')	ptr++;      get_operand (&ptr, operand + 1, 1);      break;    case 3:      ptr++;      get_operand (&ptr, operand + 0, 0);      if (*ptr == ',')	ptr++;      get_operand (&ptr, operand + 1, 1);      if (*ptr == ',')	ptr++;      get_operand (&ptr, operand + 2, 2);      break;    case 4:      ptr++;      get_operand (&ptr, operand + 0, 0);      if (*ptr == ',')	ptr++;      get_operand (&ptr, operand + 1, 1);      if (*ptr == ',')	ptr++;      get_operand (&ptr, operand + 2, 2);      if (*ptr == ',')	ptr++;      get_cc_operand (&ptr, operand + 3, 3);      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 opcode_entry_type *get_specific (opcode, operands)     opcode_entry_type *opcode;     op_type *operands;{  opcode_entry_type *this_try = opcode;  int found = 0;  unsigned int noperands = opcode->noperands;  int this_index = opcode->idx;  while (this_index == opcode->idx && !found)    {      unsigned int i;      this_try = opcode++;      for (i = 0; i < noperands; i++)	{	  unsigned int mode = operands[i].mode;	  if ((mode & CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK))	    {	      /* It could be an pc rel operand, if this is a da mode		 and we like disps, then insert it.  */	      if (mode == CLASS_DA && this_try->arg_info[i] == CLASS_DISP)		{		  /* This is the case.  */		  operands[i].mode = CLASS_DISP;		}	      else if (mode == CLASS_BA && this_try->arg_info[i])		{		  /* Can't think of a way to turn what we've been		     given into something that's OK.  */		  goto fail;		}	      else if (this_try->arg_info[i] & CLASS_PR)		{		  if (mode == CLASS_REG_LONG && segmented_mode)		    {		      /* OK.  */		    }		  else if (mode == CLASS_REG_WORD && !segmented_mode)		    {		      /* OK.  */		    }		  else		    goto fail;		}	      else		goto fail;	    }	  switch (mode & CLASS_MASK)	    {	    default:	      break;	    case CLASS_X:	    case CLASS_IR:	    case CLASS_BA:	    case CLASS_BX:	    case CLASS_DISP:	    case CLASS_REG:	    case CLASS_REG_WORD:	    case CLASS_REG_BYTE:	    case CLASS_REG_QUAD:	    case CLASS_REG_LONG:	    case CLASS_REGN0:	      reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;	      break;	    }	}      found = 1;    fail:      ;    }  if (found)    return this_try;  else    return 0;}#if 0 /* Not used.  */static voidcheck_operand (operand, width, string)     struct z8k_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))	{	  as_warn (_("operand %s0x%x out of range."),		   string, operand->exp.X_add_number);	}    }}#endifstatic char buffer[20];static voidnewfix (ptr, type, operand)     int ptr;     int type;     expressionS *operand;{  if (operand->X_add_symbol      || operand->X_op_symbol      || operand->X_add_number)    {      fix_new_exp (frag_now,		   ptr,		   1,		   operand,		   0,		   type);    }}static char *apply_fix (ptr, type, operand, size)     char *ptr;     int type;     expressionS *operand;     int size;{  int n = operand->X_add_number;  newfix ((ptr - buffer) / 2, type, operand);  switch (size)    {    case 8:			/* 8 nibbles == 32 bits.  */      *ptr++ = n >> 28;      *ptr++ = n >> 24;      *ptr++ = n >> 20;      *ptr++ = n >> 16;    case 4:			/* 4 nibbles == 16 bits.  */      *ptr++ = n >> 12;      *ptr++ = n >> 8;    case 2:      *ptr++ = n >> 4;    case 1:      *ptr++ = n >> 0;      break;    }  return ptr;}/* Now we know what sort of opcodes it is.  Let's build the bytes.  */#define INSERT(x,y) *x++ = y>>24; *x++ = y>> 16; *x++=y>>8; *x++ =y;static voidbuild_bytes (this_try, operand)     opcode_entry_type *this_try;     struct z8k_op *operand ATTRIBUTE_UNUSED;{  char *output_ptr = buffer;  int c;  int nib;  int nibble;  unsigned int *class_ptr;  frag_wane (frag_now);  frag_new (0);  memset (buffer, 20, 0);  class_ptr = this_try->byte_info;  for (nibble = 0; (c = *class_ptr++); nibble++)    {      switch (c & CLASS_MASK)	{	default:	  abort ();	case CLASS_ADDRESS:	  /* Direct address, we don't cope with the SS mode right now.  */	  if (segmented_mode)	    {	      /* da_operand->X_add_number |= 0x80000000;  --  Now set at relocation time.  */	      output_ptr = apply_fix (output_ptr, R_IMM32, da_operand, 8);	    }	  else	    {	      output_ptr = apply_fix (output_ptr, R_IMM16, da_operand, 4);	    }	  da_operand = 0;	  break;	case CLASS_DISP8:	  /* pc rel 8 bit  */	  output_ptr = apply_fix (output_ptr, R_JR, da_operand, 2);	  da_operand = 0;	  break;	case CLASS_0DISP7:	  /* pc rel 7 bit  */	  *output_ptr = 0;	  output_ptr = apply_fix (output_ptr, R_DISP7, da_operand, 2);	  da_operand = 0;	  break;	case CLASS_1DISP7:	  /* pc rel 7 bit  */	  *output_ptr = 0x80;	  output_ptr = apply_fix (output_ptr, R_DISP7, da_operand, 2);	  output_ptr[-2] = 0x8;	  da_operand = 0;	  break;	case CLASS_BIT_1OR2:	  *output_ptr = c & 0xf;	  if (imm_operand)	    {	      if (imm_operand->X_add_number == 2)		*output_ptr |= 2;	      else if (imm_operand->X_add_number != 1)		as_bad (_("immediate must be 1 or 2"));	    }	  else	    as_bad (_("immediate 1 or 2 expected"));	  output_ptr++;	  break;	case CLASS_CC:	  *output_ptr++ = the_cc;	  break;	case CLASS_0CCC:	  *output_ptr++ = the_ctrl;	  break;	case CLASS_1CCC:	  *output_ptr++ = the_ctrl | 0x8;	  break;	case CLASS_00II:	  *output_ptr++ = (~the_interrupt & 0x3);	  break;	case CLASS_01II:	  *output_ptr++ = (~the_interrupt & 0x3) | 0x4;	  break;	case CLASS_FLAGS:	  *output_ptr++ = the_flags;	  break;	case CLASS_BIT:	  *output_ptr++ = c & 0xf;	  break;	case CLASS_REGN0:	  if (reg[c & 0xf] == 0)	    as_bad (_("can't use R0 here"));	  /* Fall through.  */	case CLASS_REG:	case CLASS_REG_BYTE:	case CLASS_REG_WORD:	case CLASS_REG_LONG:	case CLASS_REG_QUAD:	  /* Insert bit mattern of right reg.  */	  *output_ptr++ = reg[c & 0xf];	  break;	case CLASS_DISP:          switch (c & ARG_MASK)            {            case ARG_DISP12:              output_ptr = apply_fix (output_ptr, R_CALLR, da_operand, 4);              break;            case ARG_DISP16:	      output_ptr = apply_fix (output_ptr, R_REL16, da_operand, 4);	      break;	    default:	      output_ptr = apply_fix (output_ptr, R_IMM16, da_operand, 4);	    }	  da_operand = 0;	  break;	case CLASS_IMM:	  {	    nib = 0;	    switch (c & ARG_MASK)	      {	      case ARG_IMM4:		output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);		break;	      case ARG_IMM4M1:		imm_operand->X_add_number--;		output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);		break;	      case ARG_IMMNMINUS1:		imm_operand->X_add_number--;		output_ptr = apply_fix (output_ptr, R_IMM4L, imm_operand, 1);		break;	      case ARG_NIM8:		imm_operand->X_add_number = -imm_operand->X_add_number;	      case ARG_IMM8:		output_ptr = apply_fix (output_ptr, R_IMM8, imm_operand, 2);		break;	      case ARG_IMM16:		output_ptr = apply_fix (output_ptr, R_IMM16, imm_operand, 4);		break;	      case ARG_IMM32:		output_ptr = apply_fix (output_ptr, R_IMM32, imm_operand, 8);		break;	      default:		abort ();	      }	  }	}    }  /* Copy from the nibble buffer into the frag.  */  {    int length = (output_ptr - buffer) / 2;    char *src = buffer;    char *fragp = frag_more (length);    while (src < output_ptr)      {	*fragp = (src[0] << 4) | src[1];	src += 2;	fragp++;      }  }}/* 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 c;  char *op_start;  char *op_end;  struct z8k_op operand[3];  opcode_entry_type *opcode;  opcode_entry_type *prev_opcode;  /* Drop leading whitespace.  */  while (*str == ' ')    str++;  /* Find the op code end.  */  for (op_start = op_end = str;       *op_end != 0 && *op_end != ' ';       op_end++)    ;  if (op_end == op_start)    {      as_bad (_("can't find opcode "));    }  c = *op_end;  *op_end = 0;  opcode = (opcode_entry_type *) hash_find (opcode_hash_control, op_start);  if (opcode == NULL)    {      as_bad (_("unknown opcode"));      return;    }  if (opcode->opcode == 250)    {      /* Was really a pseudo op.  */      pseudo_typeS *p;      char oc;      char *old = input_line_pointer;      *op_end = c;      input_line_pointer = op_end;      oc = *old;      *old = '\n';      while (*input_line_pointer == ' ')	input_line_pointer++;      p = (pseudo_typeS *) (opcode->func);      (p->poc_handler) (p->poc_val);      input_line_pointer = old;      *old = oc;    }  else    {      input_line_pointer = get_operands (opcode, op_end, operand);      prev_opcode = opcode;      opcode = get_specific (opcode, operand);      if (opcode == 0)	{	  /* Couldn't find an opcode which matched the operands.  */	  char *where = frag_more (2);	  where[0] = 0x0;	  where[1] = 0x0;	  as_bad (_("Can't find opcode to match operands"));	  return;	}      build_bytes (opcode, operand);    }}voidtc_crawl_symbol_chain (headers)     object_headers *headers ATTRIBUTE_UNUSED;{  printf (_("call to tc_crawl_symbol_chain \n"));}symbolS *md_undefined_symbol (name)     char *name ATTRIBUTE_UNUSED;{  return 0;}voidtc_headers_hook (headers)     object_headers *headers ATTRIBUTE_UNUSED;{  printf (_("call to tc_headers_hook \n"));}/* Various routines to kill one day.  *//* Equal to MAX_PRECISION in atof-ieee.c.  */#define MAX_LITTLENUMS 6/* Turn a string in input_line_pointer into a floating point constant   of type TYPE, and store the appropriate bytes in *LITP.  The number   of LITTLENUMS emitted is stored in *SIZEP.  An error message is   returned, or NULL on OK.  */char *md_atof (type, litP, sizeP)     char type;     char *litP;     int *sizeP;{  int prec;  LITTLENUM_TYPE words[MAX_LITTLENUMS];  LITTLENUM_TYPE *wordP;  char *t;  char *atof_ieee ();  switch (type)    {    case 'f':    case 'F':    case 's':    case 'S':      prec = 2;      break;    case 'd':    case 'D':    case 'r':    case 'R':      prec = 4;      break;    case 'x':    case 'X':      prec = 6;      break;    case 'p':    case 'P':      prec = 6;      break;    default:      *sizeP = 0;      return _("Bad call to MD_ATOF()");    }  t = atof_ieee (input_line_pointer, type, words);  if (t)    input_line_pointer = t;  *sizeP = prec * sizeof (LITTLENUM_TYPE);  for (wordP = words; prec--;)    {      md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));      litP += sizeof (LITTLENUM_TYPE);    }  return 0;}CONST char *md_shortopts = "z:";struct option md_longopts[] = {  {NULL, no_argument, NULL, 0}};size_t md_longopts_size = sizeof (md_longopts);intmd_parse_option (c, arg)     int c;     char *arg;{  switch (c)    {    case 'z':      if (!strcmp (arg, "8001"))	s_segm ();      else if (!strcmp (arg, "8002"))	s_unseg ();      else	{	  as_bad (_("invalid architecture -z%s"), arg);	  return 0;	}      break;    default:      return 0;    }  return 1;}voidmd_show_usage (stream)     FILE *stream;{  fprintf (stream, _("\Z8K options:\n\-z8001			generate segmented code\n\-z8002			generate unsegmented code\n"));}voidtc_aout_fix_to_chars (){  printf (_("call to tc_aout_fix_to_chars \n"));  abort ();}voidmd_convert_frag (headers, seg, fragP)     object_headers *headers ATTRIBUTE_UNUSED;     segT seg ATTRIBUTE_UNUSED;     fragS *fragP ATTRIBUTE_UNUSED;{  printf (_("call to md_convert_frag \n"));  abort ();}valueTmd_section_align (seg, size)     segT seg;     valueT size;{  return ((size + (1 << section_alignment[(int) seg]) - 1)	  & (-1 << section_alignment[(int) seg]));}voidmd_apply_fix (fixP, val)     fixS *fixP;     long val;{  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;  switch (fixP->fx_r_type)    {    case R_IMM4L:      buf[0] = (buf[0] & 0xf0) | ((buf[0] + val) & 0xf);      break;    case R_JR:      *buf++ = val;#if 0      if (val != 0)	abort ();#endif      break;    case R_DISP7:      *buf++ += val;#if 0      if (val != 0)	abort ();#endif      break;    case R_IMM8:      buf[0] += val;      break;    case R_IMM16:      *buf++ = (val >> 8);      *buf++ = val;      break;    case R_IMM32:      *buf++ = (val >> 24);      *buf++ = (val >> 16);      *buf++ = (val >> 8);      *buf++ = val;      break;#if 0    case R_DA | R_SEG:      *buf++ = (val >> 16);      *buf++ = 0x00;      *buf++ = (val >> 8);      *buf++ = val;      break;#endif    case 0:      md_number_to_chars (buf, val, fixP->fx_size);      break;    default:      abort ();    }}intmd_estimate_size_before_relax (fragP, segment_type)     register fragS *fragP ATTRIBUTE_UNUSED;     register segT segment_type ATTRIBUTE_UNUSED;{  printf (_("call tomd_estimate_size_before_relax \n"));  abort ();}/* Put number into target byte order.  */voidmd_number_to_chars (ptr, use, nbytes)     char *ptr;     valueT use;     int nbytes;{  number_to_chars_bigendian (ptr, use, nbytes);}longmd_pcrel_from (fixP)     fixS *fixP ATTRIBUTE_UNUSED;{  abort ();}voidtc_coff_symbol_emit_hook (s)     symbolS *s ATTRIBUTE_UNUSED;{}voidtc_reloc_mangle (fix_ptr, intr, base)     fixS *fix_ptr;     struct internal_reloc *intr;     bfd_vma base;{  symbolS *symbol_ptr;  if (fix_ptr->fx_addsy      && fix_ptr->fx_subsy)    {      symbolS *add = fix_ptr->fx_addsy;      symbolS *sub = fix_ptr->fx_subsy;      if (S_GET_SEGMENT (add) != S_GET_SEGMENT (sub))	as_bad (_("Can't subtract symbols in different sections %s %s"),		S_GET_NAME (add), S_GET_NAME (sub));      else	{	  int diff = S_GET_VALUE (add) - S_GET_VALUE (sub);	  fix_ptr->fx_addsy = 0;	  fix_ptr->fx_subsy = 0;	  fix_ptr->fx_offset += diff;	}    }  symbol_ptr = fix_ptr->fx_addsy;  /* If this relocation is attached to a symbol then it's ok     to output it.  */  if (fix_ptr->fx_r_type == 0)    {      /* cons likes to create reloc32's whatever the size of the reloc.  */      switch (fix_ptr->fx_size)	{	case 2:	  intr->r_type = R_IMM16;	  break;	case 1:	  intr->r_type = R_IMM8;	  break;	case 4:	  intr->r_type = R_IMM32;	  break;	default:	  abort ();	}    }  else    intr->r_type = fix_ptr->fx_r_type;  intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;  intr->r_offset = fix_ptr->fx_offset;  if (symbol_ptr)    intr->r_symndx = symbol_ptr->sy_number;  else    intr->r_symndx = -1;}

⌨️ 快捷键说明

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