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