DNBRegisterInfo.cpp revision b7a22b2bea7904809acdc101b0dfa2100265e22a
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
18DNBRegisterValueClass::DNBRegisterValueClass(const DNBRegisterInfo *regInfo)
19{
20    Clear();
21    if (regInfo)
22        info = *regInfo;
23}
24
25void
26DNBRegisterValueClass::Clear()
27{
28    memset(&info, 0, sizeof(DNBRegisterInfo));
29    memset(&value, 0, sizeof(value));
30}
31
32bool
33DNBRegisterValueClass::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
43void
44DNBRegisterValueClass::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