scfx_utils.hh revision 12853
18012Ssaidi@eecs.umich.edu/*****************************************************************************
28013Sbinkertn@umich.edu
38013Sbinkertn@umich.edu  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
48013Sbinkertn@umich.edu  more contributor license agreements.  See the NOTICE file distributed
58013Sbinkertn@umich.edu  with this work for additional information regarding copyright ownership.
68013Sbinkertn@umich.edu  Accellera licenses this file to you under the Apache License, Version 2.0
78013Sbinkertn@umich.edu  (the "License"); you may not use this file except in compliance with the
88013Sbinkertn@umich.edu  License.  You may obtain a copy of the License at
98013Sbinkertn@umich.edu
108013Sbinkertn@umich.edu    http://www.apache.org/licenses/LICENSE-2.0
118013Sbinkertn@umich.edu
128013Sbinkertn@umich.edu  Unless required by applicable law or agreed to in writing, software
138013Sbinkertn@umich.edu  distributed under the License is distributed on an "AS IS" BASIS,
148013Sbinkertn@umich.edu  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
158013Sbinkertn@umich.edu  implied.  See the License for the specific language governing
168013Sbinkertn@umich.edu  permissions and limitations under the License.
178013Sbinkertn@umich.edu
188013Sbinkertn@umich.edu *****************************************************************************/
198013Sbinkertn@umich.edu
208013Sbinkertn@umich.edu/*****************************************************************************
218013Sbinkertn@umich.edu
228013Sbinkertn@umich.edu  scfx_utils.h -
238013Sbinkertn@umich.edu
248012Ssaidi@eecs.umich.edu  Original Author: Martin Janssen, Synopsys, Inc.
258013Sbinkertn@umich.edu
268012Ssaidi@eecs.umich.edu *****************************************************************************/
277997Ssaidi@eecs.umich.edu
288013Sbinkertn@umich.edu/*****************************************************************************
297997Ssaidi@eecs.umich.edu
307997Ssaidi@eecs.umich.edu  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
317997Ssaidi@eecs.umich.edu  changes you are making here.
327997Ssaidi@eecs.umich.edu
337997Ssaidi@eecs.umich.edu      Name, Affiliation, Date:
347997Ssaidi@eecs.umich.edu  Description of Modification:
357997Ssaidi@eecs.umich.edu
367997Ssaidi@eecs.umich.edu *****************************************************************************/
377997Ssaidi@eecs.umich.edu
387997Ssaidi@eecs.umich.edu// $Log: scfx_utils.h,v $
397997Ssaidi@eecs.umich.edu// Revision 1.2  2009/02/28 00:26:20  acg
407997Ssaidi@eecs.umich.edu//  Andy Goodrich: bug fixes.
417997Ssaidi@eecs.umich.edu//
427997Ssaidi@eecs.umich.edu// Revision 1.1.1.1  2006/12/15 20:31:36  acg
437997Ssaidi@eecs.umich.edu// SystemC 2.2
447997Ssaidi@eecs.umich.edu//
457997Ssaidi@eecs.umich.edu// Revision 1.3  2006/01/13 18:53:58  acg
467997Ssaidi@eecs.umich.edu// Andy Goodrich: added $Log command so that CVS comments are reproduced in
477997Ssaidi@eecs.umich.edu// the source.
487997Ssaidi@eecs.umich.edu//
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