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
DNBRegisterValueClass(const DNBRegisterInfo * regInfo)18 DNBRegisterValueClass::DNBRegisterValueClass(const DNBRegisterInfo *regInfo)
19 {
20 Clear();
21 if (regInfo)
22 info = *regInfo;
23 }
24
25 void
Clear()26 DNBRegisterValueClass::Clear()
27 {
28 memset(&info, 0, sizeof(DNBRegisterInfo));
29 memset(&value, 0, sizeof(value));
30 }
31
32 bool
IsValid() const33 DNBRegisterValueClass::IsValid() const
34 {
35 return
36 info.name != NULL &&
37 info.type != InvalidRegType &&
38 info.size > 0 && info.size <= sizeof(value);
39 }
40
41 #define PRINT_COMMA_SEPARATOR do { if (pos < end) { if (i > 0) { strncpy(pos, ", ", end - pos); pos += 2; } } } while (0)
42
43 void
Dump(const char * pre,const char * post) const44 DNBRegisterValueClass::Dump(const char *pre, const char *post) const
45 {
46 if (info.name != NULL)
47 {
48 int i;
49 char str[1024];
50 char *pos;
51 char *end = str + sizeof(str);
52 if (info.format == Hex)
53 {
54 switch (info.size)
55 {
56 case 0: snprintf(str, sizeof(str), "%s", "error: invalid register size of zero."); break;
57 case 1: snprintf(str, sizeof(str), "0x%2.2x", value.uint8); break;
58 case 2: snprintf(str, sizeof(str), "0x%4.4x", value.uint16); break;
59 case 4: snprintf(str, sizeof(str), "0x%8.8x", value.uint32); break;
60 case 8: snprintf(str, sizeof(str), "0x%16.16llx", value.uint64); break;
61 case 16: snprintf(str, sizeof(str), "0x%16.16llx%16.16llx", value.v_uint64[0], value.v_uint64[1]); break;
62 default:
63 strncpy(str, "0x", 3);
64 pos = str + 2;
65 for (i=0; i<info.size; ++i)
66 {
67 if (pos < end)
68 pos += snprintf(pos, end - pos, "%2.2x", (uint32_t)value.v_uint8[i]);
69 }
70 break;
71 }
72 }
73 else
74 {
75 switch (info.type)
76 {
77 case Uint:
78 switch (info.size)
79 {
80 case 1: snprintf(str, sizeof(str), "%u", value.uint8); break;
81 case 2: snprintf(str, sizeof(str), "%u", value.uint16); break;
82 case 4: snprintf(str, sizeof(str), "%u", value.uint32); break;
83 case 8: snprintf(str, sizeof(str), "%llu", value.uint64); break;
84 default: snprintf(str, sizeof(str), "error: unsupported uint byte size %d.", info.size); break;
85 }
86 break;
87
88 case Sint:
89 switch (info.size)
90 {
91 case 1: snprintf(str, sizeof(str), "%d", value.sint8); break;
92 case 2: snprintf(str, sizeof(str), "%d", value.sint16); break;
93 case 4: snprintf(str, sizeof(str), "%d", value.sint32); break;
94 case 8: snprintf(str, sizeof(str), "%lld", value.sint64); break;
95 default: snprintf(str, sizeof(str), "error: unsupported sint byte size %d.", info.size); break;
96 }
97 break;
98
99 case IEEE754:
100 switch (info.size)
101 {
102 case 4: snprintf(str, sizeof(str), "%f", value.float32); break;
103 case 8: snprintf(str, sizeof(str), "%g", value.float64); break;
104 default: snprintf(str, sizeof(str), "error: unsupported float byte size %d.", info.size); break;
105 }
106 break;
107
108 case Vector:
109 if (info.size > 0)
110 {
111 switch (info.format)
112 {
113 case VectorOfSInt8:
114 snprintf(str, sizeof(str), "%s", "sint8 { ");
115 pos = str + strlen(str);
116 for (i=0; i<info.size; ++i)
117 {
118 PRINT_COMMA_SEPARATOR;
119 if (pos < end)
120 pos += snprintf(pos, end - pos, "%d", (int32_t)value.v_sint8[i]);
121 }
122 strlcat(str, " }", sizeof(str));
123 break;
124
125 default:
126 DNBLogError("unsupported vector format %d, defaulting to hex bytes.", info.format);
127 case VectorOfUInt8:
128 snprintf(str, sizeof(str), "%s", "uint8 { ");
129 pos = str + strlen(str);
130 for (i=0; i<info.size; ++i)
131 {
132 PRINT_COMMA_SEPARATOR;
133 if (pos < end)
134 pos += snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint8[i]);
135 }
136 break;
137
138 case VectorOfSInt16:
139 snprintf(str, sizeof(str), "%s", "sint16 { ");
140 pos = str + strlen(str);
141 for (i=0; i<info.size/2; ++i)
142 {
143 PRINT_COMMA_SEPARATOR;
144 if (pos < end)
145 pos += snprintf(pos, end - pos, "%d", (int32_t)value.v_sint16[i]);
146 }
147 break;
148
149 case VectorOfUInt16:
150 snprintf(str, sizeof(str), "%s", "uint16 { ");
151 pos = str + strlen(str);
152 for (i=0; i<info.size/2; ++i)
153 {
154 PRINT_COMMA_SEPARATOR;
155 if (pos < end)
156 pos += snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint16[i]);
157 }
158 break;
159
160 case VectorOfSInt32:
161 snprintf(str, sizeof(str), "%s", "sint32 { ");
162 pos = str + strlen(str);
163 for (i=0; i<info.size/4; ++i)
164 {
165 PRINT_COMMA_SEPARATOR;
166 if (pos < end)
167 pos += snprintf(pos, end - pos, "%d", (int32_t)value.v_sint32[i]);
168 }
169 break;
170
171 case VectorOfUInt32:
172 snprintf(str, sizeof(str), "%s", "uint32 { ");
173 pos = str + strlen(str);
174 for (i=0; i<info.size/4; ++i)
175 {
176 PRINT_COMMA_SEPARATOR;
177 if (pos < end)
178 pos += snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint32[i]);
179 }
180 break;
181
182 case VectorOfFloat32:
183 snprintf(str, sizeof(str), "%s", "float32 { ");
184 pos = str + strlen(str);
185 for (i=0; i<info.size/4; ++i)
186 {
187 PRINT_COMMA_SEPARATOR;
188 if (pos < end)
189 pos += snprintf(pos, end - pos, "%f", value.v_float32[i]);
190 }
191 break;
192
193 case VectorOfUInt128:
194 snprintf(str, sizeof(str), "%s", "uint128 { ");
195 pos = str + strlen(str);
196 for (i=0; i<info.size/16; ++i)
197 {
198 PRINT_COMMA_SEPARATOR;
199 if (pos < end)
200 pos += snprintf(pos, end - pos, "0x%16.16llx%16.16llx", value.v_uint64[i], value.v_uint64[i+1]);
201 }
202 break;
203 }
204 strlcat(str, " }", sizeof(str));
205 }
206 else
207 {
208 snprintf(str, sizeof(str), "error: unsupported vector size %d.", info.size);
209 }
210 break;
211
212 default:
213 snprintf(str, sizeof(str), "error: unsupported register type %d.", info.type);
214 break;
215 }
216 }
217
218 DNBLog("%s%4s = %s%s", pre ? pre : "", info.name, str, post ? post : "");
219 }
220 }
221