1 //===-- DNBRegisterInfo.cpp -------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  Created by Greg Clayton on 8/3/07.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "DNBRegisterInfo.h"
15 #include "DNBLog.h"
16 #include <string.h>
17 
18 DNBRegisterValueClass::DNBRegisterValueClass(const DNBRegisterInfo *regInfo)
19 {
20     Clear();
21     if (regInfo)
22         info = *regInfo;
23 }
24 
25 void
26 DNBRegisterValueClass::Clear()
27 {
28     memset(&info, 0, sizeof(DNBRegisterInfo));
29     memset(&value, 0, sizeof(value));
30 }
31 
32 bool
33 DNBRegisterValueClass::IsValid() const
34 {
35     return
36         info.name != NULL &&
37         info.type != InvalidRegType &&
38         info.size > 0 && info.size <= sizeof(value);
39 }
40 
41 #define PRINT_COMMA_SEPARATOR do { if (pos < end) { if (i > 0) { strncpy(pos, ", ", end - pos); pos += 2; } } } while (0)
42 
43 void
44 DNBRegisterValueClass::Dump(const char *pre, const char *post) const
45 {
46     if (info.name != NULL)
47     {
48         char str[1024];
49         char *pos;
50         char *end = str + sizeof(str);
51         if (info.format == Hex)
52         {
53             switch (info.size)
54             {
55             case 0:     snprintf(str, sizeof(str), "%s", "error: invalid register size of zero."); break;
56             case 1:     snprintf(str, sizeof(str), "0x%2.2x", value.uint8); break;
57             case 2:     snprintf(str, sizeof(str), "0x%4.4x", value.uint16); break;
58             case 4:     snprintf(str, sizeof(str), "0x%8.8x", value.uint32); break;
59             case 8:     snprintf(str, sizeof(str), "0x%16.16llx", value.uint64); break;
60             case 16:    snprintf(str, sizeof(str), "0x%16.16llx%16.16llx", value.v_uint64[0], value.v_uint64[1]); break;
61             default:
62                 strncpy(str, "0x", 3);
63                 pos = str + 2;
64                 for (uint32_t i=0; i<info.size; ++i)
65                 {
66                     if (pos < end)
67                         pos += snprintf(pos, end - pos, "%2.2x", (uint32_t)value.v_uint8[i]);
68                 }
69                 break;
70             }
71         }
72         else
73         {
74             switch (info.type)
75             {
76             case Uint:
77                 switch (info.size)
78                 {
79                 case 1:     snprintf(str, sizeof(str), "%u", value.uint8); break;
80                 case 2:     snprintf(str, sizeof(str), "%u", value.uint16); break;
81                 case 4:     snprintf(str, sizeof(str), "%u", value.uint32); break;
82                 case 8:     snprintf(str, sizeof(str), "%llu", value.uint64); break;
83                 default:    snprintf(str, sizeof(str), "error: unsupported uint byte size %d.", info.size); break;
84                 }
85                 break;
86 
87             case Sint:
88                 switch (info.size)
89                 {
90                 case 1:     snprintf(str, sizeof(str), "%d", value.sint8); break;
91                 case 2:     snprintf(str, sizeof(str), "%d", value.sint16); break;
92                 case 4:     snprintf(str, sizeof(str), "%d", value.sint32); break;
93                 case 8:     snprintf(str, sizeof(str), "%lld", value.sint64); break;
94                 default:    snprintf(str, sizeof(str), "error: unsupported sint byte size %d.", info.size); break;
95                 }
96                 break;
97 
98             case IEEE754:
99                 switch (info.size)
100                 {
101                 case 4:     snprintf(str, sizeof(str), "%f", value.float32); break;
102                 case 8:     snprintf(str, sizeof(str), "%g", value.float64); break;
103                 default:    snprintf(str, sizeof(str), "error: unsupported float byte size %d.", info.size); break;
104                 }
105                 break;
106 
107             case Vector:
108                 if (info.size > 0)
109                 {
110                     switch (info.format)
111                     {
112                     case VectorOfSInt8:
113                         snprintf(str, sizeof(str), "%s", "sint8   { ");
114                         pos = str + strlen(str);
115                         for (uint32_t i=0; i<info.size; ++i)
116                         {
117                             PRINT_COMMA_SEPARATOR;
118                             if (pos < end)
119                                 pos += snprintf(pos, end - pos, "%d", (int32_t)value.v_sint8[i]);
120                         }
121                         strlcat(str, " }", sizeof(str));
122                         break;
123 
124                     default:
125                         DNBLogError("unsupported vector format %d, defaulting to hex bytes.", info.format);
126                     case VectorOfUInt8:
127                         snprintf(str, sizeof(str), "%s", "uint8   { ");
128                         pos = str + strlen(str);
129                         for (uint32_t i=0; i<info.size; ++i)
130                         {
131                             PRINT_COMMA_SEPARATOR;
132                             if (pos < end)
133                                 pos += snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint8[i]);
134                         }
135                         break;
136 
137                     case VectorOfSInt16:
138                         snprintf(str, sizeof(str), "%s", "sint16  { ");
139                         pos = str + strlen(str);
140                         for (uint32_t i=0; i<info.size/2; ++i)
141                         {
142                             PRINT_COMMA_SEPARATOR;
143                             if (pos < end)
144                                 pos += snprintf(pos, end - pos, "%d", (int32_t)value.v_sint16[i]);
145                         }
146                         break;
147 
148                     case VectorOfUInt16:
149                         snprintf(str, sizeof(str), "%s", "uint16  { ");
150                         pos = str + strlen(str);
151                         for (uint32_t i=0; i<info.size/2; ++i)
152                         {
153                             PRINT_COMMA_SEPARATOR;
154                             if (pos < end)
155                                 pos += snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint16[i]);
156                         }
157                         break;
158 
159                     case VectorOfSInt32:
160                         snprintf(str, sizeof(str), "%s", "sint32  { ");
161                         pos = str + strlen(str);
162                         for (uint32_t i=0; i<info.size/4; ++i)
163                         {
164                             PRINT_COMMA_SEPARATOR;
165                             if (pos < end)
166                                 pos += snprintf(pos, end - pos, "%d", (int32_t)value.v_sint32[i]);
167                         }
168                         break;
169 
170                     case VectorOfUInt32:
171                         snprintf(str, sizeof(str), "%s", "uint32  { ");
172                         pos = str + strlen(str);
173                         for (uint32_t i=0; i<info.size/4; ++i)
174                         {
175                             PRINT_COMMA_SEPARATOR;
176                             if (pos < end)
177                                 pos += snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint32[i]);
178                         }
179                         break;
180 
181                     case VectorOfFloat32:
182                         snprintf(str, sizeof(str), "%s", "float32 { ");
183                         pos = str + strlen(str);
184                         for (uint32_t i=0; i<info.size/4; ++i)
185                         {
186                             PRINT_COMMA_SEPARATOR;
187                             if (pos < end)
188                                 pos += snprintf(pos, end - pos, "%f", value.v_float32[i]);
189                         }
190                         break;
191 
192                     case VectorOfUInt128:
193                         snprintf(str, sizeof(str), "%s", "uint128 { ");
194                         pos = str + strlen(str);
195                         for (uint32_t i=0; i<info.size/16; ++i)
196                         {
197                             PRINT_COMMA_SEPARATOR;
198                             if (pos < end)
199                                 pos += snprintf(pos, end - pos, "0x%16.16llx%16.16llx", value.v_uint64[i], value.v_uint64[i+1]);
200                         }
201                         break;
202                     }
203                     strlcat(str, " }", sizeof(str));
204                 }
205                 else
206                 {
207                     snprintf(str, sizeof(str), "error: unsupported vector size %d.", info.size);
208                 }
209                 break;
210 
211             default:
212                 snprintf(str, sizeof(str), "error: unsupported register type %d.", info.type);
213                 break;
214             }
215         }
216 
217         DNBLog("%s%4s = %s%s", pre ? pre : "", info.name, str, post ? post : "");
218     }
219 }
220