1061da546Spatrick //===-- DNBRegisterInfo.cpp -------------------------------------*- C++ -*-===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick //
9061da546Spatrick // Created by Greg Clayton on 8/3/07.
10061da546Spatrick //
11061da546Spatrick //===----------------------------------------------------------------------===//
12061da546Spatrick
13061da546Spatrick #include "DNBRegisterInfo.h"
14061da546Spatrick #include "DNBLog.h"
15*be691f3bSpatrick #include <cstring>
16061da546Spatrick
DNBRegisterValueClass(const DNBRegisterInfo * regInfo)17061da546Spatrick DNBRegisterValueClass::DNBRegisterValueClass(const DNBRegisterInfo *regInfo) {
18061da546Spatrick Clear();
19061da546Spatrick if (regInfo)
20061da546Spatrick info = *regInfo;
21061da546Spatrick }
22061da546Spatrick
Clear()23061da546Spatrick void DNBRegisterValueClass::Clear() {
24061da546Spatrick memset(&info, 0, sizeof(DNBRegisterInfo));
25061da546Spatrick memset(&value, 0, sizeof(value));
26061da546Spatrick }
27061da546Spatrick
IsValid() const28061da546Spatrick bool DNBRegisterValueClass::IsValid() const {
29061da546Spatrick return info.name != NULL && info.type != InvalidRegType && info.size > 0 &&
30061da546Spatrick info.size <= sizeof(value);
31061da546Spatrick }
32061da546Spatrick
33061da546Spatrick #define PRINT_COMMA_SEPARATOR \
34061da546Spatrick do { \
35061da546Spatrick if (pos < end) { \
36061da546Spatrick if (i > 0) { \
37061da546Spatrick strlcpy(pos, ", ", end - pos); \
38061da546Spatrick pos += 2; \
39061da546Spatrick } \
40061da546Spatrick } \
41061da546Spatrick } while (0)
42061da546Spatrick
Dump(const char * pre,const char * post) const43061da546Spatrick void DNBRegisterValueClass::Dump(const char *pre, const char *post) const {
44061da546Spatrick if (info.name != NULL) {
45061da546Spatrick char str[1024];
46061da546Spatrick char *pos;
47061da546Spatrick char *end = str + sizeof(str);
48061da546Spatrick if (info.format == Hex) {
49061da546Spatrick switch (info.size) {
50061da546Spatrick case 0:
51061da546Spatrick snprintf(str, sizeof(str), "%s",
52061da546Spatrick "error: invalid register size of zero.");
53061da546Spatrick break;
54061da546Spatrick case 1:
55061da546Spatrick snprintf(str, sizeof(str), "0x%2.2x", value.uint8);
56061da546Spatrick break;
57061da546Spatrick case 2:
58061da546Spatrick snprintf(str, sizeof(str), "0x%4.4x", value.uint16);
59061da546Spatrick break;
60061da546Spatrick case 4:
61061da546Spatrick snprintf(str, sizeof(str), "0x%8.8x", value.uint32);
62061da546Spatrick break;
63061da546Spatrick case 8:
64061da546Spatrick snprintf(str, sizeof(str), "0x%16.16llx", value.uint64);
65061da546Spatrick break;
66061da546Spatrick case 16:
67061da546Spatrick snprintf(str, sizeof(str), "0x%16.16llx%16.16llx", value.v_uint64[0],
68061da546Spatrick value.v_uint64[1]);
69061da546Spatrick break;
70061da546Spatrick default:
71061da546Spatrick strlcpy(str, "0x", 3);
72061da546Spatrick pos = str + 2;
73061da546Spatrick for (uint32_t i = 0; i < info.size; ++i) {
74061da546Spatrick if (pos < end)
75061da546Spatrick pos +=
76061da546Spatrick snprintf(pos, end - pos, "%2.2x", (uint32_t)value.v_uint8[i]);
77061da546Spatrick }
78061da546Spatrick break;
79061da546Spatrick }
80061da546Spatrick } else {
81061da546Spatrick switch (info.type) {
82061da546Spatrick case Uint:
83061da546Spatrick switch (info.size) {
84061da546Spatrick case 1:
85061da546Spatrick snprintf(str, sizeof(str), "%u", value.uint8);
86061da546Spatrick break;
87061da546Spatrick case 2:
88061da546Spatrick snprintf(str, sizeof(str), "%u", value.uint16);
89061da546Spatrick break;
90061da546Spatrick case 4:
91061da546Spatrick snprintf(str, sizeof(str), "%u", value.uint32);
92061da546Spatrick break;
93061da546Spatrick case 8:
94061da546Spatrick snprintf(str, sizeof(str), "%llu", value.uint64);
95061da546Spatrick break;
96061da546Spatrick default:
97061da546Spatrick snprintf(str, sizeof(str), "error: unsupported uint byte size %d.",
98061da546Spatrick info.size);
99061da546Spatrick break;
100061da546Spatrick }
101061da546Spatrick break;
102061da546Spatrick
103061da546Spatrick case Sint:
104061da546Spatrick switch (info.size) {
105061da546Spatrick case 1:
106061da546Spatrick snprintf(str, sizeof(str), "%d", value.sint8);
107061da546Spatrick break;
108061da546Spatrick case 2:
109061da546Spatrick snprintf(str, sizeof(str), "%d", value.sint16);
110061da546Spatrick break;
111061da546Spatrick case 4:
112061da546Spatrick snprintf(str, sizeof(str), "%d", value.sint32);
113061da546Spatrick break;
114061da546Spatrick case 8:
115061da546Spatrick snprintf(str, sizeof(str), "%lld", value.sint64);
116061da546Spatrick break;
117061da546Spatrick default:
118061da546Spatrick snprintf(str, sizeof(str), "error: unsupported sint byte size %d.",
119061da546Spatrick info.size);
120061da546Spatrick break;
121061da546Spatrick }
122061da546Spatrick break;
123061da546Spatrick
124061da546Spatrick case IEEE754:
125061da546Spatrick switch (info.size) {
126061da546Spatrick case 4:
127061da546Spatrick snprintf(str, sizeof(str), "%f", value.float32);
128061da546Spatrick break;
129061da546Spatrick case 8:
130061da546Spatrick snprintf(str, sizeof(str), "%g", value.float64);
131061da546Spatrick break;
132061da546Spatrick default:
133061da546Spatrick snprintf(str, sizeof(str), "error: unsupported float byte size %d.",
134061da546Spatrick info.size);
135061da546Spatrick break;
136061da546Spatrick }
137061da546Spatrick break;
138061da546Spatrick
139061da546Spatrick case Vector:
140061da546Spatrick if (info.size > 0) {
141061da546Spatrick switch (info.format) {
142061da546Spatrick case VectorOfSInt8:
143061da546Spatrick snprintf(str, sizeof(str), "%s", "sint8 { ");
144061da546Spatrick pos = str + strlen(str);
145061da546Spatrick for (uint32_t i = 0; i < info.size; ++i) {
146061da546Spatrick PRINT_COMMA_SEPARATOR;
147061da546Spatrick if (pos < end)
148061da546Spatrick pos +=
149061da546Spatrick snprintf(pos, end - pos, "%d", (int32_t)value.v_sint8[i]);
150061da546Spatrick }
151061da546Spatrick strlcat(str, " }", sizeof(str));
152061da546Spatrick break;
153061da546Spatrick
154061da546Spatrick default:
155061da546Spatrick DNBLogError(
156061da546Spatrick "unsupported vector format %d, defaulting to hex bytes.",
157061da546Spatrick info.format);
158061da546Spatrick [[clang::fallthrough]];
159061da546Spatrick case VectorOfUInt8:
160061da546Spatrick snprintf(str, sizeof(str), "%s", "uint8 { ");
161061da546Spatrick pos = str + strlen(str);
162061da546Spatrick for (uint32_t i = 0; i < info.size; ++i) {
163061da546Spatrick PRINT_COMMA_SEPARATOR;
164061da546Spatrick if (pos < end)
165061da546Spatrick pos +=
166061da546Spatrick snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint8[i]);
167061da546Spatrick }
168061da546Spatrick break;
169061da546Spatrick
170061da546Spatrick case VectorOfSInt16:
171061da546Spatrick snprintf(str, sizeof(str), "%s", "sint16 { ");
172061da546Spatrick pos = str + strlen(str);
173061da546Spatrick for (uint32_t i = 0; i < info.size / 2; ++i) {
174061da546Spatrick PRINT_COMMA_SEPARATOR;
175061da546Spatrick if (pos < end)
176061da546Spatrick pos +=
177061da546Spatrick snprintf(pos, end - pos, "%d", (int32_t)value.v_sint16[i]);
178061da546Spatrick }
179061da546Spatrick break;
180061da546Spatrick
181061da546Spatrick case VectorOfUInt16:
182061da546Spatrick snprintf(str, sizeof(str), "%s", "uint16 { ");
183061da546Spatrick pos = str + strlen(str);
184061da546Spatrick for (uint32_t i = 0; i < info.size / 2; ++i) {
185061da546Spatrick PRINT_COMMA_SEPARATOR;
186061da546Spatrick if (pos < end)
187061da546Spatrick pos +=
188061da546Spatrick snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint16[i]);
189061da546Spatrick }
190061da546Spatrick break;
191061da546Spatrick
192061da546Spatrick case VectorOfSInt32:
193061da546Spatrick snprintf(str, sizeof(str), "%s", "sint32 { ");
194061da546Spatrick pos = str + strlen(str);
195061da546Spatrick for (uint32_t i = 0; i < info.size / 4; ++i) {
196061da546Spatrick PRINT_COMMA_SEPARATOR;
197061da546Spatrick if (pos < end)
198061da546Spatrick pos +=
199061da546Spatrick snprintf(pos, end - pos, "%d", (int32_t)value.v_sint32[i]);
200061da546Spatrick }
201061da546Spatrick break;
202061da546Spatrick
203061da546Spatrick case VectorOfUInt32:
204061da546Spatrick snprintf(str, sizeof(str), "%s", "uint32 { ");
205061da546Spatrick pos = str + strlen(str);
206061da546Spatrick for (uint32_t i = 0; i < info.size / 4; ++i) {
207061da546Spatrick PRINT_COMMA_SEPARATOR;
208061da546Spatrick if (pos < end)
209061da546Spatrick pos +=
210061da546Spatrick snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint32[i]);
211061da546Spatrick }
212061da546Spatrick break;
213061da546Spatrick
214061da546Spatrick case VectorOfFloat32:
215061da546Spatrick snprintf(str, sizeof(str), "%s", "float32 { ");
216061da546Spatrick pos = str + strlen(str);
217061da546Spatrick for (uint32_t i = 0; i < info.size / 4; ++i) {
218061da546Spatrick PRINT_COMMA_SEPARATOR;
219061da546Spatrick if (pos < end)
220061da546Spatrick pos += snprintf(pos, end - pos, "%f", value.v_float32[i]);
221061da546Spatrick }
222061da546Spatrick break;
223061da546Spatrick
224061da546Spatrick case VectorOfUInt128:
225061da546Spatrick snprintf(str, sizeof(str), "%s", "uint128 { ");
226061da546Spatrick pos = str + strlen(str);
227061da546Spatrick for (uint32_t i = 0; i < info.size / 16; ++i) {
228061da546Spatrick PRINT_COMMA_SEPARATOR;
229061da546Spatrick if (pos < end)
230061da546Spatrick pos += snprintf(pos, end - pos, "0x%16.16llx%16.16llx",
231061da546Spatrick value.v_uint64[i], value.v_uint64[i + 1]);
232061da546Spatrick }
233061da546Spatrick break;
234061da546Spatrick }
235061da546Spatrick strlcat(str, " }", sizeof(str));
236061da546Spatrick } else {
237061da546Spatrick snprintf(str, sizeof(str), "error: unsupported vector size %d.",
238061da546Spatrick info.size);
239061da546Spatrick }
240061da546Spatrick break;
241061da546Spatrick
242061da546Spatrick default:
243061da546Spatrick snprintf(str, sizeof(str), "error: unsupported register type %d.",
244061da546Spatrick info.type);
245061da546Spatrick break;
246061da546Spatrick }
247061da546Spatrick }
248061da546Spatrick
249061da546Spatrick DNBLog("%s%4s = %s%s", pre ? pre : "", info.name, str, post ? post : "");
250061da546Spatrick }
251061da546Spatrick }
252