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