/* * Copyright (c) 2002 Larry Doolittle (larry@doolittle.boa.org) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) #ident "$Id: vpip_to_dec.cc,v 1.3 2002/02/04 00:41:34 steve Exp $" #endif # include "config.h" # include "vpi_priv.h" # include # include # include /* for CHAR_BIT */ # include #ifdef HAVE_MALLOC_H # include #endif # include /* If you are allergic to malloc, you can set a stack memory allocation * here. Otherwise, malloc() is used for the temporary array, so the * conversion length is unlimited. */ /* #define MAX_DIGITS 20 */ #if SIZEOF_UNSIGNED_LONG * CHAR_BIT >= 64 #define BDIGITS 9 #define BASE 1000000000 #define BBITS 32 #define BMASK 0xffffffff #else #if SIZEOF_UNSIGNED_LONG * CHAR_BIT >= 32 #define BDIGITS 4 #define BASE 10000 #define BBITS 16 #define BMASK 0xffff #else #error apparent non-conforming word length #endif #endif #define B_IS0(x) ((x) == 0) #define B_IS1(x) ((x) == 1) #define B_ISX(x) ((x) == 2) #define B_ISZ(x) ((x) == 3) /* The program works by building a base BASE representation of the number * in the valv array. BBITS bits of the number can be put in at a time. * Previous values of each valv element are always less than BASE, the * input val is less than or equal to 2^BBITS, so (valv[i]<=0; --i) { segment[i] = '0' + v%10; v=v/10; } for (i=0; i vlen_alloc) { if (valv) free(valv); valv = (unsigned long*) calloc( vlen+ALLOC_MARGIN, sizeof (*valv)); if (!valv) {perror("malloc"); return 0; } vlen_alloc=vlen+ALLOC_MARGIN; } else { memset(valv,0,vlen*sizeof(valv[0])); } for (idx = 0; idx < mbits; idx += 1) { /* printf("%c ",bits[mbits-idx-1]); */ if (B_ISZ(bits[mbits-idx-1])) count_z++; else if (B_ISX(bits[mbits-idx-1])) count_x++; else if (!comp && B_IS1(bits[mbits-idx-1])) ++val; else if ( comp && B_IS0(bits[mbits-idx-1])) ++val; if ((mbits-idx-1)%BBITS==0) { /* make negative 2's complement, not 1's complement */ if (comp && idx==mbits-1) ++val; shift_in(valv,vlen,val); val=0; } else { val=val+val; } } if (count_x == nbits) { len = 1; buf[0] = 'x'; buf[1] = 0; } else if (count_x > 0) { len = 1; buf[0] = 'X'; buf[1] = 0; } else if (count_z == nbits) { len = 1; buf[0] = 'z'; buf[1] = 0; } else if (count_z > 0) { len = 1; buf[0] = 'Z'; buf[1] = 0; } else { int i; int zero_suppress=1; if (comp) { *buf++='-'; nbuf--; /* printf("-"); */ } for (i=vlen-1; i>=0; i--) { zero_suppress = write_digits(valv[i], &buf,&nbuf,zero_suppress); /* printf(",%.4u",valv[i]); */ } /* Awkward special case, since we don't want to * zero suppress down to nothing at all. The only * way we can still have zero_suppress on in the * comp=1 case is if mbits==0, and therefore vlen==0. * We represent 1'sb1 as "-1". */ if (zero_suppress) *buf++='0'+comp; /* printf("\n"); */ *buf='\0'; } /* hold on to the memory, since we expect to be called again. */ /* free(valv); */ return 0; }