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

📄 tc-vax.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
			      else				{				  know (operandP->vop_width == VAX_WIDTH_BYTE_JUMP);				  p = frag_more (10);				  p[0] = 2;				  p[1] = VAX_BRB;				  p[2] = 6;				  p[3] = VAX_JMP;				  p[4] = VAX_PC_RELATIVE_MODE;				  fix_new (frag_now,					   p + 5 - frag_now->fr_literal,					   4, this_add_symbol,					   this_add_number, 1, NO_RELOC);				  /*				   * Now (eg)	xOBxxx	1f				   *		BRB	2f				   *	1:	JMP	foo				   *	2:				   */				}			    }			}		      else			{			  know (operandP->vop_width == VAX_WIDTH_CONDITIONAL_JUMP);			  *opcode_low_byteP ^= 1;	/* Reverse branch condition.  */			  p = frag_more (7);			  p[0] = 6;			  p[1] = VAX_JMP;			  p[2] = VAX_PC_RELATIVE_MODE;			  fix_new (frag_now, p + 3 - frag_now->fr_literal,				   4, this_add_symbol,				   this_add_number, 1, NO_RELOC);			}		    }		}	    }	}      else	{	  know (operandP->vop_access != 'b');	/* So it is ordinary operand.  */	  know (operandP->vop_access != ' ');	/* ' ' target-independent: elsewhere.  */	  know (operandP->vop_access == 'a'		|| operandP->vop_access == 'm'		|| operandP->vop_access == 'r'		|| operandP->vop_access == 'v'		|| operandP->vop_access == 'w');	  if (operandP->vop_short == 's')	    {	      if (to_seg == SEG_ABSOLUTE)		{		  if (this_add_number >= 64)		    {		      as_warn (_("Short literal overflow(%ld.), immediate mode assumed."),			       (long) this_add_number);		      operandP->vop_short = 'i';		      operandP->vop_mode = 8;		      operandP->vop_reg = 0xF;		    }		}	      else		{		  as_warn (_("Forced short literal to immediate mode. now_seg=%s to_seg=%s"),			   segment_name (now_seg), segment_name (to_seg));		  operandP->vop_short = 'i';		  operandP->vop_mode = 8;		  operandP->vop_reg = 0xF;		}	    }	  if (operandP->vop_reg >= 0 && (operandP->vop_mode < 8		  || (operandP->vop_reg != 0xF && operandP->vop_mode < 10)))	    {	      /* One byte operand.  */	      know (operandP->vop_mode > 3);	      FRAG_APPEND_1_CHAR (operandP->vop_mode << 4 | operandP->vop_reg);	      /* All 1-bytes except S^# happen here.  */	    }	  else	    {	      /* {@}{q^}foo{(Rn)} or S^#foo */	      if (operandP->vop_reg == -1 && operandP->vop_short != 's')		{		  /* "{@}{q^}foo" */		  if (to_seg == now_seg)		    {		      if (length == 0)			{			  know (operandP->vop_short == ' ');			  p = frag_var (rs_machine_dependent, 10, 2,			       ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE),					this_add_symbol, this_add_number,					opcode_low_byteP);			  know (operandP->vop_mode == 10 + at);			  *p = at << 4;			  /* At is the only context we need to carry			     to other side of relax() process.  Must			     be in the correct bit position of VAX			     operand spec. byte.  */			}		      else			{			  know (length);			  know (operandP->vop_short != ' ');			  p = frag_more (length + 1);			  p[0] = 0xF | ((at + "?\12\14?\16"[length]) << 4);			  fix_new (frag_now, p + 1 - frag_now->fr_literal,				   length, this_add_symbol,				   this_add_number, 1, NO_RELOC);			}		    }		  else		    {		/* to_seg != now_seg */		      if (this_add_symbol == NULL)			{			  know (to_seg == SEG_ABSOLUTE);			  /* Do @#foo: simpler relocation than foo-.(pc) anyway.  */			  p = frag_more (5);			  p[0] = VAX_ABSOLUTE_MODE;	/* @#...  */			  md_number_to_chars (p + 1, this_add_number, 4);			  if (length && length != 4)			    {			      as_warn (_("Length specification ignored. Address mode 9F used"));			    }			}		      else			{			  /* {@}{q^}other_seg */			  know ((length == 0 && operandP->vop_short == ' ')			     || (length > 0 && operandP->vop_short != ' '));			  if (is_undefined)			    {			      /*			       * We have a SEG_UNKNOWN symbol. It might			       * turn out to be in the same segment as			       * the instruction, permitting relaxation.			       */			      p = frag_var (rs_machine_dependent, 5, 2,			       ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),					    this_add_symbol, this_add_number,					    0);			      p[0] = at << 4;			    }			  else			    {			      if (length == 0)				{				  know (operandP->vop_short == ' ');				  length = 4;	/* Longest possible.  */				}			      p = frag_more (length + 1);			      p[0] = 0xF | ((at + "?\12\14?\16"[length]) << 4);			      md_number_to_chars (p + 1, this_add_number, length);			      fix_new (frag_now,				       p + 1 - frag_now->fr_literal,				       length, this_add_symbol,				       this_add_number, 1, NO_RELOC);			    }			}		    }		}	      else		{		  /* {@}{q^}foo(Rn) or S^# or I^# or # */		  if (operandP->vop_mode < 0xA)		    {		      /* # or S^# or I^# */		      if (operandP->vop_access == 'v'			  || operandP->vop_access == 'a')			{			  if (operandP->vop_access == 'v')			    as_warn (_("Invalid operand:  immediate value used as base address."));			  else			    as_warn (_("Invalid operand:  immediate value used as address."));			  /* gcc 2.6.3 is known to generate these in at least			     one case.  */			}		      if (length == 0			  && to_seg == SEG_ABSOLUTE && (expP->X_op != O_big)			  && operandP->vop_mode == 8	/* No '@'.  */			  && this_add_number < 64)			{			  operandP->vop_short = 's';			}		      if (operandP->vop_short == 's')			{			  FRAG_APPEND_1_CHAR (this_add_number);			}		      else			{			  /* I^#...  */			  know (nbytes);			  p = frag_more (nbytes + 1);			  know (operandP->vop_reg == 0xF);			  p[0] = (operandP->vop_mode << 4) | 0xF;			  if ((to_seg == SEG_ABSOLUTE) && (expP->X_op != O_big))			    {			      /*			       * If nbytes > 4, then we are scrod. We			       * don't know if the high order bytes			       * are to be 0xFF or 0x00.  BSD4.2 & RMS			       * say use 0x00. OK --- but this			       * assembler needs ANOTHER rewrite to			       * cope properly with this bug.  */			      md_number_to_chars (p + 1, this_add_number, min (4, nbytes));			      if (nbytes > 4)				{				  memset (p + 5, '\0', nbytes - 4);				}			    }			  else			    {			      if (expP->X_op == O_big)				{				  /*				   * Problem here is to get the bytes				   * in the right order.  We stored				   * our constant as LITTLENUMs, not				   * bytes.  */				  LITTLENUM_TYPE *lP;				  lP = floatP->low;				  if (nbytes & 1)				    {				      know (nbytes == 1);				      p[1] = *lP;				    }				  else				    {				      for (p++; nbytes; nbytes -= 2, p += 2, lP++)					{					  md_number_to_chars (p, *lP, 2);					}				    }				}			      else				{				  fix_new (frag_now, p + 1 - frag_now->fr_literal,					   nbytes, this_add_symbol,					   this_add_number, 0, NO_RELOC);				}			    }			}		    }		  else		    {		/* {@}{q^}foo(Rn) */		      know ((length == 0 && operandP->vop_short == ' ')			    || (length > 0 && operandP->vop_short != ' '));		      if (length == 0)			{			  if (to_seg == SEG_ABSOLUTE)			    {			      long test;			      test = this_add_number;			      if (test < 0)				test = ~test;			      length = test & 0xffff8000 ? 4				: test & 0xffffff80 ? 2				: 1;			    }			  else			    {			      length = 4;			    }			}		      p = frag_more (1 + length);		      know (operandP->vop_reg >= 0);		      p[0] = operandP->vop_reg			| ((at | "?\12\14?\16"[length]) << 4);		      if (to_seg == SEG_ABSOLUTE)			{			  md_number_to_chars (p + 1, this_add_number, length);			}		      else			{			  fix_new (frag_now, p + 1 - frag_now->fr_literal,				   length, this_add_symbol,				   this_add_number, 0, NO_RELOC);			}		    }		}	    }			/* if(single-byte-operand) */	}    }				/* for(operandP) */}				/* vax_assemble() *//* md_estimate_size_before_relax(), called just before relax().   Any symbol that is now undefined will not become defined.   Return the correct fr_subtype in the frag and the growth beyond   fr_fix.  */intmd_estimate_size_before_relax (fragP, segment)     fragS *fragP;     segT segment;{  if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)    {      if (S_GET_SEGMENT (fragP->fr_symbol) != segment)	{	  /* Non-relaxable cases.  */	  char *p;	  int old_fr_fix;	  old_fr_fix = fragP->fr_fix;	  p = fragP->fr_literal + old_fr_fix;	  switch (RELAX_STATE (fragP->fr_subtype))	    {	    case STATE_PC_RELATIVE:	      p[0] |= VAX_PC_RELATIVE_MODE;	/* Preserve @ bit.  */	      fragP->fr_fix += 1 + 4;	      fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol,		       fragP->fr_offset, 1, NO_RELOC);	      break;	    case STATE_CONDITIONAL_BRANCH:	      *fragP->fr_opcode ^= 1;		/* Reverse sense of branch.  */	      p[0] = 6;	      p[1] = VAX_JMP;	      p[2] = VAX_PC_RELATIVE_MODE;	/* ...(PC) */	      fragP->fr_fix += 1 + 1 + 1 + 4;	      fix_new (fragP, old_fr_fix + 3, 4, fragP->fr_symbol,		       fragP->fr_offset, 1, NO_RELOC);	      break;	    case STATE_COMPLEX_BRANCH:	      p[0] = 2;	      p[1] = 0;	      p[2] = VAX_BRB;	      p[3] = 6;	      p[4] = VAX_JMP;	      p[5] = VAX_PC_RELATIVE_MODE;	/* ...(pc) */	      fragP->fr_fix += 2 + 2 + 1 + 1 + 4;	      fix_new (fragP, old_fr_fix + 6, 4, fragP->fr_symbol,		       fragP->fr_offset, 1, NO_RELOC);	      break;	    case STATE_COMPLEX_HOP:	      p[0] = 2;	      p[1] = VAX_BRB;	      p[2] = 6;	      p[3] = VAX_JMP;	      p[4] = VAX_PC_RELATIVE_MODE;	/* ...(pc) */	      fragP->fr_fix += 1 + 2 + 1 + 1 + 4;	      fix_new (fragP, old_fr_fix + 5, 4, fragP->fr_symbol,		       fragP->fr_offset, 1, NO_RELOC);	      break;	    case STATE_ALWAYS_BRANCH:	      *fragP->fr_opcode += VAX_WIDEN_LONG;	      p[0] = VAX_PC_RELATIVE_MODE;	/* ...(PC) */	      fragP->fr_fix += 1 + 4;	      fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol,		       fragP->fr_offset, 1, NO_RELOC);	      break;	    default:	      abort ();	    }	  frag_wane (fragP);	  /* Return the growth in the fixed part of the frag.  */	  return fragP->fr_fix - old_fr_fix;	}      /* Relaxable cases.  Set up the initial guess for the variable	 part of the frag.  */      switch (RELAX_STATE (fragP->fr_subtype))	{	case STATE_PC_RELATIVE:	  fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);	  break;	case STATE_CONDITIONAL_BRANCH:	  fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE);	  break;	case STATE_COMPLEX_BRANCH:	  fragP->fr_subtype = ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_WORD);	  break;	case STATE_COMPLEX_HOP:	  fragP->fr_subtype = ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_BYTE);	  break;	case STATE_ALWAYS_BRANCH:	  fragP->fr_subtype = ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE);	  break;	}    }  if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))    abort ();  /* Return the size of the variable part of the frag.  */  return md_relax_table[fragP->fr_subtype].rlx_length;}/* *			md_convert_frag(); * * Called after relax() is finished. * In:	Address of frag. *	fr_type == rs_machine_dependent. *	fr_subtype is what the address relaxed to. * * Out:	Any fixSs and constants are set up. *	Caller will turn frag into a ".space 0". */voidmd_convert_frag (headers, seg, fragP)     object_headers *headers;     segT seg;     fragS *fragP;{  char *addressP;		/* -> _var to change.  */  char *opcodeP;		/* -> opcode char(s) to change.  */  short int extension = 0;	/* Size of relaxed address.  */  /* Added to fr_fix: incl. ALL var chars.  */  symbolS *symbolP;  long where;  long address_of_var;  /* Where, in file space, is _var of *fragP? */  long target_address = 0;  /* Where, in file space, does addr point? */  know (fragP->fr_type == rs_machine_dependent);  where = fragP->fr_fix;  addressP = fragP->fr_literal + where;  opcodeP = fragP->fr_opcode;  symbolP = fragP->fr_symbol;  know (symbolP);  target_address = S_GET_VALUE (symbolP) + fragP->fr_offset;  address_of_var = fragP->fr_address + where;

⌨️ 快捷键说明

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