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