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