| //===-- DNBRegisterInfo.cpp -------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // Created by Greg Clayton on 8/3/07. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "DNBRegisterInfo.h" |
| #include "DNBLog.h" |
| #include <string.h> |
| |
| 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) { strncpy(pos, ", ", end - pos); pos += 2; } } } while (0) |
| |
| void |
| DNBRegisterValueClass::Dump(const char *pre, const char *post) const |
| { |
| if (info.name != NULL) |
| { |
| int i; |
| 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: |
| strncpy(str, "0x", 3); |
| pos = str + 2; |
| for (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 (i=0; i<info.size; ++i) |
| { |
| PRINT_COMMA_SEPARATOR; |
| if (pos < end) |
| pos += snprintf(pos, end - pos, "%d", (int32_t)value.v_sint8[i]); |
| } |
| strncat(str, " }", sizeof(str)); |
| break; |
| |
| default: |
| DNBLogError("unsupported vector format %d, defaulting to hex bytes.", info.format); |
| case VectorOfUInt8: |
| snprintf(str, sizeof(str), "%s", "uint8 { "); |
| pos = str + strlen(str); |
| for (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 (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 (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 (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 (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 (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 (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; |
| } |
| strncat(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 : ""); |
| } |
| } |