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         strncpy(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         strncpy(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           case VectorOfUInt8:
160             snprintf(str, sizeof(str), "%s", "uint8   { ");
161             pos = str + strlen(str);
162             for (uint32_t i = 0; i < info.size; ++i) {
163               PRINT_COMMA_SEPARATOR;
164               if (pos < end)
165                 pos +=
166                     snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint8[i]);
167             }
168             break;
169 
170           case VectorOfSInt16:
171             snprintf(str, sizeof(str), "%s", "sint16  { ");
172             pos = str + strlen(str);
173             for (uint32_t i = 0; i < info.size / 2; ++i) {
174               PRINT_COMMA_SEPARATOR;
175               if (pos < end)
176                 pos +=
177                     snprintf(pos, end - pos, "%d", (int32_t)value.v_sint16[i]);
178             }
179             break;
180 
181           case VectorOfUInt16:
182             snprintf(str, sizeof(str), "%s", "uint16  { ");
183             pos = str + strlen(str);
184             for (uint32_t i = 0; i < info.size / 2; ++i) {
185               PRINT_COMMA_SEPARATOR;
186               if (pos < end)
187                 pos +=
188                     snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint16[i]);
189             }
190             break;
191 
192           case VectorOfSInt32:
193             snprintf(str, sizeof(str), "%s", "sint32  { ");
194             pos = str + strlen(str);
195             for (uint32_t i = 0; i < info.size / 4; ++i) {
196               PRINT_COMMA_SEPARATOR;
197               if (pos < end)
198                 pos +=
199                     snprintf(pos, end - pos, "%d", (int32_t)value.v_sint32[i]);
200             }
201             break;
202 
203           case VectorOfUInt32:
204             snprintf(str, sizeof(str), "%s", "uint32  { ");
205             pos = str + strlen(str);
206             for (uint32_t i = 0; i < info.size / 4; ++i) {
207               PRINT_COMMA_SEPARATOR;
208               if (pos < end)
209                 pos +=
210                     snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint32[i]);
211             }
212             break;
213 
214           case VectorOfFloat32:
215             snprintf(str, sizeof(str), "%s", "float32 { ");
216             pos = str + strlen(str);
217             for (uint32_t i = 0; i < info.size / 4; ++i) {
218               PRINT_COMMA_SEPARATOR;
219               if (pos < end)
220                 pos += snprintf(pos, end - pos, "%f", value.v_float32[i]);
221             }
222             break;
223 
224           case VectorOfUInt128:
225             snprintf(str, sizeof(str), "%s", "uint128 { ");
226             pos = str + strlen(str);
227             for (uint32_t i = 0; i < info.size / 16; ++i) {
228               PRINT_COMMA_SEPARATOR;
229               if (pos < end)
230                 pos += snprintf(pos, end - pos, "0x%16.16llx%16.16llx",
231                                 value.v_uint64[i], value.v_uint64[i + 1]);
232             }
233             break;
234           }
235           strlcat(str, " }", sizeof(str));
236         } else {
237           snprintf(str, sizeof(str), "error: unsupported vector size %d.",
238                    info.size);
239         }
240         break;
241 
242       default:
243         snprintf(str, sizeof(str), "error: unsupported register type %d.",
244                  info.type);
245         break;
246       }
247     }
248 
249     DNBLog("%s%4s = %s%s", pre ? pre : "", info.name, str, post ? post : "");
250   }
251 }
252