diff --git a/src/xenia/base/string_buffer.cc b/src/xenia/base/string_buffer.cc index 025c9b2e0..f512161f2 100644 --- a/src/xenia/base/string_buffer.cc +++ b/src/xenia/base/string_buffer.cc @@ -101,5 +101,73 @@ std::vector StringBuffer::to_bytes() const { std::memcpy(bytes.data(), buffer_, buffer_offset_); return bytes; } +#if XE_ARCH_AMD64 == 1 +static __m128i ToHexUpper(__m128i value) { + __m128i w = _mm_cvtepu8_epi16(value); + __m128i msk = + _mm_and_si128(_mm_or_si128(_mm_srli_epi16(w, 4), _mm_bslli_si128(w, 1)), + _mm_set1_epi16(0x0F0F)); + + __m128i conv = + _mm_shuffle_epi8(_mm_setr_epi8('0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'), + msk); + return conv; +} +#endif + +void StringBuffer::AppendHexUInt64(uint64_t value) { +#if XE_ARCH_AMD64 == 1 + __m128i conv = ToHexUpper(_mm_cvtsi64_si128(static_cast(value))); + + AppendBytes(reinterpret_cast(&conv), 16); +#else + AppendFormat("{:016X}", value); +#endif +} + +void StringBuffer::AppendHexUInt32(uint32_t value) { +#if XE_ARCH_AMD64 == 1 + __m128i conv = ToHexUpper(_mm_cvtsi32_si128(static_cast(value))); + + uint64_t low = _mm_cvtsi128_si64(conv); + + AppendBytes(reinterpret_cast(&low), 8); +#else + AppendFormat("{:08X}", value); +#endif +} + +void StringBuffer::AppendParenthesizedHexUInt32(uint32_t value) { +#if XE_ARCH_AMD64 == 1 + Grow(10); + + buffer_[buffer_offset_] = '('; + *reinterpret_cast(&buffer_[buffer_offset_ + 1]) = + _mm_cvtsi128_si64(ToHexUpper(_mm_cvtsi32_si128(value))); + buffer_[buffer_offset_ + 9] = ')'; + buffer_offset_ += 10; + buffer_[buffer_offset_] = 0; +#else + AppendFormat("({:08X})", value); +#endif +} + +void StringBuffer::AppendParenthesizedHexUInt64(uint64_t value) { +#if XE_ARCH_AMD64 == 1 + Grow(18); + + buffer_[buffer_offset_] = '('; + __m128i conv = ToHexUpper(_mm_cvtsi64_si128(static_cast(value))); + _mm_storeu_si128(reinterpret_cast<__m128i*>(&buffer_[buffer_offset_ + 1]), + conv); + + buffer_[buffer_offset_ + 17] = ')'; + buffer_offset_ += 18; + buffer_[buffer_offset_] = 0; +#else + AppendFormat("({:016X})", value); +#endif +} } // namespace xe diff --git a/src/xenia/base/string_buffer.h b/src/xenia/base/string_buffer.h index 9a4743deb..ac3050cb7 100644 --- a/src/xenia/base/string_buffer.h +++ b/src/xenia/base/string_buffer.h @@ -38,7 +38,10 @@ class StringBuffer { auto s = fmt::format(fmt::runtime(format), args...); Append(s.c_str()); } - + void AppendHexUInt64(uint64_t value); + void AppendHexUInt32(uint32_t value); + void AppendParenthesizedHexUInt32(uint32_t value); + void AppendParenthesizedHexUInt64(uint64_t value); void AppendVarargs(const char* format, va_list args); void AppendBytes(const uint8_t* buffer, size_t length); diff --git a/src/xenia/kernel/util/shim_utils.h b/src/xenia/kernel/util/shim_utils.h index babd68c9a..396d4863d 100644 --- a/src/xenia/kernel/util/shim_utils.h +++ b/src/xenia/kernel/util/shim_utils.h @@ -409,10 +409,10 @@ inline void AppendParam(StringBuffer* string_buffer, word_t param) { string_buffer->AppendFormat("{:04X}", uint16_t(param)); } inline void AppendParam(StringBuffer* string_buffer, dword_t param) { - string_buffer->AppendFormat("{:08X}", uint32_t(param)); + string_buffer->AppendHexUInt32(uint32_t(param)); } inline void AppendParam(StringBuffer* string_buffer, qword_t param) { - string_buffer->AppendFormat("{:016X}", uint64_t(param)); + string_buffer->AppendHexUInt64(uint64_t(param)); } inline void AppendParam(StringBuffer* string_buffer, float_t param) { string_buffer->AppendFormat("{:G}", static_cast(param)); @@ -421,28 +421,28 @@ inline void AppendParam(StringBuffer* string_buffer, double_t param) { string_buffer->AppendFormat("{:G}", static_cast(param)); } inline void AppendParam(StringBuffer* string_buffer, lpvoid_t param) { - string_buffer->AppendFormat("{:08X}", uint32_t(param)); + string_buffer->AppendHexUInt32(uint32_t(param)); } inline void AppendParam(StringBuffer* string_buffer, lpdword_t param) { - string_buffer->AppendFormat("{:08X}", param.guest_address()); + string_buffer->AppendHexUInt32(param.guest_address()); if (param) { - string_buffer->AppendFormat("({:08X})", param.value()); + string_buffer->AppendParenthesizedHexUInt32(param.value()); } } inline void AppendParam(StringBuffer* string_buffer, lpqword_t param) { - string_buffer->AppendFormat("{:08X}", param.guest_address()); + string_buffer->AppendHexUInt32(param.guest_address()); if (param) { - string_buffer->AppendFormat("({:016X})", param.value()); + string_buffer->AppendParenthesizedHexUInt64(param.value()); } } inline void AppendParam(StringBuffer* string_buffer, lpfloat_t param) { - string_buffer->AppendFormat("{:08X}", param.guest_address()); + string_buffer->AppendHexUInt32(param.guest_address()); if (param) { string_buffer->AppendFormat("({:G})", param.value()); } } inline void AppendParam(StringBuffer* string_buffer, lpdouble_t param) { - string_buffer->AppendFormat("{:08X}", param.guest_address()); + string_buffer->AppendHexUInt32(param.guest_address()); if (param) { string_buffer->AppendFormat("({:G})", param.value()); } @@ -451,20 +451,20 @@ inline void AppendParam(StringBuffer* string_buffer, ppc_context_t param) { string_buffer->Append("ContextArg"); } inline void AppendParam(StringBuffer* string_buffer, lpstring_t param) { - string_buffer->AppendFormat("{:08X}", param.guest_address()); + string_buffer->AppendHexUInt32(param.guest_address()); if (param) { string_buffer->AppendFormat("({})", param.value()); } } inline void AppendParam(StringBuffer* string_buffer, lpu16string_t param) { - string_buffer->AppendFormat("{:08X}", param.guest_address()); + string_buffer->AppendHexUInt32(param.guest_address()); if (param) { string_buffer->AppendFormat("({})", xe::to_utf8(param.value())); } } inline void AppendParam(StringBuffer* string_buffer, pointer_t record) { - string_buffer->AppendFormat("{:08X}", record.guest_address()); + string_buffer->AppendHexUInt32(record.guest_address()); if (record) { auto name_string = kernel_memory()->TranslateVirtual(record->name_ptr); @@ -490,7 +490,7 @@ inline void AppendParam(StringBuffer* string_buffer, } template void AppendParam(StringBuffer* string_buffer, pointer_t param) { - string_buffer->AppendFormat("{:08X}", param.guest_address()); + string_buffer->AppendHexUInt32(param.guest_address()); } enum class KernelModuleId {