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