scfx_utils.hh (12853:e23d6f09069a) scfx_utils.hh (13197:aeba6988033f)
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;
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)
70# if SC_LONG_64
71 MSB_STATEMENT(32);
71 MSB_STATEMENT(32);
72# endif // defined(SC_LONG_64)
72# endif // 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;
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)
89# if SC_LONG_64
90 i = 63;
91 LSB_STATEMENT(32);
92# else
93 i = 31;
90 i = 63;
91 LSB_STATEMENT(32);
92# else
93 i = 31;
94# endif // defined(SC_LONG_64)
94# endif // 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__
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__