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

📄 ia64-gen.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 5 页
字号:
      totbits += 16;    }  /* Now allocate the space.  */  needed_bytes = (totbits + 7) / 8;  if ((needed_bytes + insn_list_len) > tot_insn_list_len)    {      tot_insn_list_len += 256;      insn_list = (unsigned char *) xrealloc (insn_list, tot_insn_list_len);    }  our_offset = insn_list_len;  insn_list_len += needed_bytes;  memset (insn_list + our_offset, 0, needed_bytes);  /* Encode the skip entry by setting bit 6 set in the state op field,     and store the # of bits to skip immediately after.  */  if (ent->skip_flag)    {      bitsused += 5;      insn_list[our_offset + 0] |= 0x40 | ((ent->bits_to_skip >> 2) & 0xf);      insn_list[our_offset + 1] |= ((ent->bits_to_skip & 3) << 6);    }#define IS_ONLY_IFZERO(ENT) \  ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \   && (ENT)->disent == NULL && (ENT)->skip_flag == 0)  /* Store an "if (bit is zero)" instruction by setting bit 7 in the     state op field.  */  if (ent->bits[0] != NULL)    {      struct bittree *nent = ent->bits[0];      zero_count = 0;      insn_list[our_offset] |= 0x80;      /* We can encode sequences of multiple "if (bit is zero)" tests	 by storing the # of zero bits to check in the lower 3 bits of	 the instruction.  However, this only applies if the state	 solely tests for a zero bit.  */      if (IS_ONLY_IFZERO (ent))	{	  while (IS_ONLY_IFZERO (nent) && zero_count < 7)	    {	      nent = nent->bits[0];	      zero_count++;	    }	  insn_list[our_offset + 0] |= zero_count;	}      zero_dest = insn_list_len;      gen_dis_table (nent);    }  /* Now store the remaining tests.  We also handle a sole "termination     entry" by storing it as an "any bit" test.  */  for (x = 1; x < 3; x++)    {      if (ent->bits[x] != NULL || (x == 2 && ent->disent != NULL))	{	  struct bittree *i = ent->bits[x];	  int idest;	  int currbits = 15;	  if (i != NULL)	    {	      /* If the instruction being branched to only consists of		 a termination entry, use the termination entry as the		 place to branch to instead.  */	      if (i->bits[0] == NULL && i->bits[1] == NULL		  && i->bits[2] == NULL && i->disent != NULL)		{		  idest = i->disent->ournum;		  i = NULL;		}	      else		idest = insn_list_len - our_offset;	    }	  else	    idest = ent->disent->ournum;	  /* If the destination offset for the if (bit is 1) test is less 	     than 256 bytes away, we can store it as 8-bits instead of 16;	     the instruction has bit 5 set for the 16-bit address, and bit	     4 for the 8-bit address.  Since we've already allocated 16	     bits for the address we need to deallocate the space.	     Note that branchings within the table are relative, and	     there are no branches that branch past our instruction yet	     so we do not need to adjust any other offsets.  */	  if (x == 1)	    {	      if (idest <= 256)		{		  int start = our_offset + bitsused / 8 + 1;		  memmove (insn_list + start,			   insn_list + start + 1,			   insn_list_len - (start + 1));		  currbits = 7;		  totbits -= 8;		  needed_bytes--;		  insn_list_len--;		  insn_list[our_offset] |= 0x10;		  idest--;		}	      else		insn_list[our_offset] |= 0x20;	    }	  else	    {	      /* An instruction which solely consists of a termination		 marker and whose disassembly name index is < 4096		 can be stored in 16 bits.  The encoding is slightly		 odd; the upper 4 bits of the instruction are 0x3, and		 bit 3 loses its normal meaning.  */	      if (ent->bits[0] == NULL && ent->bits[1] == NULL		  && ent->bits[2] == NULL && ent->skip_flag == 0		  && ent->disent != NULL		  && ent->disent->ournum < (32768 + 4096))		{		  int start = our_offset + bitsused / 8 + 1;		  memmove (insn_list + start,			   insn_list + start + 1,			   insn_list_len - (start + 1));		  currbits = 11;		  totbits -= 5;		  bitsused--;		  needed_bytes--;		  insn_list_len--;		  insn_list[our_offset] |= 0x30;		  idest &= ~32768;		}	      else		insn_list[our_offset] |= 0x08;	    }	  if (debug)	    {	      int id = idest;	      if (i == NULL)		id |= 32768;	      else if (! (id & 32768))		id += our_offset;	      if (x == 1)		printf ("%d: if (1) goto %d\n", our_offset, id);	      else		printf ("%d: try %d\n", our_offset, id);	    }	  /* Store the address of the entry being branched to.  */	  while (currbits >= 0)	    {	      unsigned char *byte = insn_list + our_offset + bitsused / 8;	      if (idest & (1 << currbits))		*byte |= (1 << (7 - (bitsused % 8)));	      bitsused++;	      currbits--;	    }	  /* Now generate the states for the entry being branched to.  */	  if (i != NULL)	    gen_dis_table (i);	}    }  if (debug)    {      if (ent->skip_flag)	printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip);        if (ent->bits[0] != NULL)	printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1,		zero_dest);    }  if (bitsused != totbits)    abort ();}static voidprint_dis_table (void){  int x;  struct disent *cent = disinsntable;  printf ("static const char dis_table[] = {\n");  for (x = 0; x < insn_list_len; x++)    {      if ((x > 0) && ((x % 12) == 0))	printf ("\n");      printf ("0x%02x, ", insn_list[x]);    }  printf ("\n};\n\n");  printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n");  while (cent != NULL)    {      struct disent *ent = cent;      while (ent != NULL)	{	  printf ("{ 0x%x, %d, %d, %d },\n", ent->completer_index,		  ent->insn, (ent->nexte != NULL ? 1 : 0),                  ent->priority);	  ent = ent->nexte;	}      cent = cent->next_ent;    }  printf ("};\n\n");}static voidgenerate_disassembler (void){  int i;  bittree = make_bittree_entry ();  for (i = 0; i < otlen; i++)    {      struct main_entry *ptr = ordered_table[i];      if (ptr->opcode->type != IA64_TYPE_DYN)	add_dis_entry (bittree,		       ptr->opcode->opcode, ptr->opcode->mask, 		       ptr->main_index,		       ptr->completers, 1);    }  compact_distree (bittree);  finish_distable ();  gen_dis_table (bittree);  print_dis_table ();}static voidprint_string_table (void){  int x;  char lbuf[80], buf[80];  int blen = 0;  printf ("static const char * const ia64_strings[] = {\n");  lbuf[0] = '\0';  for (x = 0; x < strtablen; x++)    {      int len;            if (strlen (string_table[x]->s) > 75)	abort ();      sprintf (buf, " \"%s\",", string_table[x]->s);      len = strlen (buf);      if ((blen + len) > 75)	{	  printf (" %s\n", lbuf);	  lbuf[0] = '\0';	  blen = 0;	}      strcat (lbuf, buf);      blen += len;    }  if (blen > 0)    printf (" %s\n", lbuf);  printf ("};\n\n");}static struct completer_entry **glist;static int glistlen = 0;static int glisttotlen = 0;/* If the completer trees ENT1 and ENT2 are equal, return 1.  */static intcompleter_entries_eq (ent1, ent2)     struct completer_entry *ent1, *ent2;{  while (ent1 != NULL && ent2 != NULL)    {      if (ent1->name->num != ent2->name->num	  || ent1->bits != ent2->bits	  || ent1->mask != ent2->mask	  || ent1->is_terminal != ent2->is_terminal          || ent1->dependencies != ent2->dependencies          || ent1->order != ent2->order)	return 0;      if (! completer_entries_eq (ent1->addl_entries, ent2->addl_entries))	return 0;      ent1 = ent1->alternative;      ent2 = ent2->alternative;    }  return ent1 == ent2;}/* Insert ENT into the global list of completers and return it.  If an   equivalent entry (according to completer_entries_eq) already exists,   it is returned instead.  */static struct completer_entry *insert_gclist (struct completer_entry *ent){  if (ent != NULL)    {      int i;      int x;      int start = 0, end;      ent->addl_entries = insert_gclist (ent->addl_entries);      ent->alternative = insert_gclist (ent->alternative);      i = glistlen / 2;      end = glistlen;      if (glisttotlen == glistlen)	{	  glisttotlen += 20;	  glist = (struct completer_entry **)	    xrealloc (glist, sizeof (struct completer_entry *) * glisttotlen);	}      if (glistlen == 0)	{	  glist[0] = ent;	  glistlen = 1;	  return ent;	}      if (ent->name->num < glist[0]->name->num)	i = 0;      else if (ent->name->num > glist[end - 1]->name->num)	i = end;      else	{	  int c;	  while (1)	    {	      i = (start + end) / 2;	      c = ent->name->num - glist[i]->name->num;	      if (c < 0)		end = i - 1;	      else if (c == 0)		{		  while (i > 0 			 && ent->name->num == glist[i - 1]->name->num)		    i--;		  break;		}	      else		start = i + 1;	      if (start > end)		break;	    }	  if (c == 0)	    {	      while (i < glistlen)		{		  if (ent->name->num != glist[i]->name->num)		    break;		  if (completer_entries_eq (ent, glist[i]))		    return glist[i];		  i++;		}	    }	}      for (; i > 0 && i < glistlen; i--)	if (ent->name->num >= glist[i - 1]->name->num)	  break;      for (; i < glistlen; i++)	if (ent->name->num < glist[i]->name->num)	  break;      for (x = glistlen - 1; x >= i; x--)	glist[x + 1] = glist[x];      glist[i] = ent;      glistlen++;    }  return ent;}static intget_prefix_len (name)     const char *name;{  char *c;  if (name[0] == '\0')    return 0;  c = strchr (name, '.');  if (c != NULL)    return c - name;  else    return strlen (name);}static voidcompute_completer_bits (ment, ent)     struct main_entry *ment;     struct completer_entry *ent;{  while (ent != NULL)    {      compute_completer_bits (ment, ent->addl_entries);      if (ent->is_terminal)	{	  ia64_insn mask = 0;	  ia64_insn our_bits = ent->bits;	  struct completer_entry *p = ent->parent;	  ia64_insn p_bits;	  int x;	  while (p != NULL && ! p->is_terminal)	    p = p->parent;      	  if (p != NULL)	    p_bits = p->bits;	  else	    p_bits = ment->opcode->opcode;	  for (x = 0; x < 64; x++)	    {	      ia64_insn m = ((ia64_insn) 1) << x;	      if ((p_bits & m) != (our_bits & m))		mask |= m;	      else		our_bits &= ~m;	    }	  ent->bits = our_bits;	  ent->mask = mask;	}      else	{	  ent->bits = 0;	  ent->mask = 0;	}      ent = ent->alternative;    }}/* Find identical completer trees that are used in different   instructions and collapse their entries.  */static voidcollapse_redundant_completers (void){  struct main_entry *ptr;  int x;  for (ptr = maintable; ptr != NULL; ptr = ptr->next)    {      if (ptr->completers == NULL)	abort ()

⌨️ 快捷键说明

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