• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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