1 /* Copyright (c) 1991-2007 Pragmatic C Software Corp. */
2 
3 /*
4    This program is free software; you can redistribute it and/or modify it
5    under the terms of the GNU General Public License as published by the
6    Free Software Foundation; either version 2 of the License, or (at your
7    option) any later version.
8 
9    This program is distributed in the hope that it will be useful, but
10    WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License along
15    with this program; if not, write to the Free Software Foundation, Inc.,
16    59 Temple Place, Suite 330, Boston, MA, 02111-1307.
17 
18    We are selling our new Verilog compiler that compiles to X86 Linux
19    assembly language.  It is at least two times faster for accurate gate
20    level designs and much faster for procedural designs.  The new
21    commercial compiled Verilog product is called CVC.  For more information
22    on CVC visit our website at www.pragmatic-c.com/cvc.htm or contact
23    Andrew at avanvick@pragmatic-c.com
24 
25  */
26 
27 
28 /*
29  * various code macro definitions
30  * mostly for speed in long value processing
31  * notice these macros sometimes use globals and call procedures
32  * that are assumed to be defined
33  */
34 
35 /* DBG remove - */
36 extern void __push_itstk(struct itree_t *);
37 extern void __pop_itstk(void);
38 /* --- */
39 
40 /* these make only 1 or 2 percent different in worse case now */
41 /* RELEASE NOLONGERUSED MAYBE ADD --
42 #define __push_itstk(itp) \
43  do { \
44   __itstk[++__itspi] = __inst_ptr = (itp); \
45   __inst_mod = __inst_ptr->itip->imsym->el.emdp; \
46   __inum = __inst_ptr->itinum; \
47  } while (0)
48 --- */
49 
50 /* remove assign of nil to inst mod to improve speed if needed */
51 /* RELEASE NOLONGERUSED MAYBE ADD --
52 #define __pop_itstk() \
53  do { \
54   __inst_ptr = __itstk[--__itspi]; \
55   if (__itspi != -1) \
56    { \
57     __inst_mod = __inst_ptr->itip->imsym->el.emdp; \
58     __inum = __inst_ptr->itinum; \
59    } \
60   -* else { __inst_mod = NULL; __inum = 0xffffffff; } *- \
61   else __inst_mod = NULL; \
62  } while (0)
63 -- */
64 
65 /* DBG ??? add --
66 extern void __pop_xstk(void);
67 -- */
68 
69 /* --- release add */
70 #define __pop_xstk() __xspi--
71 /* -- */
72 
73 /* DBG ??? add --
74 extern struct xstk_t *__push_xstk(int32);
75 #define push_xstk_(xsp, blen) (xsp) = __push_xstk((blen))
76 --- */
77 
78 /* BEWARE - a and b parts must be contiguous because often refed as only a */
79 /*--- release add --- */
80 #define push_xstk_(xsp, blen) \
81  do { \
82   if (++__xspi >= __maxxnest) __grow_xstk(); \
83   (xsp) = __xstk[__xspi]; \
84   if (wlen_(blen) > (xsp)->xsawlen) __chg_xstk_width((xsp), wlen_(blen)); \
85   (xsp)->bp = &((xsp)->ap[wlen_(blen)]); \
86   (xsp)->xslen = (blen); \
87  } while (0)
88 /* --- */
89 
90 /* DBG ??? add --
91 extern struct xstk_t *__eval_xpr(struct expr_t *);
92 --- */
93 /* --- release add */
94 #define __eval_xpr __eval2_xpr
95 /* --- */
96 
97 /* DBG ??? add --- */
98 extern i_tev_ndx __alloc_tev(int32, struct itree_t *, word64);
99 #define alloc_tev_(tevpi, etyp, itp, absetime) \
100  (tevpi) = __alloc_tev((etyp), (itp), (absetime))
101 /*--- */
102 
103 /* -- ??? release add
104 #define alloc_tev_(tevpi, etyp, itp, absetime) \
105  do { \
106   register struct tev_t *tevp__; \
107   if (__tefreelsti != -1) \
108    { tevpi = __tefreelsti; __tefreelsti = __tevtab[__tefreelsti].tenxti; } \
109   else \
110    { \
111     if (++__numused_tevtab >= __size_tevtab) __grow_tevtab(); \
112     tevpi = __numused_tevtab; \
113    } \
114   tevp__ = &(__tevtab[tevpi]); \
115   memset(tevp__, 0, sizeof(struct tev_t)); \
116   tevp__->tetyp = etyp; \
117   tevp__->teitp = itp; \
118   tevp__->etime = absetime; \
119   tevp__->tenxti = -1; \
120  } while (0)
121 -- */
122 
123 #define ld_scalval_(ap, bp, bytp) \
124  do { \
125   (ap)[0] = (word32) ((bytp)[__inum]); \
126   (bp)[0] = ((ap)[0] >> 1) & 1L; \
127   (ap)[0] &= 1L; \
128  } while(0)
129 
130 /* LOOKATME _ notice this assumes av and bv values only occupy low bit */
131 #define st_scalval_(bp, av, bv) \
132  (bp)[__inum] = (byte) ((av) | ((bv) << 1))
133 
134 #define st2_scalval_(bp, val) (bp)[__inum] = (byte) (val)
135 
136 #define chg_st_scalval_(bp, av, bv) \
137  do { \
138   register word32 nval__; \
139   nval__ = (av) | ((bv) << 1); \
140   if (((word32) (bp)[__inum]) != (nval__)) \
141    { (bp)[__inum] = (byte) (nval__); __lhs_changed = TRUE; } \
142  } while(0)
143 
144 #define get_stwire_addr_(sbp, np) \
145  (sbp) = &((np)->nva.bp[np->nwid*__inum])
146 
147 /* DBG ??? add --
148 extern void __record_nchg(struct net_t *);
149 #define record_nchg_(np) __record_nchg(np)
150 --- */
151 
152 /* SJM 08/08/03 - can't assume caller turns off chged flag any more */
153 /* but one record called, it must be off for dctrl processing - not needed */
154 
155 /* recording var change macros */
156 /* DBG ??? release add --- */
157 #define record_nchg_(np) \
158  do { \
159   __lhs_changed = FALSE; \
160   if (np->nchg_has_dces) \
161    __wakeup_delay_ctrls(np, -1, -1); \
162   if (((np)->nchgaction[__inum] & NCHG_ALL_CHGED) == 0) __add_nchglst_el(np); \
163   if (((np)->nchgaction[__inum] & (NCHG_DMPVARNOW | NCHG_DMPVNOTCHGED)) \
164    == (NCHG_DMPVARNOW | NCHG_DMPVNOTCHGED)) \
165    { \
166     (np)->nchgaction[__inum] &= ~(NCHG_DMPVNOTCHGED); \
167     __add_dmpv_chglst_el(np); \
168    } \
169  } while (0)
170 
171 /* --- */
172 
173 /* DBG ??? add ---
174 extern void __record_sel_nchg(struct net_t *, int32, int32);
175 #define record_sel_nchg_(np, i1, i2) __record_sel_nchg(np, i1, i2)
176  --- */
177 
178 /* SJM 08/08/03 - can't assume caller turns off chged flag any more */
179 /* but one record called, it must be off for dctrl processing - not needed */
180 /* DBG ??? release add --- */
181 #define record_sel_nchg_(np, i1, i2) \
182  do { \
183   __lhs_changed = FALSE; \
184   if ((np)->dcelst != NULL) __wakeup_delay_ctrls(np, (i1), (i2)); \
185   if (((np)->nchgaction[__inum] & NCHG_ALL_CHGED) == 0) \
186    __add_select_nchglst_el((np), (i1), (i2)); \
187   if (((np)->nchgaction[__inum] & (NCHG_DMPVARNOW | NCHG_DMPVNOTCHGED)) \
188    == (NCHG_DMPVARNOW | NCHG_DMPVNOTCHGED)) \
189    { \
190     (np)->nchgaction[__inum] &= ~(NCHG_DMPVNOTCHGED); \
191     __add_dmpv_chglst_el(np); \
192    } \
193  } while (0)
194 /* --- */
195 
196 /* conversion macros */
197 #define valtoch_(c) (((c) < 10) ? '0' + (c) : 'a' + (c) - 10)
198 /* conversion from real to int32 in Verilog is rounding away from 0 */
199 #define ver_rint_(x) ((int32) (((x) >= 0.0) \
200   ? ((x) + 0.500000000) : ((x) - 0.500000000)))
201 #define ver_rword(x) ((word32) ((x) + 0.500000000))
202 
203 /* convert a 64 bit delay to no. of sim ticks */
204 #define cnv_num64to_ticks_(tickstim, inttim, mdp) \
205  (tickstim) = __itoticks_tab[__des_timeprec - (mdp)->mtime_units]*(inttim)
206 
207 /* value extraction macros */
208 #define get_packintowrd_(nva, inum, vecw) \
209  (((vecw) <= 4) ? ((word32) (nva).bp[(inum)]) \
210  : (((vecw) > 8) ? (nva).wp[(inum)] : (word32) (nva).hwp[(inum)]))
211 
212 #define st_packintowrd_(nva, ind, uwrd, vecw) \
213  (((vecw) <= 4) ? ((nva).bp[(ind)] = (byte) (uwrd)) \
214  : (((vecw) > 8) ? ((nva).wp[(ind)] = (uwrd)) : ((nva).hwp[(ind)] = (hword) (uwrd))))
215 
216 #define ubits_(blen) ((blen) & 0x1f)
217 #define wlen_(blen) (((blen) + 31) >> 5)
218 #define get_wofs_(bi) ((bi) >> 5)
219 #define get_bofs_(bi) ((bi) & 0x1f)
220 
221 /* version of ubits that returns 32 for all used not 0 */
222 #define ubits2_(blen) (((blen & 0x1f) == 0) ? WBITS : (blen & 0x1f))
223 
224 /* get conducting tranif state for cur. instance (for non input 3rd gate) */
225 /* possibilities are 1 on, 0 off, or 3 unknown */
226 #define get_tranif_onoff_(gp) \
227   (((gp)->gstate.wp[get_wofs_(2*__inum)] >> get_bofs_(2*__inum)) & 3L)
228 
229 /* -- unused */
230 /* #define cmpxlen(w1, b1, w2, b2) \ */
231 /*  (((w1)==(w2)) ? ((b1) - (b2)) : ((w1) - (w2))) */
232 
233 /* comparison macros */
234 #define cvt_wrdbool_(av, bv)  \
235  ((((av) & ~(bv)) != 0L) ? 1 : (((bv) != 0L) ? 3 : 0))
236 
237 #define vval_is0_(wp, blen) \
238  (((blen) <= WBITS) ? (*(wp) == 0L) : __wide_vval_is0((wp), (blen)))
239 
240 /* comparing entire 2 wlen section - unused in both must be 0 */
241 #define cmp_vval_(wp1, wp2, blen) \
242  memcmp((wp2), (wp1), (WRDBYTES*(wlen_(blen))))
243 #define cmp_wvval_(wp1, wp2, wlen) memcmp((wp2), (wp1), (WRDBYTES*wlen))
244 
245 /* bit load and store macros */
246 #define rhsbsel_(wp, bi) ((wp)[get_wofs_(bi)] >> get_bofs_(bi)) & 1L
247 
248 /* value change macros - can't assume no overlap here */
249 #define cp_walign_(dwp, swp, blen) \
250  memmove((dwp), (swp), (int32) (WRDBYTES*(wlen_(blen)))); \
251  (dwp)[wlen_(blen) - 1] &= __masktab[ubits_(blen)]
252 
253 #define zero_allbits_(wp, blen) memset(((wp)), 0, \
254  (int32) (WRDBYTES*(wlen_(blen))))
255 
256 #define one_allbits_(wp, blen) \
257  do { register int32 __i; \
258   for (__i = 0; __i < wlen_(blen); __i++) (wp)[__i] = ALL1W; \
259   (wp)[(wlen_(blen)) - 1] &= __masktab[ubits_(blen)]; \
260  } while (0)
261 
262 /* macro must be passed a byte pointer */
263 #define set_byteval_(sbp, len, stval) \
264  do { register int32 __i; \
265   for (__i = 0; __i < (len); __i++) (sbp)[__i] = ((byte) (stval)); \
266  } while (0)
267 
268 /* this macro may need to be surrounded by { } in some places */
269 #define set_regtox_(ap, bp, len) \
270  one_allbits_((ap), len); one_allbits_((bp), len);
271 
272 /* map index from source [i1:i2] to internal h:0 */
273 #define normalize_ndx_(ndxval, mi1, mi2) \
274  (((mi1) >= (mi2)) ? (ndxval - mi2) : (mi2 - ndxval))
275 
276 /* misc macros */
277 #define reg_fr_inhibit_(np) \
278  (np->nu2.qcval[2*__inum].qc_active \
279  || np->nu2.qcval[2*__inum + 1].qc_active)
280 
281 /* i/o macros */
282 
283 #define vis_white_(c) \
284  ((((__pv_ctv = __pv_ctab[(c) & 0x7f]) == 1) || __pv_ctv == 3) ? TRUE : FALSE)
285 
286 #define vis_nonnl_white_(c) ((__pv_ctab[(c) & 0x7f] == 1) ? TRUE : FALSE)
287 
288 /* notice this does not leave line null terminated */
289 #define addch_(ch) \
290  do { \
291   if (__cur_sofs >= __exprlinelen - 1) __chg_xprline_size(1); \
292   __exprline[__cur_sofs++] = (ch); \
293  } while (0)
294 
295 #define my_puts_(s, f) \
296  do { \
297    fputs((s), (f)); \
298    if ((f) == stdout && __log_s != NULL) fputs((s), __log_s); \
299   } while (0)
300 
301 #define my_putc_(c, f) \
302  do { \
303    fputc((c), (f)); \
304    if ((f) == stdout && __log_s != NULL) fputc((c), __log_s); \
305   } while (0)
306 
307 #define my_ungetc_(c, f) \
308  if (f == NULL) \
309  { if (c == EOF) *__visp->vichp = '\0'; else *(--__visp->vichp) = c; } \
310  else ungetc(c, f)
311 
312 /* must follow convention only immediately read char can be pushed back */
313 /* --- DBG remove ---
314 #define my_ungetc_(c, f) \
315   if (f == NULL) \
316    { \
317     if (c == EOF) \
318      { \
319       if (*__visp->vichp != '\0') __arg_terr(__FILE__, __LINE__); \
320       *__visp->vichp = '\0'; \
321      } \
322     else \
323      { \
324       (__visp->vichp)--; \
325       if (*__visp->vichp != c) __arg_terr(__FILE__, __LINE__); \
326       *(__visp->vichp) = c; \
327      } \
328    } \
329   else ungetc(c, f) \
330 ---- */
331