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

📄 vax.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
			  else			    {			      /* b<cond> */			      *opcode_low_byteP ^= 1;	/* To reverse the condition in a VAX branch, complement the lowest order bit. */			      p = frag_more (7);			      p[0] = 6;			      p[1] = VAX_JMP;			      p[2] = VAX_ABSOLUTE_MODE;	/* @#... */			      md_number_to_chars (p + 3, this_add_number, 4);			      /*			       * Now (eg)	BLEQ	1f			       *		JMP	@#foo			       *	1:			       */			    }			}		    }		  else		    {		/* to_seg != now_seg && to_seg != SEG_UNKNOWN && to_Seg != SEG_ABSOLUTE */		      if (nbytes > 0)			{			  /* Pc-relative. Conventional relocation. */			  know (!(opcode_as_number & VIT_OPCODE_SYNTHETIC));			  p = frag_more (nbytes);			  fix_new (frag_now, p - frag_now->fr_literal,				nbytes, &abs_symbol, 0, this_add_number, 1);			}		      else			{			  know (opcode_as_number & VIT_OPCODE_SYNTHETIC);			  if (opcode_as_number & VIT_OPCODE_SPECIAL)			    {			      if (operandP->vop_width == VAX_WIDTH_UNCONDITIONAL_JUMP)				{				  /* br or jsb */				  know (opcode_as_chars[1] == 0);				  *opcode_low_byteP = opcode_as_chars[0] + VAX_WIDEN_LONG;				  p = frag_more (5);				  p[0] = VAX_PC_RELATIVE_MODE;				  fix_new (frag_now,					   p + 1 - frag_now->fr_literal, 4,					   this_add_symbol, 0,					   this_add_number, 1);				  /* Now eg JMP foo or JSB foo. */				}			      else				{				  if (operandP->vop_width == VAX_WIDTH_WORD_JUMP)				    {				      p = frag_more (10);				      p[0] = 0;				      p[1] = 2;				      p[2] = VAX_BRB;				      p[3] = 6;				      p[4] = VAX_JMP;				      p[5] = VAX_PC_RELATIVE_MODE;				      fix_new (frag_now,					    p + 6 - frag_now->fr_literal, 4,					       this_add_symbol, 0,					       this_add_number, 1);				      /*				       * Now (eg)	ACBx	1f				       *		BRB	2f				       *	1:	JMP	foo				       *	2:				       */				    }				  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, 0,					       this_add_number, 1);				      /*				       * 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, 0,				       this_add_number, 1);			    }			}		    }		}	    }	  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 < 0 || this_add_number >= 64)			{			  as_warn ("Short literal overflow(%d.), immediate mode assumed.", 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", seg_name[(int) now_seg], seg_name[(int) 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);			      /* JF is this array stuff really going to work? */			      p[0] = 0xF | ((at + "?\12\14?\16"[length]) << 4);			      fix_new (frag_now, p + 1 - frag_now->fr_literal,				       length, this_add_symbol, 0,				       this_add_number, 1);			    }			}		      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, 0,					   this_add_number, 1);				}			    }			}		    }		  else		    {		/* {@}{q^}foo(Rn) or S^# or I^# or # */		      if (operandP->vop_mode < 0xA)			{	/* # or S^# or I^# */			  /* know(   (length == 0 && operandP->vop_short == ' ')	\			       || (length >  0 && operandP->vop_short != ' ')); */			  if (length == 0			      && to_seg == SEG_ABSOLUTE			      && operandP->vop_mode == 8	/* No '@'. */			      && this_add_number < 64			      && this_add_number >= 0)			    {			      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)				{/* * 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)				    {				      bzero (p + 5, nbytes - 4);				    }				}			      else				{				  if (to_seg == SEG_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, 0,					       this_add_number, 0);				    }				}			    }			}		      else			{	/* {@}{q^}foo(Rn) */			  know ((length == 0 && operandP->vop_short == ' ') \			      ||(length > 0 && operandP->vop_short != ' '));			  if (length == 0)			    {			      if (to_seg == SEG_ABSOLUTE)				{				  register long int 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, 0,				       this_add_number, 0);			    }			}		    }		}		/* if(single-byte-operand) */	    }	}			/* for(operandP) */    }				/* if(!need_pass_2&&!goofed) */}				/* 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. * Return the initial "guess for fr_var" to caller. * The guess for fr_var is ACTUALLY the growth beyond fr_fix. * Whatever we do to grow fr_fix or fr_var contributes to our returned value. * Although it may not be explicit in the frag, pretend fr_var starts with a * 0 value. */intmd_estimate_size_before_relax (fragP, segment_type)     register fragS *fragP;     register int segment_type;	/* N_DATA or N_TEXT. */{  register char *p;  register int old_fr_fix;  old_fr_fix = fragP->fr_fix;  switch (fragP->fr_subtype)    {    case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF):      if ((fragP->fr_symbol->sy_type & N_TYPE) == segment_type)	{			/* A relaxable case. */	  fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);	}      else	{	  p = fragP->fr_literal + old_fr_fix;	  p[0] |= VAX_PC_RELATIVE_MODE;	/* Preserve @ bit. */	  fragP->fr_fix += 1 + 4;	  fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol, 0,		   fragP->fr_offset, 1);	  frag_wane (fragP);	}      break;    case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF):      if ((fragP->fr_symbol->sy_type & N_TYPE) == segment_type)	{	  fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE);	}      else	{	  p = fragP->fr_literal + old_fr_fix;	  *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, 0,		   fragP->fr_offset, 1);	  frag_wane (fragP);	}      break;    case ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_UNDF):      if ((fragP->fr_symbol->sy_type & N_TYPE) == segment_type)	{	  fragP->fr_subtype = ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_WORD);	}      else	{	  p = fragP->fr_literal + old_fr_fix;	  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, 0,		   fragP->fr_offset, 1);	  frag_wane (fragP);	}      break;    case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_UNDF):      if ((fragP->fr_symbol->sy_type & N_TYPE) == segment_type)	{	  fragP->fr_subtype = ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_BYTE);	}      else	{	  p = fragP->fr_literal + old_fr_fix;	  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, 0,		   fragP->fr_offset, 1);	  frag_wane (fragP);	}      break;    case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_UNDF):      if ((fragP->fr_symbol->sy_type & N_TYPE) == segment_type)	{	  fragP->fr_subtype = ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE);	}      else	{	  p = fragP->fr_literal + old_fr_fix;	  *fragP->fr_opcode += VAX_WIDEN_LONG;	  p[0] = VAX_PC_RELATIVE_MODE;	/* ...(PC) */

⌨️ 快捷键说明

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