xref: /openbsd-src/gnu/llvm/lldb/tools/debugserver/source/DNBRegisterInfo.cpp (revision be691f3bb6417f04a68938fadbcaee2d5795e764)
1 //===-- DNBRegisterInfo.cpp -------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //  Created by Greg Clayton on 8/3/07.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "DNBRegisterInfo.h"
14 #include "DNBLog.h"
15 #include <cstring>
16 
DNBRegisterValueClass(const DNBRegisterInfo * regInfo)17 DNBRegisterValueClass::DNBRegisterValueClass(const DNBRegisterInfo *regInfo) {
18   Clear();
19   if (regInfo)
20     info = *regInfo;
21 }
22 
Clear()23 void DNBRegisterValueClass::Clear() {
24   memset(&info, 0, sizeof(DNBRegisterInfo));
25   memset(&value, 0, sizeof(value));
26 }
27 
IsValid() const28 bool DNBRegisterValueClass::IsValid() const {
29   return info.name != NULL && info.type != InvalidRegType && info.size > 0 &&
30          info.size <= sizeof(value);
31 }
32 
33 #define PRINT_COMMA_SEPARATOR                                                  \
34   do {                                                                         \
35     if (pos < end) {                                                           \
36       if (i > 0) {                                                             \
37         strlcpy(pos, ", ", end - pos);                                         \
38         pos += 2;                                                              \
39       }                                                                        \
40     }                                                                          \
41   } while (0)
42 
Dump(const char * pre,const char * post) const43 void DNBRegisterValueClass::Dump(const char *pre, const char *post) const {
44   if (info.name != NULL) {
45     char str[1024];
46     char *pos;
47     char *end = str + sizeof(str);
48     if (info.format == Hex) {
49       switch (info.size) {
50       case 0:
51         snprintf(str, sizeof(str), "%s",
52                  "error: invalid register size of zero.");
53         break;
54       case 1:
55         snprintf(str, sizeof(str), "0x%2.2x", value.uint8);
56         break;
57       case 2:
58         snprintf(str, sizeof(str), "0x%4.4x", value.uint16);
59         break;
60       case 4:
61         snprintf(str, sizeof(str), "0x%8.8x", value.uint32);
62         break;
63       case 8:
64         snprintf(str, sizeof(str), "0x%16.16llx", value.uint64);
65         break;
66       case 16:
67         snprintf(str, sizeof(str), "0x%16.16llx%16.16llx", value.v_uint64[0],
68                  value.v_uint64[1]);
69         break;
70       default:
71         strlcpy(str, "0x", 3);
72         pos = str + 2;
73         for (uint32_t i = 0; i < info.size; ++i) {
74           if (pos < end)
75             pos +=
76                 snprintf(pos, end - pos, "%2.2x", (uint32_t)value.v_uint8[i]);
77         }
78         break;
79       }
80     } else {
81       switch (info.type) {
82       case Uint:
83         switch (info.size) {
84         case 1:
85           snprintf(str, sizeof(str), "%u", value.uint8);
86           break;
87         case 2:
88           snprintf(str, sizeof(str), "%u", value.uint16);
89           break;
90         case 4:
91           snprintf(str, sizeof(str), "%u", value.uint32);
92           break;
93         case 8:
94           snprintf(str, sizeof(str), "%llu", value.uint64);
95           break;
96         default:
97           snprintf(str, sizeof(str), "error: unsupported uint byte size %d.",
98                    info.size);
99           break;
100         }
101         break;
102 
103       case Sint:
104         switch (info.size) {
105         case 1:
106           snprintf(str, sizeof(str), "%d", value.sint8);
107           break;
108         case 2:
109           snprintf(str, sizeof(str), "%d", value.sint16);
110           break;
111         case 4:
112           snprintf(str, sizeof(str), "%d", value.sint32);
113           break;
114         case 8:
115           snprintf(str, sizeof(str), "%lld", value.sint64);
116           break;
117         default:
118           snprintf(str, sizeof(str), "error: unsupported sint byte size %d.",
119                    info.size);
120           break;
121         }
122         break;
123 
124       case IEEE754:
125         switch (info.size) {
126         case 4:
127           snprintf(str, sizeof(str), "%f", value.float32);
128           break;
129         case 8:
130           snprintf(str, sizeof(str), "%g", value.float64);
131           break;
132         default:
133           snprintf(str, sizeof(str), "error: unsupported float byte size %d.",
134                    info.size);
135           break;
136         }
137         break;
138 
139       case Vector:
140         if (info.size > 0) {
141           switch (info.format) {
142           case VectorOfSInt8:
143             snprintf(str, sizeof(str), "%s", "sint8   { ");
144             pos = str + strlen(str);
145             for (uint32_t i = 0; i < info.size; ++i) {
146               PRINT_COMMA_SEPARATOR;
147               if (pos < end)
148                 pos +=
149                     snprintf(pos, end - pos, "%d", (int32_t)value.v_sint8[i]);
150             }
151             strlcat(str, " }", sizeof(str));
152             break;
153 
154           default:
155             DNBLogError(
156                 "unsupported vector format %d, defaulting to hex bytes.",
157                 info.format);
158             [[clang::fallthrough]];
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