1
2 /*
3 * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19
20 #if !defined __DEBUG_PRN_H_INCLUDED__
21 #define __DEBUG_PRN_H_INCLUDED__ 1
22
23 // self-debug
24 #if defined DO_PRINT
25 #include <stdio.h>
26 #include <fenv.h>
27 #include <string.h>
28 #define PRINT(x) do_printing(&(x), #x, __LINE__, __FILE__, sizeof(x))
29 #else
30 #define PRINT(x)
31 #endif
32
33 #if defined DO_PRINT
print_status_flags(char * dst)34 static void print_status_flags(char * dst)
35 {
36 if ( fetestexcept(FE_INEXACT) )
37 {
38 strncat(dst, "P", 1);
39 }
40 else
41 {
42 strncat(dst, "p", 1);
43 }
44
45 if ( fetestexcept(FE_UNDERFLOW) )
46 {
47 strncat(dst, "U", 1);
48 }
49 else
50 {
51 strncat(dst, "u", 1);
52 }
53
54 if ( fetestexcept(FE_OVERFLOW) )
55 {
56 strncat(dst, "O", 1);
57 }
58 else
59 {
60 strncat(dst, "o", 1);
61 }
62
63 if ( fetestexcept(FE_DIVBYZERO) )
64 {
65 strncat(dst, "Z", 1);
66 }
67 else
68 {
69 strncat(dst, "z", 1);
70 }
71 //TODO: add non-Intel compiler support for denormal flag
72 {
73 strncat(dst, "d", 1);
74 }
75 if ( fetestexcept(FE_INVALID) )
76 {
77 strncat(dst, "I", 1);
78 }
79 else
80 {
81 strncat(dst, "i", 1);
82 }
83
84 return;
85 }
86
do_printing(void * pvar,const char * varname,int linenum,const char * filename,int varsize)87 static void do_printing(void * pvar, const char * varname, int linenum, const char * filename, int varsize)
88 {
89 char buffer[100];
90 char buffer1[150] = "";
91 char tmp[16];
92
93 // copy last 15 chars from the file name, pad with spaces, right-justified
94 #define THIS_MAX(a, b) ((a) > (b) ? (a) : (b))
95 snprintf(buffer, 15+1+1, "%15s:", filename + THIS_MAX((int)strlen(filename) - 15, 0));
96 #undef THIS_MAX
97 // print line number
98 snprintf(tmp, 5+1+1+1, "%5d: ", linenum);
99 strncat(buffer, tmp, 5+1+1);
100 // print status flags
101 print_status_flags(buffer);
102 strncat(buffer, ": ", 2);
103 // print variable name
104 snprintf(tmp, sizeof(tmp), "%14s:", varname);
105 strncat(buffer, tmp, sizeof(tmp));
106 // print variable value
107 switch(varsize)
108 {
109 case sizeof(float):
110 {
111 float fval = *((float*)pvar);
112 double dval = (double)fval;
113 unsigned uval = *((unsigned*)pvar);
114 snprintf(buffer1, 150, "%s: %08X == %-20g == %-25a == %d",
115 buffer, uval, dval, fval, uval);
116 }
117 break;
118 default:
119 case sizeof(double):
120 {
121 double dval = *((double*)pvar);
122 unsigned long long u64val = *((unsigned long long*)pvar);
123 snprintf(buffer1, 150, "%s: %016llX == %-20g == %-25a == %lld",
124 buffer, u64val, dval, dval, u64val);
125 }
126 break;
127 }
128
129 fprintf(stdout, "%s\n", buffer1);
130 return;
131 }
132 #endif
133
134 #endif //#if !defined __DEBUG_PRN_H_INCLUDED__
135