130fdc8d8SChris Lattner //===-- DNBRegisterInfo.cpp -------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner //
930fdc8d8SChris Lattner //  Created by Greg Clayton on 8/3/07.
1030fdc8d8SChris Lattner //
1130fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
1230fdc8d8SChris Lattner 
1330fdc8d8SChris Lattner #include "DNBRegisterInfo.h"
1430fdc8d8SChris Lattner #include "DNBLog.h"
15*76e47d48SRaphael Isemann #include <cstring>
1630fdc8d8SChris Lattner 
DNBRegisterValueClass(const DNBRegisterInfo * regInfo)17b9c1b51eSKate Stone DNBRegisterValueClass::DNBRegisterValueClass(const DNBRegisterInfo *regInfo) {
1830fdc8d8SChris Lattner   Clear();
1930fdc8d8SChris Lattner   if (regInfo)
2030fdc8d8SChris Lattner     info = *regInfo;
2130fdc8d8SChris Lattner }
2230fdc8d8SChris Lattner 
Clear()23b9c1b51eSKate Stone void DNBRegisterValueClass::Clear() {
2430fdc8d8SChris Lattner   memset(&info, 0, sizeof(DNBRegisterInfo));
2530fdc8d8SChris Lattner   memset(&value, 0, sizeof(value));
2630fdc8d8SChris Lattner }
2730fdc8d8SChris Lattner 
IsValid() const28b9c1b51eSKate Stone bool DNBRegisterValueClass::IsValid() const {
29b9c1b51eSKate Stone   return info.name != NULL && info.type != InvalidRegType && info.size > 0 &&
30b9c1b51eSKate Stone          info.size <= sizeof(value);
3130fdc8d8SChris Lattner }
3230fdc8d8SChris Lattner 
33b9c1b51eSKate Stone #define PRINT_COMMA_SEPARATOR                                                  \
34b9c1b51eSKate Stone   do {                                                                         \
35b9c1b51eSKate Stone     if (pos < end) {                                                           \
36b9c1b51eSKate Stone       if (i > 0) {                                                             \
37aae5b690SJason Molenda         strlcpy(pos, ", ", end - pos);                                         \
38b9c1b51eSKate Stone         pos += 2;                                                              \
39b9c1b51eSKate Stone       }                                                                        \
40b9c1b51eSKate Stone     }                                                                          \
41b9c1b51eSKate Stone   } while (0)
4230fdc8d8SChris Lattner 
Dump(const char * pre,const char * post) const43b9c1b51eSKate Stone void DNBRegisterValueClass::Dump(const char *pre, const char *post) const {
44b9c1b51eSKate Stone   if (info.name != NULL) {
4530fdc8d8SChris Lattner     char str[1024];
4630fdc8d8SChris Lattner     char *pos;
4730fdc8d8SChris Lattner     char *end = str + sizeof(str);
48b9c1b51eSKate Stone     if (info.format == Hex) {
49b9c1b51eSKate Stone       switch (info.size) {
50b9c1b51eSKate Stone       case 0:
51b9c1b51eSKate Stone         snprintf(str, sizeof(str), "%s",
52b9c1b51eSKate Stone                  "error: invalid register size of zero.");
53b9c1b51eSKate Stone         break;
54b9c1b51eSKate Stone       case 1:
55b9c1b51eSKate Stone         snprintf(str, sizeof(str), "0x%2.2x", value.uint8);
56b9c1b51eSKate Stone         break;
57b9c1b51eSKate Stone       case 2:
58b9c1b51eSKate Stone         snprintf(str, sizeof(str), "0x%4.4x", value.uint16);
59b9c1b51eSKate Stone         break;
60b9c1b51eSKate Stone       case 4:
61b9c1b51eSKate Stone         snprintf(str, sizeof(str), "0x%8.8x", value.uint32);
62b9c1b51eSKate Stone         break;
63b9c1b51eSKate Stone       case 8:
64b9c1b51eSKate Stone         snprintf(str, sizeof(str), "0x%16.16llx", value.uint64);
65b9c1b51eSKate Stone         break;
66b9c1b51eSKate Stone       case 16:
67b9c1b51eSKate Stone         snprintf(str, sizeof(str), "0x%16.16llx%16.16llx", value.v_uint64[0],
68b9c1b51eSKate Stone                  value.v_uint64[1]);
69b9c1b51eSKate Stone         break;
7030fdc8d8SChris Lattner       default:
71aae5b690SJason Molenda         strlcpy(str, "0x", 3);
7230fdc8d8SChris Lattner         pos = str + 2;
73b9c1b51eSKate Stone         for (uint32_t i = 0; i < info.size; ++i) {
7430fdc8d8SChris Lattner           if (pos < end)
75b9c1b51eSKate Stone             pos +=
76b9c1b51eSKate Stone                 snprintf(pos, end - pos, "%2.2x", (uint32_t)value.v_uint8[i]);
7730fdc8d8SChris Lattner         }
7830fdc8d8SChris Lattner         break;
7930fdc8d8SChris Lattner       }
80b9c1b51eSKate Stone     } else {
81b9c1b51eSKate Stone       switch (info.type) {
8230fdc8d8SChris Lattner       case Uint:
83b9c1b51eSKate Stone         switch (info.size) {
84b9c1b51eSKate Stone         case 1:
85b9c1b51eSKate Stone           snprintf(str, sizeof(str), "%u", value.uint8);
86b9c1b51eSKate Stone           break;
87b9c1b51eSKate Stone         case 2:
88b9c1b51eSKate Stone           snprintf(str, sizeof(str), "%u", value.uint16);
89b9c1b51eSKate Stone           break;
90b9c1b51eSKate Stone         case 4:
91b9c1b51eSKate Stone           snprintf(str, sizeof(str), "%u", value.uint32);
92b9c1b51eSKate Stone           break;
93b9c1b51eSKate Stone         case 8:
94b9c1b51eSKate Stone           snprintf(str, sizeof(str), "%llu", value.uint64);
95b9c1b51eSKate Stone           break;
96b9c1b51eSKate Stone         default:
97b9c1b51eSKate Stone           snprintf(str, sizeof(str), "error: unsupported uint byte size %d.",
98b9c1b51eSKate Stone                    info.size);
99b9c1b51eSKate Stone           break;
10030fdc8d8SChris Lattner         }
10130fdc8d8SChris Lattner         break;
10230fdc8d8SChris Lattner 
10330fdc8d8SChris Lattner       case Sint:
104b9c1b51eSKate Stone         switch (info.size) {
105b9c1b51eSKate Stone         case 1:
106b9c1b51eSKate Stone           snprintf(str, sizeof(str), "%d", value.sint8);
107b9c1b51eSKate Stone           break;
108b9c1b51eSKate Stone         case 2:
109b9c1b51eSKate Stone           snprintf(str, sizeof(str), "%d", value.sint16);
110b9c1b51eSKate Stone           break;
111b9c1b51eSKate Stone         case 4:
112b9c1b51eSKate Stone           snprintf(str, sizeof(str), "%d", value.sint32);
113b9c1b51eSKate Stone           break;
114b9c1b51eSKate Stone         case 8:
115b9c1b51eSKate Stone           snprintf(str, sizeof(str), "%lld", value.sint64);
116b9c1b51eSKate Stone           break;
117b9c1b51eSKate Stone         default:
118b9c1b51eSKate Stone           snprintf(str, sizeof(str), "error: unsupported sint byte size %d.",
119b9c1b51eSKate Stone                    info.size);
120b9c1b51eSKate Stone           break;
12130fdc8d8SChris Lattner         }
12230fdc8d8SChris Lattner         break;
12330fdc8d8SChris Lattner 
12430fdc8d8SChris Lattner       case IEEE754:
125b9c1b51eSKate Stone         switch (info.size) {
126b9c1b51eSKate Stone         case 4:
127b9c1b51eSKate Stone           snprintf(str, sizeof(str), "%f", value.float32);
128b9c1b51eSKate Stone           break;
129b9c1b51eSKate Stone         case 8:
130b9c1b51eSKate Stone           snprintf(str, sizeof(str), "%g", value.float64);
131b9c1b51eSKate Stone           break;
132b9c1b51eSKate Stone         default:
133b9c1b51eSKate Stone           snprintf(str, sizeof(str), "error: unsupported float byte size %d.",
134b9c1b51eSKate Stone                    info.size);
135b9c1b51eSKate Stone           break;
13630fdc8d8SChris Lattner         }
13730fdc8d8SChris Lattner         break;
13830fdc8d8SChris Lattner 
13930fdc8d8SChris Lattner       case Vector:
140b9c1b51eSKate Stone         if (info.size > 0) {
141b9c1b51eSKate Stone           switch (info.format) {
14230fdc8d8SChris Lattner           case VectorOfSInt8:
14330fdc8d8SChris Lattner             snprintf(str, sizeof(str), "%s", "sint8   { ");
14430fdc8d8SChris Lattner             pos = str + strlen(str);
145b9c1b51eSKate Stone             for (uint32_t i = 0; i < info.size; ++i) {
14630fdc8d8SChris Lattner               PRINT_COMMA_SEPARATOR;
14730fdc8d8SChris Lattner               if (pos < end)
148b9c1b51eSKate Stone                 pos +=
149b9c1b51eSKate Stone                     snprintf(pos, end - pos, "%d", (int32_t)value.v_sint8[i]);
15030fdc8d8SChris Lattner             }
1517afbe07aSGreg Clayton             strlcat(str, " }", sizeof(str));
15230fdc8d8SChris Lattner             break;
15330fdc8d8SChris Lattner 
15430fdc8d8SChris Lattner           default:
155b9c1b51eSKate Stone             DNBLogError(
156b9c1b51eSKate Stone                 "unsupported vector format %d, defaulting to hex bytes.",
157b9c1b51eSKate Stone                 info.format);
158a1050973SJason Molenda             [[clang::fallthrough]];
15930fdc8d8SChris Lattner           case VectorOfUInt8:
16030fdc8d8SChris Lattner             snprintf(str, sizeof(str), "%s", "uint8   { ");
16130fdc8d8SChris Lattner             pos = str + strlen(str);
162b9c1b51eSKate Stone             for (uint32_t i = 0; i < info.size; ++i) {
16330fdc8d8SChris Lattner               PRINT_COMMA_SEPARATOR;
16430fdc8d8SChris Lattner               if (pos < end)
165b9c1b51eSKate Stone                 pos +=
166b9c1b51eSKate Stone                     snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint8[i]);
16730fdc8d8SChris Lattner             }
16830fdc8d8SChris Lattner             break;
16930fdc8d8SChris Lattner 
17030fdc8d8SChris Lattner           case VectorOfSInt16:
17130fdc8d8SChris Lattner             snprintf(str, sizeof(str), "%s", "sint16  { ");
17230fdc8d8SChris Lattner             pos = str + strlen(str);
173b9c1b51eSKate Stone             for (uint32_t i = 0; i < info.size / 2; ++i) {
17430fdc8d8SChris Lattner               PRINT_COMMA_SEPARATOR;
17530fdc8d8SChris Lattner               if (pos < end)
176b9c1b51eSKate Stone                 pos +=
177b9c1b51eSKate Stone                     snprintf(pos, end - pos, "%d", (int32_t)value.v_sint16[i]);
17830fdc8d8SChris Lattner             }
17930fdc8d8SChris Lattner             break;
18030fdc8d8SChris Lattner 
18130fdc8d8SChris Lattner           case VectorOfUInt16:
18230fdc8d8SChris Lattner             snprintf(str, sizeof(str), "%s", "uint16  { ");
18330fdc8d8SChris Lattner             pos = str + strlen(str);
184b9c1b51eSKate Stone             for (uint32_t i = 0; i < info.size / 2; ++i) {
18530fdc8d8SChris Lattner               PRINT_COMMA_SEPARATOR;
18630fdc8d8SChris Lattner               if (pos < end)
187b9c1b51eSKate Stone                 pos +=
188b9c1b51eSKate Stone                     snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint16[i]);
18930fdc8d8SChris Lattner             }
19030fdc8d8SChris Lattner             break;
19130fdc8d8SChris Lattner 
19230fdc8d8SChris Lattner           case VectorOfSInt32:
19330fdc8d8SChris Lattner             snprintf(str, sizeof(str), "%s", "sint32  { ");
19430fdc8d8SChris Lattner             pos = str + strlen(str);
195b9c1b51eSKate Stone             for (uint32_t i = 0; i < info.size / 4; ++i) {
19630fdc8d8SChris Lattner               PRINT_COMMA_SEPARATOR;
19730fdc8d8SChris Lattner               if (pos < end)
198b9c1b51eSKate Stone                 pos +=
199b9c1b51eSKate Stone                     snprintf(pos, end - pos, "%d", (int32_t)value.v_sint32[i]);
20030fdc8d8SChris Lattner             }
20130fdc8d8SChris Lattner             break;
20230fdc8d8SChris Lattner 
20330fdc8d8SChris Lattner           case VectorOfUInt32:
20430fdc8d8SChris Lattner             snprintf(str, sizeof(str), "%s", "uint32  { ");
20530fdc8d8SChris Lattner             pos = str + strlen(str);
206b9c1b51eSKate Stone             for (uint32_t i = 0; i < info.size / 4; ++i) {
20730fdc8d8SChris Lattner               PRINT_COMMA_SEPARATOR;
20830fdc8d8SChris Lattner               if (pos < end)
209b9c1b51eSKate Stone                 pos +=
210b9c1b51eSKate Stone                     snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint32[i]);
21130fdc8d8SChris Lattner             }
21230fdc8d8SChris Lattner             break;
21330fdc8d8SChris Lattner 
21430fdc8d8SChris Lattner           case VectorOfFloat32:
21530fdc8d8SChris Lattner             snprintf(str, sizeof(str), "%s", "float32 { ");
21630fdc8d8SChris Lattner             pos = str + strlen(str);
217b9c1b51eSKate Stone             for (uint32_t i = 0; i < info.size / 4; ++i) {
21830fdc8d8SChris Lattner               PRINT_COMMA_SEPARATOR;
21930fdc8d8SChris Lattner               if (pos < end)
22030fdc8d8SChris Lattner                 pos += snprintf(pos, end - pos, "%f", value.v_float32[i]);
22130fdc8d8SChris Lattner             }
22230fdc8d8SChris Lattner             break;
22330fdc8d8SChris Lattner 
22430fdc8d8SChris Lattner           case VectorOfUInt128:
22530fdc8d8SChris Lattner             snprintf(str, sizeof(str), "%s", "uint128 { ");
22630fdc8d8SChris Lattner             pos = str + strlen(str);
227b9c1b51eSKate Stone             for (uint32_t i = 0; i < info.size / 16; ++i) {
22830fdc8d8SChris Lattner               PRINT_COMMA_SEPARATOR;
22930fdc8d8SChris Lattner               if (pos < end)
230b9c1b51eSKate Stone                 pos += snprintf(pos, end - pos, "0x%16.16llx%16.16llx",
231b9c1b51eSKate Stone                                 value.v_uint64[i], value.v_uint64[i + 1]);
23230fdc8d8SChris Lattner             }
23330fdc8d8SChris Lattner             break;
23430fdc8d8SChris Lattner           }
2357afbe07aSGreg Clayton           strlcat(str, " }", sizeof(str));
236b9c1b51eSKate Stone         } else {
237b9c1b51eSKate Stone           snprintf(str, sizeof(str), "error: unsupported vector size %d.",
238b9c1b51eSKate Stone                    info.size);
23930fdc8d8SChris Lattner         }
24030fdc8d8SChris Lattner         break;
24130fdc8d8SChris Lattner 
24230fdc8d8SChris Lattner       default:
243b9c1b51eSKate Stone         snprintf(str, sizeof(str), "error: unsupported register type %d.",
244b9c1b51eSKate Stone                  info.type);
24530fdc8d8SChris Lattner         break;
24630fdc8d8SChris Lattner       }
24730fdc8d8SChris Lattner     }
24830fdc8d8SChris Lattner 
24930fdc8d8SChris Lattner     DNBLog("%s%4s = %s%s", pre ? pre : "", info.name, str, post ? post : "");
25030fdc8d8SChris Lattner   }
25130fdc8d8SChris Lattner }
252