misc.c

来自「一个很有名的硬件模拟器。可以模拟CPU」· C语言 代码 · 共 1,190 行 · 第 1/2 页

C
1,190
字号
	    val = (largeint_t)va_arg(v, word_t);	  /* set buffer pointer to last digit */	  p = bp = buf + MAXDIGS;	  if (val & HIBITL)	    *--bp = _lowdigit(&val);	  goto decimal;	case 'o':	  mradix = 7;	  lradix = 2;	  goto fixed;	case 'p': /* target address */	  if (sizeof(md_addr_t) > 4)	    flagword |= LENGTH;	  /* fallthru */	case 'X':	case 'x':	  mradix = 15;	  lradix = 3;	fixed:	  /* fetch the argument to be printed */	  if (flagword & LENGTH)	    val = va_arg(v, largeint_t);	  else	    val = (largeint_t)va_arg(v, word_t);	  /* set translate table for digits */	  tab = (fcode == 'X') ? "0123456789ABCDEF" : "0123456789abcdef";	  /* develop the digits of the value */	  p = bp = buf + MAXDIGS;	  {	    slargeint_t qval = val;	    if (qval == 0)	      {		otherlength = lzero = 1;		flagword |= LZERO;	      }	    else	      do {		*--bp = tab[qval & mradix];		qval = ((qval >> 1) & ~HIBITL) >> lradix;	      } while (qval != 0);	  }	  break;#ifndef HOST_HAS_QWORD	process_float:#endif /* !HOST_HAS_QWORD */	case 'f':	  if (flagword & DOTSEEN)	    sprintf(buf1, "%%%d.%df", width, prec);	  else if (width)	    sprintf(buf1, "%%%df", width);	  else	    sprintf(buf1, "%%f");	  /* fetch the argument to be printed */	  fval = va_arg(v, dfloat_t);	  /* print floating point value */	  sprintf(buf, buf1, fval);	  bp = buf;	  p = bp + strlen(bp);	  break;	case 's':	  bp = va_arg(v, char *);	  if (bp == NULL)	    bp = "(null)";	  p = bp + strlen(bp);	  break;	case '%':	  buf[0] = fcode;	  goto c_merge;	case 'c':	  buf[0] = va_arg(v, int);	c_merge:	  p = (bp = &buf[0]) + 1;	  break;	default:	  /* this is technically an error; what we do is to back up the format             pointer to the offending char and continue with the format scan */	  format--;	  continue;	}      /* calculate number of padding blanks */      k = (n = p - bp) + prefixlength + otherlength;      if (width <= k)	count += k;      else	{	  count += width;	  /* set up for padding zeroes if requested; otherwise emit padding             blanks unless output is to be left-justified */	  if (flagword & PADZERO)	    {	      if (!(flagword & LZERO))		{		  flagword |= LZERO;		  lzero = width - k;		}	      else		lzero += width - k;	      /* cancel padding blanks */	      k = width;	    }	  else	    {	      /* blanks on left if required */	      PAD(_blanks, width - k);	    }	}      /* prefix, if any */      if (prefixlength != 0)	{	  PUT(prefix, prefixlength);	}      /* zeroes on the left */      if (flagword & LZERO)	{	  PAD(_zeroes, lzero);	}      /* the value itself */      if (n > 0)	{	  PUT(bp, n);	}    }}/* portable sprintf with qword support, returns end pointer */char *mysprintf(char *obuf, char *format, ...){  /* vararg parameters */  va_list v;  va_start(v, format);  return myvsprintf(obuf, format, v);}/* portable vfprintf with qword support, returns end pointer */voidmyvfprintf(FILE *stream, char *format, va_list v){  /* temp buffer */  char buf[2048];  myvsprintf(buf, format, v);  fputs(buf, stream);}/* portable fprintf with qword support, returns end pointer */voidmyfprintf(FILE *stream, char *format, ...){  /* temp buffer */  char buf[2048];  /* vararg parameters */  va_list v;  va_start(v, format);  myvsprintf(buf, format, v);  fputs(buf, stream);}#ifdef HOST_HAS_QWORD#define LL_MAX		LL(9223372036854775807)#define LL_MIN		(-LL_MAX - 1)#define ULL_MAX		(ULL(9223372036854775807) * ULL(2) + 1)/* convert a string to a signed result */sqword_tmyatosq(char *nptr, char **endp, int base){  char *s, *save;  int negative, overflow;  sqword_t cutoff, cutlim, i;  unsigned char c;  extern int errno;  if (!nptr || !*nptr)    panic("strtoll() passed a NULL string");  s = nptr;  /* skip white space */  while (isspace((int)(*s)))    ++s;  if (*s == '\0')    goto noconv;  if (base == 0)    {      if (s[0] == '0' && toupper(s[1]) == 'X')	base = 16;      else	base = 10;    }  if (base <= 1 || base > 36)    panic("bogus base: %d", base);  /* check for a sign */  if (*s == '-')    {      negative = 1;      ++s;    }  else if (*s == '+')    {      negative = 0;      ++s;    }  else    negative = 0;  if (base == 16 && s[0] == '0' && toupper(s[1]) == 'X')    s += 2;  /* save the pointer so we can check later if anything happened */  save = s;  cutoff = LL_MAX / (unsigned long int) base;  cutlim = LL_MAX % (unsigned long int) base;  overflow = 0;  i = 0;  for (c = *s; c != '\0'; c = *++s)    {      if (isdigit (c))        c -= '0';      else if (isalpha (c))        c = toupper(c) - 'A' + 10;      else        break;      if (c >= base)        break;      /* check for overflow */      if (i > cutoff || (i == cutoff && c > cutlim))        overflow = 1;      else        {          i *= (unsigned long int) base;          i += c;        }    }  /* check if anything actually happened */  if (s == save)    goto noconv;  /* store in ENDP the address of one character past the last character     we converted */  if (endp != NULL)    *endp = (char *) s;  if (overflow)    {      errno = ERANGE;      return negative ? LL_MIN : LL_MAX;    }  else    {      errno = 0;      /* return the result of the appropriate sign */      return (negative ? -i : i);    }noconv:  /* there was no number to convert */  if (endp != NULL)    *endp = (char *) nptr;  return 0;}/* convert a string to a unsigned result */qword_tmyatoq(char *nptr, char **endp, int base){  char *s, *save;  int overflow;  qword_t cutoff, cutlim, i;  unsigned char c;  extern int errno;  if (!nptr || !*nptr)    panic("strtoll() passed a NULL string");  s = nptr;  /* skip white space */  while (isspace((int)(*s)))    ++s;  if (*s == '\0')    goto noconv;  if (base == 0)    {      if (s[0] == '0' && toupper(s[1]) == 'X')	base = 16;      else	base = 10;    }  if (base <= 1 || base > 36)    panic("bogus base: %d", base);  if (base == 16 && s[0] == '0' && toupper(s[1]) == 'X')    s += 2;  /* save the pointer so we can check later if anything happened */  save = s;  cutoff = ULL_MAX / (unsigned long int) base;  cutlim = ULL_MAX % (unsigned long int) base;  overflow = 0;  i = 0;  for (c = *s; c != '\0'; c = *++s)    {      if (isdigit (c))        c -= '0';      else if (isalpha (c))        c = toupper(c) - 'A' + 10;      else        break;      if (c >= base)        break;      /* check for overflow */      if (i > cutoff || (i == cutoff && c > cutlim))        overflow = 1;      else        {          i *= (unsigned long int) base;          i += c;        }    }  /* check if anything actually happened */  if (s == save)    goto noconv;  /* store in ENDP the address of one character past the last character     we converted */  if (endp != NULL)    *endp = (char *) s;  if (overflow)    {      errno = ERANGE;      return ULL_MAX;    }  else    {      errno = 0;      /* return the result of the appropriate sign */      return i;    }noconv:  /* there was no number to convert */  if (endp != NULL)    *endp = (char *) nptr;  return 0;}#ifdef TESTITvoidtestit(char *s){  char buf[128];  qword_t qval;  qval = myatoq(s, NULL, 10);  myqtoa(qval, "%x", buf, NULL);  fprintf(stderr, "x:    %s\n", buf);  myqtoa(qval, "%16x", buf, NULL);  fprintf(stderr, "16x:  %s\n", buf);  myqtoa(qval, "%016x", buf, NULL);  fprintf(stderr, "016x: %s\n", buf);  myqtoa(qval, "0x%016x", buf, NULL);  fprintf(stderr, "0x016x: %s\n", buf);  myqtoa(qval, "0x%08x", buf, NULL);  fprintf(stderr, "0x08x: %s\n", buf);  myqtoa(qval, "%d", buf, NULL);  fprintf(stderr, "d:    %s\n", buf);  myqtoa(qval, "%22d", buf, NULL);  fprintf(stderr, "22d:  %s\n", buf);  myqtoa(qval, "%022d", buf, NULL);  fprintf(stderr, "022d: %s\n", buf);  myqtoa(qval, "%u", buf, NULL);  fprintf(stderr, "u:    %s\n", buf);  myqtoa(qval, "%o", buf, NULL);  fprintf(stderr, "o:    %s\n", buf);}voidstestit(char *s){  char buf[128];  sqword_t sqval;  sqval = myatosq(s, NULL, 10);  myqtoa(sqval, "%x", buf, NULL);  fprintf(stderr, "x: %s\n", buf);  myqtoa(sqval, "%d", buf, NULL);  fprintf(stderr, "d: %s\n", buf);  myqtoa(sqval, "%u", buf, NULL);  fprintf(stderr, "u: %s\n", buf);}voidxtestit(char *s){  char buf[128];  qword_t qval;  qval = myatoq(s, NULL, 16);  myqtoa(qval, "%x", buf, NULL);  fprintf(stderr, "x: %s\n", buf);  myqtoa(qval, "%d", buf, NULL);  fprintf(stderr, "d: %s\n", buf);  myqtoa(qval, "%u", buf, NULL);  fprintf(stderr, "u: %s\n", buf);}#endif /* TESTIT */#endif /* HOST_HAS_QWORD */#ifdef GZIP_PATHstatic struct {  char *type;  char *ext;  char *cmd;} gzcmds[] = {  /* type */	/* extension */		/* command */  { "r",	".gz",			"%s -dc %s" },  { "rb",	".gz",			"%s -dc %s" },  { "r",	".Z",			"%s -dc %s" },  { "rb",	".Z",			"%s -dc %s" },  { "w",	".gz",			"%s > %s" },  { "wb",	".gz",			"%s > %s" }};/* same semantics as fopen() except that filenames ending with a ".gz" or ".Z"   will be automagically get compressed */FILE *gzopen(char *fname, char *type){  int i;  char *cmd = NULL, *ext;  FILE *fd;  char str[2048];  /* get the extension */  ext = mystrrchr(fname, '.');  /* check if extension indicates compressed file */  if (ext != NULL && *ext != '\0')    {      for (i=0; i < N_ELT(gzcmds); i++)	{	  if (!strcmp(gzcmds[i].type, type) && !strcmp(gzcmds[i].ext, ext))	    {	      cmd = gzcmds[i].cmd;	      break;	    }	}    }  if (!cmd)    {      /* open file */      fd = fopen(fname, type);    }  else    {      /* open pipe to compressor/decompressor */      sprintf(str, cmd, GZIP_PATH, fname);      fd = popen(str, type);    }  return fd;}/* close compressed stream */voidgzclose(FILE *fd){  /* attempt pipe close, otherwise file close */  if (pclose(fd) == -1)    fclose(fd);}#else /* !GZIP_PATH */FILE *gzopen(char *fname, char *type){  return fopen(fname, type);}voidgzclose(FILE *fd){  fclose(fd);}#endif /* GZIP_PATH *//* compute 32-bit CRC one byte at a time using the high-bit first (big-endian)   bit ordering convention */#define POLYNOMIAL 0x04c11db7Lstatic int crc_init = FALSE;static unsigned long crc_table[256];/* generate the table of CRC remainders for all possible bytes */static voidcrc_gentab(void){  int i, j;  word_t crc_accum;  for (i=0; i < 256; i++)    {      crc_accum = ((unsigned long)i << 24);      for (j=0; j < 8; j++)	{	  if (crc_accum & 0x80000000L)	    crc_accum = (crc_accum << 1) ^ POLYNOMIAL;	  else	    crc_accum = (crc_accum << 1);	}      crc_table[i] = crc_accum;    }  return;}/* update the CRC on the data block one byte at a time */word_tcrc(word_t crc_accum, word_t data){  int i, j;  if (!crc_init)    {      crc_gentab();      crc_init = TRUE;    }  for (j=0; j < sizeof(word_t); j++)    {      i = ((int)(crc_accum >> 24) ^ (data >> (j*8))) & 0xff;      crc_accum = (crc_accum << 8) ^ crc_table[i];    }  return crc_accum;}

⌨️ 快捷键说明

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