scfx_utils.hh revision 12853:e23d6f09069a
1/*****************************************************************************
2
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements.  See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License.  You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied.  See the License for the specific language governing
16  permissions and limitations under the License.
17
18 *****************************************************************************/
19
20/*****************************************************************************
21
22  scfx_utils.h -
23
24  Original Author: Martin Janssen, Synopsys, Inc.
25
26 *****************************************************************************/
27
28/*****************************************************************************
29
30  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
31  changes you are making here.
32
33      Name, Affiliation, Date:
34  Description of Modification:
35
36 *****************************************************************************/
37
38// $Log: scfx_utils.h,v $
39// Revision 1.2  2009/02/28 00:26:20  acg
40//  Andy Goodrich: bug fixes.
41//
42// Revision 1.1.1.1  2006/12/15 20:31:36  acg
43// SystemC 2.2
44//
45// Revision 1.3  2006/01/13 18:53:58  acg
46// Andy Goodrich: added $Log command so that CVS comments are reproduced in
47// the source.
48//
49
50#ifndef __SYSTEMC_EXT_DT_FX_SCFX_UTILS_HH__
51#define __SYSTEMC_EXT_DT_FX_SCFX_UTILS_HH__
52
53#include "sc_fxdefs.hh"
54#include "scfx_params.hh"
55#include "scfx_string.hh"
56
57namespace sc_dt
58{
59
60// ----------------------------------------------------------------------------
61//  Find the most and least significant non-zero bits in a unsigned long
62// ----------------------------------------------------------------------------
63
64#define MSB_STATEMENT(n) if (x >> n) { x >>= n; i += n; }
65
66inline int
67scfx_find_msb(unsigned long x)
68{
69    int i = 0;
70#   if defined(SC_LONG_64)
71        MSB_STATEMENT(32);
72#   endif // defined(SC_LONG_64)
73    MSB_STATEMENT(16);
74    MSB_STATEMENT(8);
75    MSB_STATEMENT(4);
76    MSB_STATEMENT(2);
77    MSB_STATEMENT(1);
78    return i;
79}
80
81#undef MSB_STATEMENT
82
83#define LSB_STATEMENT(n) if (x << n) { x <<= n; i -= n; }
84
85inline int
86scfx_find_lsb(unsigned long x)
87{
88    int i;
89#   if defined(SC_LONG_64)
90        i = 63;
91        LSB_STATEMENT(32);
92#   else
93        i = 31;
94#   endif // defined(SC_LONG_64)
95    LSB_STATEMENT(16);
96    LSB_STATEMENT(8);
97    LSB_STATEMENT(4);
98    LSB_STATEMENT(2);
99    LSB_STATEMENT(1);
100    return i;
101}
102
103#undef LSB_STATEMENT
104
105
106// ----------------------------------------------------------------------------
107//  Utilities for parsing a character string number
108// ----------------------------------------------------------------------------
109
110inline int
111scfx_parse_sign(const char *&s, bool &sign_char)
112{
113    int sign = 1;
114
115    if (*s == '+') {
116        ++s;
117        sign_char = true;
118    } else if (*s == '-' ) {
119        sign = -1;
120        ++s;
121        sign_char = true;
122    } else {
123        sign_char = false;
124    }
125
126    return sign;
127}
128
129inline sc_numrep
130scfx_parse_prefix(const char *&s)
131{
132    if (s[0] == '0') {
133        switch (s[1]) {
134          case 'b':
135          case 'B':
136            {
137                if ((s[2] == 'u' || s[2] == 'U') &&
138                    (s[3] == 's' || s[3] == 'S')) {
139                    s += 4;
140                    return SC_BIN_US;
141                }
142                if ((s[2] == 's' || s[2] == 'S') &&
143                    (s[3] == 'm' || s[3] == 'M')) {
144                    s += 4;
145                    return SC_BIN_SM;
146                }
147                s += 2;
148                return SC_BIN;
149            }
150          case 'o':
151          case 'O':
152            {
153                if ((s[2] == 'u' || s[2] == 'U') &&
154                    (s[3] == 's' || s[3] == 'S')) {
155                    s += 4;
156                    return SC_OCT_US;
157                }
158                if ((s[2] == 's' || s[2] == 'S') &&
159                    (s[3] == 'm' || s[3] == 'M')) {
160                    s += 4;
161                    return SC_OCT_SM;
162                }
163                s += 2;
164                return SC_OCT;
165            }
166          case 'x':
167          case 'X':
168            {
169                if ((s[2] == 'u' || s[2] == 'U') &&
170                    (s[3] == 's' || s[3] == 'S')) {
171                    s += 4;
172                    return SC_HEX_US;
173                }
174                if ((s[2] == 's' || s[2] == 'S') &&
175                    (s[3] == 'm' || s[3] == 'M')) {
176                    s += 4;
177                    return SC_HEX_SM;
178                }
179                s += 2;
180                return SC_HEX;
181            }
182          case 'd':
183          case 'D':
184            {
185                s += 2;
186                return SC_DEC;
187            }
188          case 'c':
189          case 'C':
190            {
191                if ((s[2] == 's' || s[2] == 'S') &&
192                    (s[3] == 'd' || s[3] == 'D')) {
193                    s += 4;
194                    return SC_CSD;
195                }
196                break;
197            }
198          default:
199            break;
200        }
201    }
202
203    return SC_DEC;
204}
205
206inline int
207scfx_parse_base(const char *&s)
208{
209    const char *s1 = s + 1;
210
211    int base = 10;
212
213    if (*s == '0') {
214        switch (*s1) {
215          case 'b':
216          case 'B': base =  2; s += 2; break;
217          case 'o':
218          case 'O': base =  8; s += 2; break;
219          case 'd':
220          case 'D': base = 10; s += 2; break;
221          case 'x':
222          case 'X': base = 16; s += 2; break;
223        }
224    }
225
226    return base;
227}
228
229inline bool
230scfx_is_equal(const char *a, const char *b)
231{
232    while (*a != 0 && *b != 0 && *a == *b) {
233        ++ a;
234        ++ b;
235    }
236    return (*a == 0 && *b == 0);
237}
238
239inline bool
240scfx_is_nan(const char *s)
241{
242    return scfx_is_equal(s, "NaN");
243}
244
245inline bool
246scfx_is_inf(const char *s)
247{
248    return (scfx_is_equal(s, "Inf") || scfx_is_equal(s, "Infinity"));
249}
250
251inline bool
252scfx_exp_start(const char *s)
253{
254    if (*s == 'e' || *s == 'E') {
255        ++s;
256        if (*s == '+' || *s == '-')
257            return true;
258    }
259    return false;
260}
261
262inline bool
263scfx_is_digit(char c, sc_numrep numrep)
264{
265    bool is_digit;
266
267    switch(numrep) {
268      case SC_DEC:
269        {
270            switch(c) {
271              case '0': case '1': case '2': case '3': case '4':
272              case '5': case '6': case '7': case '8': case '9':
273                {
274                    is_digit = true;
275                    break;
276                }
277              default:
278                    is_digit = false;
279            }
280            break;
281        }
282      case SC_BIN:
283      case SC_BIN_US:
284      case SC_BIN_SM:
285        {
286            switch(c) {
287              case '0': case '1':
288                {
289                    is_digit = true;
290                    break;
291                }
292              default:
293                is_digit = false;
294            }
295            break;
296        }
297      case SC_OCT:
298      case SC_OCT_US:
299      case SC_OCT_SM:
300        {
301            switch(c) {
302              case '0': case '1': case '2': case '3':
303              case '4': case '5': case '6': case '7':
304                {
305                    is_digit = true;
306                    break;
307                }
308              default:
309                is_digit = false;
310            }
311            break;
312        }
313      case SC_HEX:
314      case SC_HEX_US:
315      case SC_HEX_SM:
316        {
317            switch (c) {
318              case '0': case '1': case '2': case '3': case '4':
319              case '5': case '6': case '7': case '8': case '9':
320              case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
321              case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
322                {
323                    is_digit = true;
324                    break;
325                }
326              default:
327                is_digit = false;
328            }
329            break;
330        }
331      case SC_CSD:
332        {
333            switch (c) {
334              case '0': case '1': case '-':
335                {
336                    is_digit = true;
337                    break;
338                }
339              default:
340                is_digit = false;
341            }
342            break;
343        }
344      default:
345        is_digit = false;
346    }
347
348    return is_digit;
349}
350
351inline int
352scfx_to_digit(char c, sc_numrep numrep)
353{
354    int to_digit;
355
356    switch (numrep) {
357      case SC_DEC:
358      case SC_BIN:
359      case SC_BIN_US:
360      case SC_BIN_SM:
361      case SC_OCT:
362      case SC_OCT_US:
363      case SC_OCT_SM:
364        {
365            to_digit = c - '0';
366            break;
367        }
368      case SC_HEX:
369      case SC_HEX_US:
370      case SC_HEX_SM:
371        {
372            switch (c) {
373              case '0': case '1': case '2': case '3': case '4':
374              case '5': case '6': case '7': case '8': case '9':
375                to_digit = c - '0';
376                break;
377              case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
378                to_digit = c - 'a' + 10;
379                break;
380              case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
381                to_digit = c - 'A' + 10;
382                break;
383              default:
384                to_digit = -2;
385            }
386            break;
387        }
388      case SC_CSD:
389        {
390            if (c == '-')
391                to_digit = -1;
392            else
393                to_digit = c - '0';
394            break;
395        }
396      default:
397        to_digit = -2;
398    }
399
400    return to_digit;
401}
402
403
404// ----------------------------------------------------------------------------
405//  Utilities for printing a character string number
406// ----------------------------------------------------------------------------
407
408inline void scfx_print_nan(scfx_string &s) { s += "NaN"; }
409inline void
410scfx_print_inf(scfx_string &s, bool negative)
411{
412    if (negative)
413        s += "-Inf";
414    else
415        s += "Inf";
416}
417
418inline void
419scfx_print_prefix(scfx_string &s, sc_numrep numrep)
420{
421    switch (numrep) {
422      case SC_DEC:
423        s += "0d";
424        break;
425      case SC_BIN:
426        s += "0b";
427        break;
428      case SC_BIN_US:
429        s += "0bus";
430        break;
431      case SC_BIN_SM:
432        s += "0bsm";
433        break;
434      case SC_OCT:
435        s += "0o";
436        break;
437      case SC_OCT_US:
438        s += "0ous";
439        break;
440      case SC_OCT_SM:
441        s += "0osm";
442        break;
443      case SC_HEX:
444        s += "0x";
445        break;
446      case SC_HEX_US:
447        s += "0xus";
448        break;
449      case SC_HEX_SM:
450        s += "0xsm";
451        break;
452      case SC_CSD:
453        s += "0csd";
454        break;
455      default:
456        s += "unknown";
457    }
458}
459
460inline void
461scfx_print_exp(scfx_string &s, int exp)
462{
463    if (exp != 0) {
464        s += 'e';
465
466        if (exp < 0) {
467            exp = - exp;
468            s += '-';
469        } else {
470            s += '+';
471        }
472
473        bool first = true;
474        int scale = 1000000000;
475        do {
476            int digit = exp / scale;
477            exp = exp % scale;
478            if (digit != 0 || !first) {
479                s += static_cast<char>(digit + '0');
480                first = false;
481            }
482            scale /= 10;
483        }
484        while (scale > 0);
485    }
486}
487
488void scfx_tc2csd(scfx_string &, int);
489void scfx_csd2tc(scfx_string &);
490
491} // namespace sc_dt
492
493#endif // __SYSTEMC_EXT_DT_FX_SCFX_UTILS_HH__
494