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