//===-- DNBRegisterInfo.cpp -------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Created by Greg Clayton on 8/3/07. // //===----------------------------------------------------------------------===// #include "DNBRegisterInfo.h" #include "DNBLog.h" #include DNBRegisterValueClass::DNBRegisterValueClass(const DNBRegisterInfo *regInfo) { Clear(); if (regInfo) info = *regInfo; } void DNBRegisterValueClass::Clear() { memset(&info, 0, sizeof(DNBRegisterInfo)); memset(&value, 0, sizeof(value)); } bool DNBRegisterValueClass::IsValid() const { return info.name != NULL && info.type != InvalidRegType && info.size > 0 && info.size <= sizeof(value); } #define PRINT_COMMA_SEPARATOR \ do { \ if (pos < end) { \ if (i > 0) { \ strlcpy(pos, ", ", end - pos); \ pos += 2; \ } \ } \ } while (0) void DNBRegisterValueClass::Dump(const char *pre, const char *post) const { if (info.name != NULL) { char str[1024]; char *pos; char *end = str + sizeof(str); if (info.format == Hex) { switch (info.size) { case 0: snprintf(str, sizeof(str), "%s", "error: invalid register size of zero."); break; case 1: snprintf(str, sizeof(str), "0x%2.2x", value.uint8); break; case 2: snprintf(str, sizeof(str), "0x%4.4x", value.uint16); break; case 4: snprintf(str, sizeof(str), "0x%8.8x", value.uint32); break; case 8: snprintf(str, sizeof(str), "0x%16.16llx", value.uint64); break; case 16: snprintf(str, sizeof(str), "0x%16.16llx%16.16llx", value.v_uint64[0], value.v_uint64[1]); break; default: strlcpy(str, "0x", 3); pos = str + 2; for (uint32_t i = 0; i < info.size; ++i) { if (pos < end) pos += snprintf(pos, end - pos, "%2.2x", (uint32_t)value.v_uint8[i]); } break; } } else { switch (info.type) { case Uint: switch (info.size) { case 1: snprintf(str, sizeof(str), "%u", value.uint8); break; case 2: snprintf(str, sizeof(str), "%u", value.uint16); break; case 4: snprintf(str, sizeof(str), "%u", value.uint32); break; case 8: snprintf(str, sizeof(str), "%llu", value.uint64); break; default: snprintf(str, sizeof(str), "error: unsupported uint byte size %d.", info.size); break; } break; case Sint: switch (info.size) { case 1: snprintf(str, sizeof(str), "%d", value.sint8); break; case 2: snprintf(str, sizeof(str), "%d", value.sint16); break; case 4: snprintf(str, sizeof(str), "%d", value.sint32); break; case 8: snprintf(str, sizeof(str), "%lld", value.sint64); break; default: snprintf(str, sizeof(str), "error: unsupported sint byte size %d.", info.size); break; } break; case IEEE754: switch (info.size) { case 4: snprintf(str, sizeof(str), "%f", value.float32); break; case 8: snprintf(str, sizeof(str), "%g", value.float64); break; default: snprintf(str, sizeof(str), "error: unsupported float byte size %d.", info.size); break; } break; case Vector: if (info.size > 0) { switch (info.format) { case VectorOfSInt8: snprintf(str, sizeof(str), "%s", "sint8 { "); pos = str + strlen(str); for (uint32_t i = 0; i < info.size; ++i) { PRINT_COMMA_SEPARATOR; if (pos < end) pos += snprintf(pos, end - pos, "%d", (int32_t)value.v_sint8[i]); } strlcat(str, " }", sizeof(str)); break; default: DNBLogError( "unsupported vector format %d, defaulting to hex bytes.", info.format); [[clang::fallthrough]]; case VectorOfUInt8: snprintf(str, sizeof(str), "%s", "uint8 { "); pos = str + strlen(str); for (uint32_t i = 0; i < info.size; ++i) { PRINT_COMMA_SEPARATOR; if (pos < end) pos += snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint8[i]); } break; case VectorOfSInt16: snprintf(str, sizeof(str), "%s", "sint16 { "); pos = str + strlen(str); for (uint32_t i = 0; i < info.size / 2; ++i) { PRINT_COMMA_SEPARATOR; if (pos < end) pos += snprintf(pos, end - pos, "%d", (int32_t)value.v_sint16[i]); } break; case VectorOfUInt16: snprintf(str, sizeof(str), "%s", "uint16 { "); pos = str + strlen(str); for (uint32_t i = 0; i < info.size / 2; ++i) { PRINT_COMMA_SEPARATOR; if (pos < end) pos += snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint16[i]); } break; case VectorOfSInt32: snprintf(str, sizeof(str), "%s", "sint32 { "); pos = str + strlen(str); for (uint32_t i = 0; i < info.size / 4; ++i) { PRINT_COMMA_SEPARATOR; if (pos < end) pos += snprintf(pos, end - pos, "%d", (int32_t)value.v_sint32[i]); } break; case VectorOfUInt32: snprintf(str, sizeof(str), "%s", "uint32 { "); pos = str + strlen(str); for (uint32_t i = 0; i < info.size / 4; ++i) { PRINT_COMMA_SEPARATOR; if (pos < end) pos += snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint32[i]); } break; case VectorOfFloat32: snprintf(str, sizeof(str), "%s", "float32 { "); pos = str + strlen(str); for (uint32_t i = 0; i < info.size / 4; ++i) { PRINT_COMMA_SEPARATOR; if (pos < end) pos += snprintf(pos, end - pos, "%f", value.v_float32[i]); } break; case VectorOfUInt128: snprintf(str, sizeof(str), "%s", "uint128 { "); pos = str + strlen(str); for (uint32_t i = 0; i < info.size / 16; ++i) { PRINT_COMMA_SEPARATOR; if (pos < end) pos += snprintf(pos, end - pos, "0x%16.16llx%16.16llx", value.v_uint64[i], value.v_uint64[i + 1]); } break; } strlcat(str, " }", sizeof(str)); } else { snprintf(str, sizeof(str), "error: unsupported vector size %d.", info.size); } break; default: snprintf(str, sizeof(str), "error: unsupported register type %d.", info.type); break; } } DNBLog("%s%4s = %s%s", pre ? pre : "", info.name, str, post ? post : ""); } }