diff --git a/Utilities/BEType.h b/Utilities/BEType.h index be6f012c70..4476106a3a 100644 --- a/Utilities/BEType.h +++ b/Utilities/BEType.h @@ -327,14 +327,44 @@ inline v128 operator ~(const v128& other) #define IS_INTEGER(t) (std::is_integral::value || std::is_enum::value) #define IS_BINARY_COMPARABLE(t1, t2) (IS_INTEGER(t1) && IS_INTEGER(t2) && sizeof(t1) == sizeof(t2)) -template +template struct se_storage { - static_assert(!Size, "Bad se_storage<> type"); + using type = std::aligned_storage_t; + + // Unoptimized generic byteswap for unaligned data + static void reverse(u8* dst, const u8* src) + { + for (std::size_t i = 0; i < Size; i++) + { + dst[i] = src[Size - 1 - i]; + } + } + + static type to(const T& src) + { + type result; + reverse(reinterpret_cast(&result), reinterpret_cast(&src)); + return result; + } + + static T from(const type& src) + { + T result; + reverse(reinterpret_cast(&result), reinterpret_cast(&src)); + return result; + } + + static type copy(const type& src) + { + type result; + std::memcpy(&result, &src, Size); + return result; + } }; template -struct se_storage +struct se_storage { using type = u16; @@ -357,10 +387,15 @@ struct se_storage const u16 result = swap(src); return reinterpret_cast(result); } + + static inline T copy(const T& src) + { + return src; + } }; template -struct se_storage +struct se_storage { using type = u32; @@ -383,10 +418,15 @@ struct se_storage const u32 result = swap(src); return reinterpret_cast(result); } + + static inline T copy(const T& src) + { + return src; + } }; template -struct se_storage +struct se_storage { using type = u64; @@ -409,10 +449,15 @@ struct se_storage const u64 result = swap(src); return reinterpret_cast(result); } + + static inline T copy(const T& src) + { + return src; + } }; template -struct se_storage +struct se_storage { using type = v128; @@ -431,43 +476,22 @@ struct se_storage const v128 result = swap(src); return reinterpret_cast(result); } -}; -template using se_storage_t = typename se_storage::type; - -template -struct se_convert -{ - using type_from = std::remove_cv_t; - using type_to = std::remove_cv_t; - using stype_from = se_storage_t>; - using stype_to = se_storage_t>; - using storage_from = se_storage>; - using storage_to = se_storage>; - - static inline std::enable_if_t::value, stype_to> convert(const stype_from& data) + static inline T copy(const T& src) { - return data; - } - - static inline stype_to convert(const stype_from& data, ...) - { - return storage_to::to(storage_from::from(data)); + return src; } }; static struct se_raw_tag_t {} constexpr se_raw{}; -template -class se_t; - // Switched endianness -template -class se_t +template +class se_t { using type = typename std::remove_cv::type; - using stype = se_storage_t; - using storage = se_storage; + using stype = typename se_storage::type; + using storage = se_storage; stype m_data; @@ -585,39 +609,41 @@ public: }; // Native endianness -template -class se_t +template +class se_t { using type = typename std::remove_cv::type; + using stype = typename se_storage::type; + using storage = se_storage; static_assert(!std::is_pointer::value, "se_t<> error: invalid type (pointer)"); static_assert(!std::is_reference::value, "se_t<> error: invalid type (reference)"); static_assert(!std::is_array::value, "se_t<> error: invalid type (array)"); static_assert(sizeof(type) == alignof(type), "se_t<> error: unexpected alignment"); - type m_data; + stype m_data; public: se_t() = default; - constexpr se_t(type value) - : m_data(value) + se_t(type value) + : m_data(reinterpret_cast(value)) { } // Construct directly from raw data (don't use) - constexpr se_t(const type& raw_value, const se_raw_tag_t&) + constexpr se_t(const stype& raw_value, const se_raw_tag_t&) : m_data(raw_value) { } - constexpr type value() const + type value() const { - return m_data; + return storage::copy(reinterpret_cast(m_data)); } // Access underlying raw data (don't use) - constexpr const type& raw_data() const noexcept + constexpr const stype& raw_data() const noexcept { return m_data; } @@ -626,14 +652,14 @@ public: se_t& operator =(type value) { - return m_data = value, *this; + return m_data = reinterpret_cast(value), *this; } using simple_type = simple_t; - constexpr operator type() const + operator type() const { - return m_data; + return storage::copy(reinterpret_cast(m_data)); } template @@ -656,59 +682,59 @@ public: }; // se_t with native endianness (alias) -template using nse_t = se_t; +template using nse_t = se_t; -template -inline se_t& operator +=(se_t& left, const T1& right) +template +inline se_t& operator +=(se_t& left, const T1& right) { auto value = left.value(); return left = (value += right); } -template -inline se_t& operator -=(se_t& left, const T1& right) +template +inline se_t& operator -=(se_t& left, const T1& right) { auto value = left.value(); return left = (value -= right); } -template -inline se_t& operator *=(se_t& left, const T1& right) +template +inline se_t& operator *=(se_t& left, const T1& right) { auto value = left.value(); return left = (value *= right); } -template -inline se_t& operator /=(se_t& left, const T1& right) +template +inline se_t& operator /=(se_t& left, const T1& right) { auto value = left.value(); return left = (value /= right); } -template -inline se_t& operator %=(se_t& left, const T1& right) +template +inline se_t& operator %=(se_t& left, const T1& right) { auto value = left.value(); return left = (value %= right); } -template -inline se_t& operator <<=(se_t& left, const T1& right) +template +inline se_t& operator <<=(se_t& left, const T1& right) { auto value = left.value(); return left = (value <<= right); } -template -inline se_t& operator >>=(se_t& left, const T1& right) +template +inline se_t& operator >>=(se_t& left, const T1& right) { auto value = left.value(); return left = (value >>= right); } -template -inline se_t operator ++(se_t& left, int) +template +inline se_t operator ++(se_t& left, int) { auto value = left.value(); auto result = value++; @@ -716,8 +742,8 @@ inline se_t operator ++(se_t& left, int) return result; } -template -inline se_t operator --(se_t& left, int) +template +inline se_t operator --(se_t& left, int) { auto value = left.value(); auto result = value--; @@ -725,15 +751,15 @@ inline se_t operator --(se_t& left, int) return result; } -template -inline se_t& operator ++(se_t& right) +template +inline se_t& operator ++(se_t& right) { auto value = right.value(); return right = ++value; } -template -inline se_t& operator --(se_t& right) +template +inline se_t& operator --(se_t& right) { auto value = right.value(); return right = --value; @@ -852,16 +878,28 @@ inline std::enable_if_t::value && sizeof(T) >= 4, se_t using be_t = se_t; -template using le_t = se_t; +template using be_t = se_t; +template using le_t = se_t; #endif // Type converter: converts native endianness arithmetic/enum types to appropriate se_t<> type template struct to_se { + template + struct to_se_ + { + using type = T2; + }; + + template + struct to_se_::value || std::is_enum::value>> + { + using type = se_t; + }; + // Convert arithmetic and enum types - using type = typename std::conditional::value || std::is_enum::value, se_t, T>::type; + using type = typename to_se_::type; }; template struct to_se { using type = se_t; }; @@ -911,10 +949,10 @@ template using atomic_le_t = atomic_t>; #endif // Formatting for BE/LE data -template -struct unveil, void> +template +struct unveil, void> { - static inline auto get(const se_t& arg) + static inline auto get(const se_t& arg) { return unveil::get(arg); } diff --git a/Utilities/types.h b/Utilities/types.h index c822aba50a..ad61bce0e2 100644 --- a/Utilities/types.h +++ b/Utilities/types.h @@ -34,6 +34,12 @@ struct bijective_pair T2 v2; }; +template +struct se_storage; + +template +class se_t; + // Specialization with static constexpr bijective_pair map[] member expected template struct bijective; diff --git a/rpcs3/Emu/Cell/Modules/cellPamf.h b/rpcs3/Emu/Cell/Modules/cellPamf.h index 60d042e77e..8f80f5fd12 100644 --- a/rpcs3/Emu/Cell/Modules/cellPamf.h +++ b/rpcs3/Emu/Cell/Modules/cellPamf.h @@ -253,8 +253,6 @@ struct CellPamfLpcmInfo -#pragma pack(push, 1) // file data - struct PamfStreamHeader { u8 type; @@ -341,7 +339,7 @@ struct PamfStreamHeader }; }; -CHECK_SIZE(PamfStreamHeader, 48); +CHECK_SIZE_ALIGN(PamfStreamHeader, 48, 4); struct PamfHeader { @@ -349,25 +347,25 @@ struct PamfHeader u32 version; //"0041" (is it const?) be_t data_offset; //== 2048 >> 11, PAMF headers seem to be always 2048 bytes in size be_t data_size; //== ((fileSize - 2048) >> 11) - u64 reserved[8]; + u32 reserved[16]; be_t table_size; //== size of mapping-table u16 reserved1; be_t start_pts_high; - be_t start_pts_low; //Presentation Time Stamp (start) + be_t start_pts_low; //Presentation Time Stamp (start) be_t end_pts_high; - be_t end_pts_low; //Presentation Time Stamp (end) - be_t mux_rate_max; //== 0x01D470 (400 bps per unit, == 48000000 bps) - be_t mux_rate_min; //== 0x0107AC (?????) + be_t end_pts_low; //Presentation Time Stamp (end) + be_t mux_rate_max; //== 0x01D470 (400 bps per unit, == 48000000 bps) + be_t mux_rate_min; //== 0x0107AC (?????) u16 reserved2; // ????? u8 reserved3; u8 stream_count; //total stream count (reduced to 1 byte) be_t unk1; //== 1 (?????) - be_t table_data_size; //== table_size - 0x20 == 0x14 + (0x30 * total_stream_num) (?????) + be_t table_data_size; //== table_size - 0x20 == 0x14 + (0x30 * total_stream_num) (?????) //TODO: check relative offset of stream structs (could be from 0x0c to 0x14, currently 0x14) be_t start_pts_high2; //????? (probably same values) - be_t start_pts_low2; //????? + be_t start_pts_low2; //????? be_t end_pts_high2; //????? - be_t end_pts_low2; //????? + be_t end_pts_low2; //????? be_t unk2; //== 0x10000 (?????) be_t unk3; // ????? be_t unk4; // == stream_count @@ -375,6 +373,8 @@ struct PamfHeader PamfStreamHeader stream_headers[256]; }; +CHECK_SIZE_ALIGN(PamfHeader, 136 + sizeof(PamfHeader::stream_headers), 4); + struct PamfEpHeader { be_t value0; //mixed indexN (probably left 2 bits) and nThRefPictureOffset @@ -383,9 +383,7 @@ struct PamfEpHeader be_t rpnOffset; }; -CHECK_SIZE(PamfEpHeader, 12); - -#pragma pack(pop) +CHECK_SIZE_ALIGN(PamfEpHeader, 12, 4); // not directly accessed by virtual CPU, fields are unknown struct CellPamfReader diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.h b/rpcs3/Emu/Cell/lv2/sys_fs.h index ad044f23a3..d1f56d59a3 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.h +++ b/rpcs3/Emu/Cell/lv2/sys_fs.h @@ -7,8 +7,6 @@ namespace vm { using namespace ps3; } -#pragma pack(push, 4) - // Error Codes enum : s32 { @@ -136,20 +134,22 @@ struct CellFsStat be_t mode; be_t uid; be_t gid; - be_t atime; - be_t mtime; - be_t ctime; - be_t size; - be_t blksize; + be_t atime; + be_t mtime; + be_t ctime; + be_t size; + be_t blksize; }; +CHECK_SIZE_ALIGN(CellFsStat, 52, 4); + struct CellFsUtimbuf { - be_t actime; - be_t modtime; + be_t actime; + be_t modtime; }; -#pragma pack(pop) +CHECK_SIZE_ALIGN(CellFsUtimbuf, 16, 4); // Stream Support Status (st_status) enum : u32 diff --git a/rpcs3/Emu/Memory/vm_ptr.h b/rpcs3/Emu/Memory/vm_ptr.h index c2e96b46b5..3667d7a015 100644 --- a/rpcs3/Emu/Memory/vm_ptr.h +++ b/rpcs3/Emu/Memory/vm_ptr.h @@ -130,6 +130,18 @@ namespace vm return aligned(ALIGN_32(T)); } + // Get type size + static constexpr u32 size() + { + return SIZE_32(T); + } + + // Get type alignment + static constexpr u32 align() + { + return ALIGN_32(T); + } + // Test address for arbitrary alignment: (addr & (align - 1)) != 0 explicit_bool_t operator %(u32 align) const { @@ -266,9 +278,11 @@ namespace vm // Native endianness pointer to LE data template using ptrl = _ptr_base, AT>; + template using cptrl = ptrl; // Native endianness pointer to BE data template using ptrb = _ptr_base, AT>; + template using cptrb = ptrb; // BE pointer to LE data template using bptrl = _ptr_base, to_be_t>; @@ -286,24 +300,19 @@ namespace vm { // Default pointer type for PS3 HLE functions (Native endianness pointer to BE data) template using ptr = ptrb; + template using cptr = ptr; // Default pointer to pointer type for PS3 HLE functions (Native endianness pointer to BE pointer to BE data) template using pptr = ptr, AT>; + template using cpptr = pptr; // Default pointer type for PS3 HLE structures (BE pointer to BE data) template using bptr = bptrb; + template using bcptr = bptr; // Default pointer to pointer type for PS3 HLE structures (BE pointer to BE pointer to BE data) template using bpptr = bptr, AT>; - - // Native endianness pointer to const BE data - template using cptr = ptr; - - // BE pointer to const BE data - template using bcptr = bptr; - - template using cpptr = pptr; - template using bcpptr = bpptr; + template using bcpptr = bpptr; // Perform static_cast (for example, vm::ptr to vm::ptr) template*>(std::declval()))> @@ -324,23 +333,18 @@ namespace vm { // Default pointer type for PSV HLE functions (Native endianness pointer to LE data) template using ptr = ptrl; + template using cptr = ptr; // Default pointer to pointer type for PSV HLE functions (Native endianness pointer to LE pointer to LE data) template using pptr = ptr>; + template using cpptr = pptr; // Default pointer type for PSV HLE structures (LE pointer to LE data) template using lptr = lptrl; + template using lcptr = lptr; // Default pointer to pointer type for PSV HLE structures (LE pointer to LE pointer to LE data) template using lpptr = lptr>; - - // Native endianness pointer to const LE data - template using cptr = ptr; - - // LE pointer to const LE data - template using lcptr = lptr; - - template using cpptr = pptr; template using lcpptr = lpptr; // Perform static_cast (for example, vm::ptr to vm::ptr) diff --git a/rpcs3/Emu/Memory/vm_var.h b/rpcs3/Emu/Memory/vm_var.h index 24fa149396..7467919ae1 100644 --- a/rpcs3/Emu/Memory/vm_var.h +++ b/rpcs3/Emu/Memory/vm_var.h @@ -109,10 +109,10 @@ namespace vm template using var = varb; // Make BE variable initialized from value - template inline auto make_var(const T& value) + template + inline auto make_var(const T& value) { - varb var(value); - return var; + return varb(value); } // Global HLE variable @@ -128,10 +128,10 @@ namespace vm template using var = varl; // Make LE variable initialized from value - template inline auto make_var(const T& value) + template + inline auto make_var(const T& value) { - varl var(value); - return var; + return varl(value); } // Global HLE variable diff --git a/rpcs3/Loader/ELF.h b/rpcs3/Loader/ELF.h index cbe308c138..e46d21afb9 100644 --- a/rpcs3/Loader/ELF.h +++ b/rpcs3/Loader/ELF.h @@ -32,6 +32,12 @@ enum class elf_machine : u16 mips = 0x08, }; +template +using elf_be = be_t; + +template +using elf_le = le_t; + template class en_t, typename sz_t> struct elf_ehdr { @@ -341,7 +347,7 @@ public: } }; -using ppu_exec_object = elf_object; -using ppu_prx_object = elf_object; -using spu_exec_object = elf_object; -using arm_exec_object = elf_object; +using ppu_exec_object = elf_object; +using ppu_prx_object = elf_object; +using spu_exec_object = elf_object; +using arm_exec_object = elf_object;