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

📄 tc-vax.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
	       * modified frag type and then coding up a frag for this	       * case will be easy. SEG_OP was invented for the	       * .words after a CASE opcode, and was never intended for	       * instruction operands.	       */	      need_pass_2 = 1;	      as_warn (_("Can't relocate expression"));	      break;	    case O_big:	      /* Preserve the bits.  */	      if (expP->X_add_number > 0)		{		  bignum_copy (generic_bignum, expP->X_add_number,			       floatP->low, SIZE_OF_LARGE_NUMBER);		}	      else		{		  know (expP->X_add_number < 0);		  flonum_copy (&generic_floating_point_number,			       floatP);		  if (strchr ("s i", operandP->vop_short))		    {		      /* Could possibly become S^# */		      flonum_gen2vax (-expP->X_add_number, floatP, literal_float);		      switch (-expP->X_add_number)			{			case 'f':			  can_be_short =			    (literal_float[0] & 0xFC0F) == 0x4000			    && literal_float[1] == 0;			  break;			case 'd':			  can_be_short =			    (literal_float[0] & 0xFC0F) == 0x4000			    && literal_float[1] == 0			    && literal_float[2] == 0			    && literal_float[3] == 0;			  break;			case 'g':			  can_be_short =			    (literal_float[0] & 0xFF81) == 0x4000			    && literal_float[1] == 0			    && literal_float[2] == 0			    && literal_float[3] == 0;			  break;			case 'h':			  can_be_short = ((literal_float[0] & 0xFFF8) == 0x4000					  && (literal_float[1] & 0xE000) == 0					  && literal_float[2] == 0					  && literal_float[3] == 0					  && literal_float[4] == 0					  && literal_float[5] == 0					  && literal_float[6] == 0					  && literal_float[7] == 0);			  break;			default:			  BAD_CASE (-expP->X_add_number);			  break;			}	/* switch (float type) */		    }		/* if (could want to become S^#...) */		}		/* bignum or flonum ? */	      if (operandP->vop_short == 's'		  || operandP->vop_short == 'i'		  || (operandP->vop_short == ' '		      && operandP->vop_reg == 0xF		      && (operandP->vop_mode & 0xE) == 0x8))		{		  /* Saw a '#'.  */		  if (operandP->vop_short == ' ')		    {		      /* We must chose S^ or I^.  */		      if (expP->X_add_number > 0)			{			  /* Bignum: Short literal impossible.  */			  operandP->vop_short = 'i';			  operandP->vop_mode = 8;			  operandP->vop_reg = 0xF;	/* VAX PC.  */			}		      else			{			  /* Flonum: Try to do it.  */			  if (can_be_short)			    {			      operandP->vop_short = 's';			      operandP->vop_mode = 0;			      operandP->vop_ndx = -1;			      operandP->vop_reg = -1;			      expP->X_op = O_constant;			    }			  else			    {			      operandP->vop_short = 'i';			      operandP->vop_mode = 8;			      operandP->vop_reg = 0xF;	/* VAX PC */			    }			}	/* bignum or flonum ? */		    }		/*  if #, but no S^ or I^ seen.  */		  /* No more ' ' case: either 's' or 'i'.  */		  if (operandP->vop_short == 's')		    {		      /* Wants to be a short literal.  */		      if (expP->X_add_number > 0)			{			  as_warn (_("Bignum not permitted in short literal. Immediate mode assumed."));			  operandP->vop_short = 'i';			  operandP->vop_mode = 8;			  operandP->vop_reg = 0xF;	/* VAX PC.  */			}		      else			{			  if (!can_be_short)			    {			      as_warn (_("Can't do flonum short literal: immediate mode used."));			      operandP->vop_short = 'i';			      operandP->vop_mode = 8;			      operandP->vop_reg = 0xF;	/* VAX PC.  */			    }			  else			    {	/* Encode short literal now.  */			      int temp = 0;			      switch (-expP->X_add_number)				{				case 'f':				case 'd':				  temp = literal_float[0] >> 4;				  break;				case 'g':				  temp = literal_float[0] >> 1;				  break;				case 'h':				  temp = ((literal_float[0] << 3) & 070)				    | ((literal_float[1] >> 13) & 07);				  break;				default:				  BAD_CASE (-expP->X_add_number);				  break;				}			      floatP->low[0] = temp & 077;			      floatP->low[1] = 0;			    }	/* if can be short literal float */			}	/* flonum or bignum ? */		    }		  else		    {		/* I^# seen: set it up if float.  */		      if (expP->X_add_number < 0)			{			  memcpy (floatP->low, literal_float, sizeof (literal_float));			}		    }		/* if S^# seen.  */		}	      else		{		  as_warn (_("A bignum/flonum may not be a displacement: 0x%lx used"),			   (expP->X_add_number = 0x80000000L));		  /* Chosen so luser gets the most offset bits to patch later.  */		}	      expP->X_add_number = floatP->low[0]		| ((LITTLENUM_MASK & (floatP->low[1])) << LITTLENUM_NUMBER_OF_BITS);	      /*	       * For the O_big case we have:	       * If vop_short == 's' then a short floating literal is in the	       *	lowest 6 bits of floatP -> low [0], which is	       *	big_operand_bits [---] [0].	       * If vop_short == 'i' then the appropriate number of elements	       *	of big_operand_bits [---] [...] are set up with the correct	       *	bits.	       * Also, just in case width is byte word or long, we copy the lowest	       * 32 bits of the number to X_add_number.	       */	      break;	    }	  if (input_line_pointer != operandP->vop_expr_end + 1)	    {	      as_warn ("Junk at end of expression \"%s\"", input_line_pointer);	      goofed = 1;	    }	  operandP->vop_expr_end[1] = c_save;	}    }				/* for(each operand) */  input_line_pointer = save_input_line_pointer;  if (need_pass_2 || goofed)    {      return;    }  /* Emit op-code.  */  /* Remember where it is, in case we want to modify the op-code later.  */  opcode_low_byteP = frag_more (v.vit_opcode_nbytes);  memcpy (opcode_low_byteP, v.vit_opcode, v.vit_opcode_nbytes);  opcode_as_number = md_chars_to_number (opcode_as_chars = v.vit_opcode, 4);  for (operandP = v.vit_operand,       expP = exp_of_operand,       segP = seg_of_operand,       floatP = float_operand,       end_operandP = v.vit_operand + v.vit_operands;       operandP < end_operandP;       operandP++,       floatP++,       segP++,       expP++)    {      if (operandP->vop_ndx >= 0)	{	  /* indexed addressing byte */	  /* Legality of indexed mode already checked: it is OK */	  FRAG_APPEND_1_CHAR (0x40 + operandP->vop_ndx);	}			/* if(vop_ndx>=0) */      /* Here to make main operand frag(s).  */      this_add_number = expP->X_add_number;      this_add_symbol = expP->X_add_symbol;      to_seg = *segP;      is_undefined = (to_seg == SEG_UNKNOWN);      at = operandP->vop_mode & 1;      length = (operandP->vop_short == 'b'		? 1 : (operandP->vop_short == 'w'		       ? 2 : (operandP->vop_short == 'l'			      ? 4 : 0)));      nbytes = operandP->vop_nbytes;      if (operandP->vop_access == 'b')	{	  if (to_seg == now_seg || is_undefined)	    {	      /* If is_undefined, then it might BECOME now_seg.  */	      if (nbytes)		{		  p = frag_more (nbytes);		  fix_new (frag_now, p - frag_now->fr_literal, nbytes,			   this_add_symbol, this_add_number, 1, NO_RELOC);		}	      else		{		/* to_seg==now_seg || to_seg == SEG_UNKNOWN */		  /* nbytes==0 */		  length_code = is_undefined ? STATE_UNDF : STATE_BYTE;		  if (opcode_as_number & VIT_OPCODE_SPECIAL)		    {		      if (operandP->vop_width == VAX_WIDTH_UNCONDITIONAL_JUMP)			{			  /* br or jsb */			  frag_var (rs_machine_dependent, 5, 1,			    ENCODE_RELAX (STATE_ALWAYS_BRANCH, length_code),				    this_add_symbol, this_add_number,				    opcode_low_byteP);			}		      else			{			  if (operandP->vop_width == VAX_WIDTH_WORD_JUMP)			    {			      length_code = STATE_WORD;			      /* JF: There is no state_byte for this one! */			      frag_var (rs_machine_dependent, 10, 2,					ENCODE_RELAX (STATE_COMPLEX_BRANCH, length_code),					this_add_symbol, this_add_number,					opcode_low_byteP);			    }			  else			    {			      know (operandP->vop_width == VAX_WIDTH_BYTE_JUMP);			      frag_var (rs_machine_dependent, 9, 1,			      ENCODE_RELAX (STATE_COMPLEX_HOP, length_code),					this_add_symbol, this_add_number,					opcode_low_byteP);			    }			}		    }		  else		    {		      know (operandP->vop_width == VAX_WIDTH_CONDITIONAL_JUMP);		      frag_var (rs_machine_dependent, 7, 1,		       ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, length_code),				this_add_symbol, this_add_number,				opcode_low_byteP);		    }		}	    }	  else	    {	      /* to_seg != now_seg && to_seg != SEG_UNKNOWN */	      /*	       * --- SEG FLOAT MAY APPEAR HERE ----	       */	      if (to_seg == SEG_ABSOLUTE)		{		  if (nbytes)		    {		      know (!(opcode_as_number & VIT_OPCODE_SYNTHETIC));		      p = frag_more (nbytes);		      /* Conventional relocation.  */		      fix_new (frag_now, p - frag_now->fr_literal,			       nbytes, &abs_symbol, this_add_number,			       1, NO_RELOC);		    }		  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 */			      *opcode_low_byteP = opcode_as_chars[0] + VAX_WIDEN_LONG;			      know (opcode_as_chars[1] == 0);			      p = frag_more (5);			      p[0] = VAX_ABSOLUTE_MODE;	/* @#...  */			      md_number_to_chars (p + 1, this_add_number, 4);			      /* Now (eg) JMP @#foo or JSB @#foo.  */			    }			  else			    {			      if (operandP->vop_width == VAX_WIDTH_WORD_JUMP)				{				  p = frag_more (10);				  p[0] = 2;				  p[1] = 0;				  p[2] = VAX_BRB;				  p[3] = 6;				  p[4] = VAX_JMP;				  p[5] = VAX_ABSOLUTE_MODE;	/* @#...  */				  md_number_to_chars (p + 6, this_add_number, 4);				  /*				   * Now (eg)	ACBx	1f				   *		BRB	2f				   *	1:	JMP	@#foo				   *	2:				   */				}			      else				{				  know (operandP->vop_width == VAX_WIDTH_BYTE_JUMP);				  p = frag_more (9);				  p[0] = 2;				  p[1] = VAX_BRB;				  p[2] = 6;				  p[3] = VAX_JMP;                                  p[4] = VAX_ABSOLUTE_MODE;     /* @#...  */				  md_number_to_chars (p + 5, this_add_number, 4);				  /*				   * Now (eg)	xOBxxx	1f				   *		BRB	2f				   *	1:	JMP	@#foo				   *	2:				   */				}			    }			}		      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, this_add_number,			       1, NO_RELOC);		    }		  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,				       this_add_number, 1, NO_RELOC);			      /* 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,					   this_add_number, 1, NO_RELOC);				  /*				   * Now (eg)	ACBx	1f				   *		BRB	2f				   *	1:	JMP	foo				   *	2:				   */				}

⌨️ 快捷键说明

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