blob: a8f09bc8784032bb55c8c3abe5557d5fed524109 [file] [log] [blame]
//===-- 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 : "");
}
}