252 lines · cpp
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-exception6//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