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

📄 tc-vax.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
 * You MUST have called vip_begin() once before using this function. */static voidvip (vitP, instring)     struct vit *vitP;		/* We build an exploded instruction here.  */     char *instring;		/* Text of a vax instruction: we modify.  */{  /* How to bit-encode this opcode.  */  struct vot_wot *vwP;  /* 1/skip whitespace.2/scan vot_how */  char *p;  char *q;  /* counts number of operands seen */  unsigned char count;  /* scan operands in struct vit */  struct vop *operandp;  /* error over all operands */  const char *alloperr;  /* Remember char, (we clobber it with '\0' temporarily).  */  char c;  /* Op-code of this instruction.  */  vax_opcodeT oc;  if (*instring == ' ')    ++instring;			/* Skip leading whitespace.  */  for (p = instring; *p && *p != ' '; p++);;	/* MUST end in end-of-string or exactly 1 space.  */  /* Scanned up to end of operation-code.  */  /* Operation-code is ended with whitespace.  */  if (p - instring == 0)    {      vitP->vit_error = _("No operator");      count = 0;      memset (vitP->vit_opcode, '\0', sizeof (vitP->vit_opcode));    }  else    {      c = *p;      *p = '\0';      /*       * Here with instring pointing to what better be an op-name, and p       * pointing to character just past that.       * We trust instring points to an op-name, with no whitespace.       */      vwP = (struct vot_wot *) hash_find (op_hash, instring);      *p = c;			/* Restore char after op-code.  */      if (vwP == 0)	{	  vitP->vit_error = _("Unknown operator");	  count = 0;	  memset (vitP->vit_opcode, '\0', sizeof (vitP->vit_opcode));	}      else	{	  /*	   * We found a match! So let's pick up as many operands as the	   * instruction wants, and even gripe if there are too many.	   * We expect comma to seperate each operand.	   * We let instring track the text, while p tracks a part of the	   * struct vot.	   */	  const char *howp;	  /*	   * The lines below know about 2-byte opcodes starting FD,FE or FF.	   * They also understand synthetic opcodes. Note:	   * we return 32 bits of opcode, including bucky bits, BUT	   * an opcode length is either 8 or 16 bits for vit_opcode_nbytes.	   */	  oc = vwP->vot_code;	/* The op-code.  */	  vitP->vit_opcode_nbytes = (oc & 0xFF) >= 0xFD ? 2 : 1;	  md_number_to_chars (vitP->vit_opcode, oc, 4);	  count = 0;		/* no operands seen yet */	  instring = p;		/* point just past operation code */	  alloperr = "";	  for (howp = vwP->vot_how, operandp = vitP->vit_operand;	       !(alloperr && *alloperr) && *howp;	       operandp++, howp += 2)	    {	      /*	       * Here to parse one operand. Leave instring pointing just	       * past any one ',' that marks the end of this operand.	       */	      if (!howp[1])		as_fatal (_("odd number of bytes in operand description"));	      else if (*instring)		{		  for (q = instring; (c = *q) && c != ','; q++)		    ;		  /*		   * Q points to ',' or '\0' that ends argument. C is that		   * character.		   */		  *q = 0;		  operandp->vop_width = howp[1];		  operandp->vop_nbytes = vax_operand_width_size[(unsigned) howp[1]];		  operandp->vop_access = howp[0];		  vip_op (instring, operandp);		  *q = c;	/* Restore input text.  */		  if (operandp->vop_error)		    alloperr = _("Bad operand");		  instring = q + (c ? 1 : 0);	/* next operand (if any) */		  count++;	/*  won another argument, may have an operr */		}	      else		alloperr = _("Not enough operands");	    }	  if (!*alloperr)	    {	      if (*instring == ' ')		instring++;	/* Skip whitespace.  */	      if (*instring)		alloperr = _("Too many operands");	    }	  vitP->vit_error = alloperr;	}    }  vitP->vit_operands = count;}#ifdef test/* * Test program for above. */struct vit myvit;		/* build an exploded vax instruction here */char answer[100];		/* human types a line of vax assembler here */char *mybug;			/* "" or an internal logic diagnostic */int mycount;			/* number of operands */struct vop *myvop;		/* scan operands from myvit */int mysynth;			/* 1 means want synthetic opcodes.  */char my_immediate[200];char my_indirect[200];char my_displen[200];main (){  char *p;  printf ("0 means no synthetic instructions.   ");  printf ("Value for vip_begin?  ");  gets (answer);  sscanf (answer, "%d", &mysynth);  printf ("Synthetic opcodes %s be included.\n", mysynth ? "will" : "will not");  printf ("enter immediate symbols eg enter #   ");  gets (my_immediate);  printf ("enter indirect symbols  eg enter @   ");  gets (my_indirect);  printf ("enter displen symbols   eg enter ^   ");  gets (my_displen);  if (p = vip_begin (mysynth, my_immediate, my_indirect, my_displen))    {      error ("vip_begin=%s", p);    }  printf ("An empty input line will quit you from the vax instruction parser\n");  for (;;)    {      printf ("vax instruction: ");      fflush (stdout);      gets (answer);      if (!*answer)	{	  break;		/* out of for each input text loop */	}      vip (&myvit, answer);      if (*myvit.vit_error)	{	  printf ("ERR:\"%s\"\n", myvit.vit_error);	}      printf ("opcode=");      for (mycount = myvit.vit_opcode_nbytes, p = myvit.vit_opcode;	   mycount;	   mycount--, p++	)	{	  printf ("%02x ", *p & 0xFF);	}      printf ("   operand count=%d.\n", mycount = myvit.vit_operands);      for (myvop = myvit.vit_operand; mycount; mycount--, myvop++)	{	  printf ("mode=%xx reg=%xx ndx=%xx len='%c'=%c%c%d. expr=\"",		  myvop->vop_mode, myvop->vop_reg, myvop->vop_ndx,		  myvop->vop_short, myvop->vop_access, myvop->vop_width,		  myvop->vop_nbytes);	  for (p = myvop->vop_expr_begin; p <= myvop->vop_expr_end; p++)	    {	      putchar (*p);	    }	  printf ("\"\n");	  if (myvop->vop_error)	    {	      printf ("  err:\"%s\"\n", myvop->vop_error);	    }	  if (myvop->vop_warn)	    {	      printf ("  wrn:\"%s\"\n", myvop->vop_warn);	    }	}    }  vip_end ();  exit (EXIT_SUCCESS);}#endif /* #ifdef test *//* end of vax_ins_parse.c *//* vax_reg_parse.c - convert a VAX register name to a number *//* Copyright (C) 1987 Free Software Foundation, Inc. A part of GNU.  *//* *          v a x _ r e g _ p a r s e ( ) * * Take 3 char.s, the last of which may be `\0` (non-existent) * and return the VAX register number that they represent. * * Return -1 if they don't form a register name. Good names return * a number from 0:15 inclusive. * * Case is not important in a name. * * Register names understood are: * *	R0 *	R1 *	R2 *	R3 *	R4 *	R5 *	R6 * 	R7 *	R8 *	R9 *	R10 *	R11 *	R12	AP *	R13	FP *	R14	SP *	R15	PC * */#include <ctype.h>#define AP (12)#define FP (13)#define SP (14)#define PC (15)int				/* return -1 or 0:15 */vax_reg_parse (c1, c2, c3)	/* 3 chars of register name */     char c1, c2, c3;		/* c3 == 0 if 2-character reg name */{  int retval;		/* return -1:15 */  retval = -1;  if (isupper (c1))    c1 = tolower (c1);  if (isupper (c2))    c2 = tolower (c2);  if (isdigit (c2) && c1 == 'r')    {      retval = c2 - '0';      if (isdigit (c3))	{	  retval = retval * 10 + c3 - '0';	  retval = (retval > 15) ? -1 : retval;	  /* clamp the register value to 1 hex digit */	}      else if (c3)	retval = -1;		/* c3 must be '\0' or a digit */    }  else if (c3)			/* There are no three letter regs */    retval = -1;  else if (c2 == 'p')    {      switch (c1)	{	case 's':	  retval = SP;	  break;	case 'f':	  retval = FP;	  break;	case 'a':	  retval = AP;	  break;	default:	  retval = -1;	}    }  else if (c1 == 'p' && c2 == 'c')    retval = PC;  else    retval = -1;  return (retval);}/* *               v i p _ o p ( ) * * Parse a vax operand in DEC assembler notation. * For speed, expect a string of whitespace to be reduced to a single ' '. * This is the case for GNU AS, and is easy for other DEC-compatible * assemblers. * * Knowledge about DEC VAX assembler operand notation lives here. * This doesn't even know what a register name is, except it believes * all register names are 2 or 3 characters, and lets vax_reg_parse() say * what number each name represents. * It does, however, know that PC, SP etc are special registers so it can * detect addressing modes that are silly for those registers. * * Where possible, it delivers 1 fatal or 1 warning message if the operand * is suspect. Exactly what we test for is still evolving. *//* *		   	B u g s * *	Arg block. * * There were a number of 'mismatched argument type' bugs to vip_op. * The most general solution is to typedef each (of many) arguments. * We used instead a typedef'd argument block. This is less modular * than using seperate return pointers for each result, but runs faster * on most engines, and seems to keep programmers happy. It will have * to be done properly if we ever want to use vip_op as a general-purpose * module (it was designed to be). * *	G^ * * Doesn't support DEC "G^" format operands. These always take 5 bytes * to express, and code as modes 8F or 9F. Reason: "G^" deprives you of * optimising to (say) a "B^" if you are lucky in the way you link. * When someone builds a linker smart enough to convert "G^" to "B^", "W^" * whenever possible, then we should implement it. * If there is some other use for "G^", feel free to code it in! * * *	speed * * If I nested if()s more, I could avoid testing (*err) which would save * time, space and page faults. I didn't nest all those if()s for clarity * and because I think the mode testing can be re-arranged 1st to test the * commoner constructs 1st. Does anybody have statistics on this? * * * *	error messages * * In future, we should be able to 'compose' error messages in a scratch area * and give the user MUCH more informative error messages. Although this takes * a little more code at run-time, it will make this module much more self- * documenting. As an example of what sucks now: most error messages have * hardwired into them the DEC VAX metacharacters "#^@" which are nothing like * the Un*x characters "$`*", that most users will expect from this AS. *//* * The input is a string, ending with '\0'. * * We also require a 'hint' of what kind of operand is expected: so * we can remind caller not to write into literals for instance. * * The output is a skeletal instruction. * * The algorithm has two parts. * 1. extract the syntactic features (parse off all the @^#-()+[] mode crud); * 2. express the @^#-()+[] as some parameters suited to further analysis. * * 2nd step is where we detect the googles of possible invalid combinations * a human (or compiler) might write. Note that if we do a half-way * decent assembler, we don't know how long to make (eg) displacement * fields when we first meet them (because they may not have defined values). * So we must wait until we know how many bits are needed for each address, * then we can know both length and opcodes of instructions. * For reason(s) above, we will pass to our caller a 'broken' instruction * of these major components, from which our caller can generate instructions: *  -  displacement length      I^ S^ L^ B^ W^ unspecified *  -  mode                     (many) *  -  register                 R0-R15 or absent *  -  index register           R0-R15 or absent *  -  expression text          what we don't parse *  -  error text(s)            why we couldn't understand the operand *//* * To decode output of this, test errtxt. If errtxt[0] == '\0', then * we had no errors that prevented parsing. Also, if we ever report * an internal bug, errtxt[0] is set non-zero. So one test tells you * if the other outputs are to be taken seriously. *//* * Because this module is useful for both VMS and UN*X style assemblers * and because of the variety of UN*X assemblers we must recognise * the different conventions for assembler operand notation. For example * VMS says "#42" for immediate mode, while most UN*X say "$42". * We permit arbitrary sets of (single) characters to represent the * 3 concepts that DEC writes '#', '@', '^'. *//* character tests */#define VIP_IMMEDIATE 01	/* Character is like DEC # */#define VIP_INDIRECT  02	/* Char is like DEC @ */#define VIP_DISPLEN   04	/* Char is like DEC ^ */#define IMMEDIATEP(c)	(vip_metacharacters [(c)&0xff]&VIP_IMMEDIATE)#define INDIRECTP(c)	(vip_metacharacters [(c)&0xff]&VIP_INDIRECT)#define DISPLENP(c)	(vip_metacharacters [(c)&0xff]&VIP_DISPLEN)/* We assume 8 bits per byte. Use vip_op_defaults() to set these up BEFORE we * are ever called. */#if defined(CONST_TABLE)#define _ 0,#define I VIP_IMMEDIATE,#define S VIP_INDIRECT,#define D VIP_DISPLEN,static const charvip_metacharacters[256] ={  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _	/* ^@ ^A ^B ^C ^D ^E ^F ^G ^H ^I ^J ^K ^L ^M ^N ^O*/  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _	/* ^P ^Q ^R ^S ^T ^U ^V ^W ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */  _ _ 

⌨️ 快捷键说明

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