scfx_utils.h revision 12027:1eb7dc7aa10b
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 SCFX_UTILS_H
51#define SCFX_UTILS_H
52
53
54#include "sysc/datatypes/fx/sc_fxdefs.h"
55#include "sysc/datatypes/fx/scfx_params.h"
56#include "sysc/datatypes/fx/scfx_string.h"
57
58
59namespace sc_dt
60{
61
62// ----------------------------------------------------------------------------
63//  Find the most and least significant non-zero bits in a unsigned long
64// ----------------------------------------------------------------------------
65
66#define MSB_STATEMENT(n) if( x >> n ) { x >>= n; i += n; }
67
68inline
69int
70scfx_find_msb( unsigned long x )
71{
72    int i = 0;
73#   if defined(SC_LONG_64)
74        MSB_STATEMENT( 32 );
75#   endif // defined(SC_LONG_64)
76    MSB_STATEMENT( 16 );
77    MSB_STATEMENT( 8 );
78    MSB_STATEMENT( 4 );
79    MSB_STATEMENT( 2 );
80    MSB_STATEMENT( 1 );
81    return i;
82}
83
84#undef MSB_STATEMENT
85
86#define LSB_STATEMENT(n) if( x << n ) { x <<= n; i -= n; }
87
88inline
89int
90scfx_find_lsb( unsigned long x )
91{
92    int i;
93#   if defined(SC_LONG_64)
94        i = 63;
95        LSB_STATEMENT( 32 );
96#   else
97        i = 31;
98#   endif // defined(SC_LONG_64)
99    LSB_STATEMENT( 16 );
100    LSB_STATEMENT( 8 );
101    LSB_STATEMENT( 4 );
102    LSB_STATEMENT( 2 );
103    LSB_STATEMENT( 1 );
104    return i;
105}
106
107#undef LSB_STATEMENT
108
109
110// ----------------------------------------------------------------------------
111//  Utilities for parsing a character string number
112// ----------------------------------------------------------------------------
113
114inline
115int
116scfx_parse_sign( const char*& s, bool& sign_char )
117{
118    int sign = 1;
119
120    if( *s == '+' )
121    {
122        ++ s;
123	sign_char = true;
124    }
125    else if( *s == '-' )
126    {
127        sign = -1;
128        ++ s;
129	sign_char = true;
130    }
131    else
132	sign_char = false;
133
134    return sign;
135}
136
137inline
138sc_numrep
139scfx_parse_prefix( const char*& s )
140{
141    if( s[0] == '0' ) {
142        switch( s[1] )
143        {
144	    case 'b':
145	    case 'B':
146            {
147	        if( (s[2] == 'u' || s[2] == 'U') && (s[3] == 's' || s[3] == 'S') ) {
148		    s += 4;
149                    return SC_BIN_US;
150                }
151                if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'm' || s[3] == 'M') ) {
152                    s += 4;
153                    return SC_BIN_SM;
154                }
155                s += 2;
156                return SC_BIN;
157            }
158	    case 'o':
159	    case 'O':
160	    {
161                if( (s[2] == 'u' || s[2] == 'U') && (s[3] == 's' || s[3] == 'S') ) {
162                    s += 4;
163                    return SC_OCT_US;
164                }
165                if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'm' || s[3] == 'M') ) {
166                    s += 4;
167                    return SC_OCT_SM;
168                }
169                s += 2;
170                return SC_OCT;
171            }
172  	    case 'x':
173	    case 'X':
174            {
175                if( (s[2] == 'u' || s[2] == 'U') && (s[3] == 's' || s[3] == 'S') ) {
176                    s += 4;
177                    return SC_HEX_US;
178                }
179                if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'm' || s[3] == 'M') ) {
180                    s += 4;
181                    return SC_HEX_SM;
182                }
183                s += 2;
184                return SC_HEX;
185            }
186   	    case 'd':
187	    case 'D':
188            {
189                s += 2;
190                return SC_DEC;
191            }
192	    case 'c':
193	    case 'C':
194            {
195                if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'd' || s[3] == 'D') ) {
196                    s += 4;
197                    return SC_CSD;
198                }
199                break;
200            }
201            default:
202                break;
203        }
204    }
205
206    return SC_DEC;
207}
208
209
210inline
211int
212scfx_parse_base( const char*& s )
213{
214    const char* s1 = s + 1;
215
216    int base = 10;
217
218    if( *s == '0' )
219    {
220        switch( *s1 )
221	{
222            case 'b':
223            case 'B': base =  2; s += 2; break;
224            case 'o':
225            case 'O': base =  8; s += 2; break;
226            case 'd':
227            case 'D': base = 10; s += 2; break;
228            case 'x':
229            case 'X': base = 16; s += 2; break;
230        }
231    }
232
233    return base;
234}
235
236inline
237bool
238scfx_is_equal( const char* a, const char* b )
239{
240    while( *a != 0 && *b != 0 && *a == *b )
241    {
242        ++ a;
243        ++ b;
244    }
245    return ( *a == 0 && *b == 0 );
246}
247
248inline
249bool
250scfx_is_nan( const char* s )
251{
252    return scfx_is_equal( s, "NaN" );
253}
254
255inline
256bool
257scfx_is_inf( const char* s )
258{
259    return ( scfx_is_equal( s, "Inf" ) || scfx_is_equal( s, "Infinity" ) );
260}
261
262inline
263bool
264scfx_exp_start( const char* s )
265{
266    if( *s == 'e' || *s == 'E' )
267    {
268        ++ s;
269        if( *s == '+' || *s == '-' )
270            return true;
271    }
272    return false;
273}
274
275inline
276bool
277scfx_is_digit( char c, sc_numrep numrep )
278{
279    bool is_digit;
280
281    switch( numrep )
282    {
283        case SC_DEC:
284	{
285            switch( c )
286	    {
287                case '0': case '1': case '2': case '3': case '4':
288                case '5': case '6': case '7': case '8': case '9':
289		{
290                    is_digit = true;
291                    break;
292		}
293                default:
294                    is_digit = false;
295            }
296            break;
297	}
298	case SC_BIN:
299	case SC_BIN_US:
300	case SC_BIN_SM:
301	{
302            switch( c )
303	    {
304                case '0': case '1':
305		{
306                    is_digit = true;
307                    break;
308		}
309                default:
310                    is_digit = false;
311            }
312            break;
313	}
314	case SC_OCT:
315	case SC_OCT_US:
316	case SC_OCT_SM:
317	{
318            switch( c )
319	    {
320                case '0': case '1': case '2': case '3':
321                case '4': case '5': case '6': case '7':
322		{
323                    is_digit = true;
324                    break;
325		}
326                default:
327                    is_digit = false;
328            }
329            break;
330	}
331	case SC_HEX:
332	case SC_HEX_US:
333	case SC_HEX_SM:
334	{
335            switch( c )
336	    {
337                case '0': case '1': case '2': case '3': case '4':
338                case '5': case '6': case '7': case '8': case '9':
339                case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
340                case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
341		{
342                    is_digit = true;
343                    break;
344		}
345                default:
346                    is_digit = false;
347            }
348            break;
349	}
350	case SC_CSD:
351	{
352            switch( c )
353	    {
354		case '0': case '1': case '-':
355		{
356                    is_digit = true;
357                    break;
358		}
359                default:
360                    is_digit = false;
361            }
362            break;
363	}
364	default:
365            is_digit = false;
366    }
367
368    return is_digit;
369}
370
371inline
372int
373scfx_to_digit( char c, sc_numrep numrep )
374{
375    int to_digit;
376
377    switch( numrep )
378    {
379	case SC_DEC:
380	case SC_BIN:
381	case SC_BIN_US:
382	case SC_BIN_SM:
383	case SC_OCT:
384	case SC_OCT_US:
385	case SC_OCT_SM:
386	{
387            to_digit = c - '0';
388            break;
389	}
390	case SC_HEX:
391	case SC_HEX_US:
392	case SC_HEX_SM:
393	{
394            switch( c )
395	    {
396                case '0': case '1': case '2': case '3': case '4':
397                case '5': case '6': case '7': case '8': case '9':
398                    to_digit = c - '0';
399                    break;
400                case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
401                    to_digit = c - 'a' + 10;
402                    break;
403                case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
404                    to_digit = c - 'A' + 10;
405                    break;
406                default:
407                    to_digit = -2;
408            }
409            break;
410	}
411	case SC_CSD:
412	{
413            if( c == '-' )
414                to_digit = -1;
415            else
416                to_digit = c - '0';
417            break;
418	}
419        default:
420            to_digit = -2;
421    }
422
423    return to_digit;
424}
425
426
427// ----------------------------------------------------------------------------
428//  Utilities for printing a character string number
429// ----------------------------------------------------------------------------
430
431inline
432void
433scfx_print_nan( scfx_string& s )
434{
435    s += "NaN";
436}
437
438inline
439void
440scfx_print_inf( scfx_string& s, bool negative )
441{
442    if( negative )
443        s += "-Inf";
444    else
445        s += "Inf";
446}
447
448inline
449void
450scfx_print_prefix( scfx_string& s, sc_numrep numrep )
451{
452    switch( numrep )
453    {
454        case SC_DEC:
455	    s += "0d";
456	    break;
457        case SC_BIN:
458	    s += "0b";
459	    break;
460        case SC_BIN_US:
461	    s += "0bus";
462	    break;
463        case SC_BIN_SM:
464	    s += "0bsm";
465	    break;
466        case SC_OCT:
467	    s += "0o";
468	    break;
469        case SC_OCT_US:
470	    s += "0ous";
471	    break;
472        case SC_OCT_SM:
473	    s += "0osm";
474	    break;
475        case SC_HEX:
476	    s += "0x";
477	    break;
478        case SC_HEX_US:
479	    s += "0xus";
480	    break;
481        case SC_HEX_SM:
482	    s += "0xsm";
483	    break;
484        case SC_CSD:
485	    s += "0csd";
486	    break;
487        default:
488	    s += "unknown";
489    }
490}
491
492inline
493void
494scfx_print_exp( scfx_string& s, int exp )
495{
496    if( exp != 0 )
497    {
498        s += 'e';
499
500        if( exp < 0 )
501	{
502            exp = - exp;
503            s += '-';
504        }
505	else
506            s += '+';
507
508        bool first = true;
509        int scale = 1000000000;
510        do
511	{
512            int digit = exp / scale;
513            exp = exp % scale;
514            if( digit != 0 || ! first )
515	    {
516                s += static_cast<char>( digit + '0' );
517                first = false;
518            }
519            scale /= 10;
520        }
521	while( scale > 0 );
522    }
523}
524
525
526void scfx_tc2csd( scfx_string&, int );
527void scfx_csd2tc( scfx_string& );
528
529} // namespace sc_dt
530
531
532#endif
533
534// Taf!
535