Move endianness type into lib/util header

This commit is contained in:
AJR 2021-08-31 12:30:11 -04:00
parent d7e65e3f42
commit ccaa00b3ed
12 changed files with 137 additions and 103 deletions

View File

@ -61,6 +61,7 @@ project "utils"
MAME_DIR .. "src/lib/util/delegate.h",
MAME_DIR .. "src/lib/util/disasmintf.cpp",
MAME_DIR .. "src/lib/util/disasmintf.h",
MAME_DIR .. "src/lib/util/endianness.h",
MAME_DIR .. "src/lib/util/flac.cpp",
MAME_DIR .. "src/lib/util/flac.h",
MAME_DIR .. "src/lib/util/harddisk.cpp",

View File

@ -1057,7 +1057,7 @@ void mips1core_device_base::lwl(u32 const op)
offs_t const offset = SIMMVAL + m_r[RSREG];
load<u32, false>(offset, [this, op, offset](u32 temp)
{
unsigned const shift = ((offset & 3) ^ ENDIAN_VALUE_LE_BE(m_endianness, 3, 0)) << 3;
unsigned const shift = ((offset & 3) ^ (m_endianness == ENDIANNESS_LITTLE ? 3 : 0)) << 3;
m_r[RTREG] = (m_r[RTREG] & ~u32(0xffffffffU << shift)) | (temp << shift);
});
@ -1068,7 +1068,7 @@ void mips1core_device_base::lwr(u32 const op)
offs_t const offset = SIMMVAL + m_r[RSREG];
load<u32, false>(offset, [this, op, offset](u32 temp)
{
unsigned const shift = ((offset & 0x3) ^ ENDIAN_VALUE_LE_BE(m_endianness, 0, 3)) << 3;
unsigned const shift = ((offset & 0x3) ^ (m_endianness == ENDIANNESS_LITTLE ? 0 : 3)) << 3;
m_r[RTREG] = (m_r[RTREG] & ~u32(0xffffffffU >> shift)) | (temp >> shift);
});
@ -1077,7 +1077,7 @@ void mips1core_device_base::lwr(u32 const op)
void mips1core_device_base::swl(u32 const op)
{
offs_t const offset = SIMMVAL + m_r[RSREG];
unsigned const shift = ((offset & 3) ^ ENDIAN_VALUE_LE_BE(m_endianness, 3, 0)) << 3;
unsigned const shift = ((offset & 3) ^ (m_endianness == ENDIANNESS_LITTLE ? 3 : 0)) << 3;
store<u32, false>(offset, m_r[RTREG] >> shift, 0xffffffffU >> shift);
}
@ -1085,7 +1085,7 @@ void mips1core_device_base::swl(u32 const op)
void mips1core_device_base::swr(u32 const op)
{
offs_t const offset = SIMMVAL + m_r[RSREG];
unsigned const shift = ((offset & 3) ^ ENDIAN_VALUE_LE_BE(m_endianness, 0, 3)) << 3;
unsigned const shift = ((offset & 3) ^ (m_endianness == ENDIANNESS_LITTLE ? 0 : 3)) << 3;
store<u32, false>(offset, m_r[RTREG] << shift, 0xffffffffU << shift);
}

View File

@ -70,7 +70,7 @@ debug_view_memory_source::debug_view_memory_source(std::string &&name, memory_re
, m_blocklength(region.bytes())
, m_numblocks(1)
, m_blockstride(0)
, m_offsetxor(ENDIAN_VALUE_NE_NNE(region.endianness(), 0, region.bytewidth() - 1))
, m_offsetxor(region.endianness() == ENDIANNESS_NATIVE ? 0 : region.bytewidth() - 1)
, m_endianness(region.endianness())
, m_prefsize(std::min<u8>(region.bytewidth(), 8))
{

View File

@ -13,8 +13,6 @@
#include "emucore.h"
#include "osdcore.h"
const char *const endianness_names[2] = { "little", "big" };
emu_fatalerror::emu_fatalerror(util::format_argument_pack<std::ostream> const &args)
: emu_fatalerror(0, args)
{

View File

@ -37,6 +37,7 @@
#include "osdcomm.h"
#include "coretmpl.h"
#include "bitmap.h"
#include "endianness.h"
#include "strformat.h"
#include "vecstream.h"
@ -78,6 +79,21 @@ using util::bitswap;
using util::iabs;
using util::string_format;
using endianness_t = util::endianness;
using util::BYTE_XOR_BE;
using util::BYTE_XOR_LE;
using util::BYTE4_XOR_BE;
using util::BYTE4_XOR_LE;
using util::WORD_XOR_BE;
using util::WORD_XOR_LE;
using util::BYTE8_XOR_BE;
using util::BYTE8_XOR_LE;
using util::WORD2_XOR_BE;
using util::WORD2_XOR_LE;
using util::DWORD_XOR_BE;
using util::DWORD_XOR_LE;
// pen_t is used to represent pixel values in bitmaps
typedef u32 pen_t;
@ -150,21 +166,9 @@ union PAIR64
// COMMON CONSTANTS
//**************************************************************************
// constants for expression endianness
enum endianness_t
{
ENDIANNESS_LITTLE,
ENDIANNESS_BIG
};
extern const char *const endianness_names[2];
// declare native endianness to be one or the other
#ifdef LSB_FIRST
const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_LITTLE;
#else
const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_BIG;
#endif
constexpr endianness_t ENDIANNESS_LITTLE = util::endianness::little;
constexpr endianness_t ENDIANNESS_BIG = util::endianness::big;
constexpr endianness_t ENDIANNESS_NATIVE = util::endianness::native;
// M_PI is not part of the C/C++ standards and is not present on
@ -264,16 +268,6 @@ template <typename T> constexpr auto RADIAN_TO_DEGREE(T const &x) { return (180.
template <typename T> constexpr auto DEGREE_TO_RADIAN(T const &x) { return (M_PI / 180.0) * x; }
// endian-based value: first value is if 'endian' is little-endian, second is if 'endian' is big-endian
#define ENDIAN_VALUE_LE_BE(endian,leval,beval) (((endian) == ENDIANNESS_LITTLE) ? (leval) : (beval))
// endian-based value: first value is if native endianness is little-endian, second is if native is big-endian
#define NATIVE_ENDIAN_VALUE_LE_BE(leval,beval) ENDIAN_VALUE_LE_BE(ENDIANNESS_NATIVE, leval, beval)
// endian-based value: first value is if 'endian' matches native, second is if 'endian' doesn't match native
#define ENDIAN_VALUE_NE_NNE(endian,neval,nneval) (((endian) == ENDIANNESS_NATIVE) ? (neval) : (nneval))
//**************************************************************************
// EXCEPTION CLASSES
//**************************************************************************

View File

@ -1567,7 +1567,7 @@ public:
fatalerror("Requesting cache() with data width %d while the config says %d\n", 8 << Width, m_config.data_width());
if(Endian != m_config.endianness())
fatalerror("Requesting cache() with endianness %s while the config says %s\n",
endianness_names[Endian], endianness_names[m_config.endianness()]);
util::endian_to_string_view(Endian), util::endian_to_string_view(m_config.endianness()));
v.set(this, get_cache_info());
}
@ -1581,7 +1581,7 @@ public:
fatalerror("Requesting specific() with data width %d while the config says %d\n", 8 << Width, m_config.data_width());
if(Endian != m_config.endianness())
fatalerror("Requesting spefific() with endianness %s while the config says %s\n",
endianness_names[Endian], endianness_names[m_config.endianness()]);
util::endian_to_string_view(Endian), util::endian_to_string_view(m_config.endianness()));
v.set(this, get_specific_info());
}
@ -1966,33 +1966,6 @@ private:
#define ACCESSING_BITS_32_63 ((mem_mask & 0xffffffff00000000U) != 0)
// macros for accessing bytes and words within larger chunks
// read/write a byte to a 16-bit space
#define BYTE_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0))
#define BYTE_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,1))
// read/write a byte to a 32-bit space
#define BYTE4_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(3,0))
#define BYTE4_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,3))
// read/write a word to a 32-bit space
#define WORD_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(2,0))
#define WORD_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,2))
// read/write a byte to a 64-bit space
#define BYTE8_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(7,0))
#define BYTE8_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,7))
// read/write a word to a 64-bit space
#define WORD2_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(6,0))
#define WORD2_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,6))
// read/write a dword to a 64-bit space
#define DWORD_XOR_BE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(4,0))
#define DWORD_XOR_LE(a) ((a) ^ NATIVE_ENDIAN_VALUE_LE_BE(0,4))
// helpers for checking address alignment
#define WORD_ALIGNED(a) (((a) & 1) == 0)
#define DWORD_ALIGNED(a) (((a) & 3) == 0)

View File

@ -35,7 +35,7 @@ template<> u8 mask_to_ukey<u64>(u64 mask)
(mask & 0x00000000000000ff ? 0x01 : 0x00);
}
template<int Width, int AddrShift> memory_units_descriptor<Width, AddrShift>::memory_units_descriptor(u8 access_width, u8 access_endian, handler_entry *handler, offs_t addrstart, offs_t addrend, offs_t mask, typename emu::detail::handler_entry_size<Width>::uX unitmask, int cswidth) : m_handler(handler), m_access_width(access_width), m_access_endian(access_endian)
template<int Width, int AddrShift> memory_units_descriptor<Width, AddrShift>::memory_units_descriptor(u8 access_width, endianness_t access_endian, handler_entry *handler, offs_t addrstart, offs_t addrend, offs_t mask, typename emu::detail::handler_entry_size<Width>::uX unitmask, int cswidth) : m_handler(handler), m_access_width(access_width), m_access_endian(access_endian)
{
u32 bits_per_access = 8 << access_width;
constexpr u32 NATIVE_MASK = Width + AddrShift >= 0 ? make_bitmask<u32>(Width + AddrShift) : 0;

View File

@ -15,7 +15,7 @@ public:
u8 m_offset;
};
memory_units_descriptor(u8 access_width, u8 access_endian, handler_entry *handler, offs_t addrstart, offs_t addrend, offs_t mask, uX unitmask, int cswidth);
memory_units_descriptor(u8 access_width, endianness_t access_endian, handler_entry *handler, offs_t addrstart, offs_t addrend, offs_t mask, uX unitmask, int cswidth);
offs_t get_handler_start() const { return m_handler_start; }
offs_t get_handler_mask() const { return m_handler_mask; }
@ -24,7 +24,7 @@ public:
const std::vector<entry> &get_entries_for_key(u8 key) const { return m_entries_for_key.find(key)->second; }
u8 get_subunit_width() const { return m_access_width; }
u8 get_subunit_endian() const { return m_access_endian; }
endianness_t get_subunit_endian() const { return m_access_endian; }
void set_subunit_handler(handler_entry *handler) { m_handler = handler; }
handler_entry *get_subunit_handler() const { return m_handler; }
@ -35,7 +35,7 @@ private:
handler_entry *m_handler;
std::array<u8, 4> m_keymap;
u8 m_access_width;
u8 m_access_endian;
endianness_t m_access_endian;
void generate(u8 ukey, uX gumask, uX umask, u32 cswidth, u32 bits_per_access, u8 base_shift, s8 shift, u32 active_count);
};

View File

@ -52,34 +52,34 @@ void memory_array::set(void *base, u32 bytes, int membits, endianness_t endianne
m_bytes_per_entry = bpe;
// derive data
switch (bpe*1000 + membits*10 + endianness)
switch (bpe*1000 + membits*10 + (endianness == ENDIANNESS_LITTLE ? 0 : 1))
{
case 1*1000 + 8*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read8_from_8; m_write_entry = &memory_array::write8_to_8; break;
case 1*1000 + 8*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read8_from_8; m_write_entry = &memory_array::write8_to_8; break;
case 1*1000 + 16*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read8_from_16le; m_write_entry = &memory_array::write8_to_16le; break;
case 1*1000 + 16*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read8_from_16be; m_write_entry = &memory_array::write8_to_16be; break;
case 1*1000 + 32*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read8_from_32le; m_write_entry = &memory_array::write8_to_32le; break;
case 1*1000 + 32*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read8_from_32be; m_write_entry = &memory_array::write8_to_32be; break;
case 1*1000 + 64*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read8_from_64le; m_write_entry = &memory_array::write8_to_64le; break;
case 1*1000 + 64*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read8_from_64be; m_write_entry = &memory_array::write8_to_64be; break;
case 1*1000 + 8*10 + 0: m_read_entry = &memory_array::read8_from_8; m_write_entry = &memory_array::write8_to_8; break;
case 1*1000 + 8*10 + 1: m_read_entry = &memory_array::read8_from_8; m_write_entry = &memory_array::write8_to_8; break;
case 1*1000 + 16*10 + 0: m_read_entry = &memory_array::read8_from_16le; m_write_entry = &memory_array::write8_to_16le; break;
case 1*1000 + 16*10 + 1: m_read_entry = &memory_array::read8_from_16be; m_write_entry = &memory_array::write8_to_16be; break;
case 1*1000 + 32*10 + 0: m_read_entry = &memory_array::read8_from_32le; m_write_entry = &memory_array::write8_to_32le; break;
case 1*1000 + 32*10 + 1: m_read_entry = &memory_array::read8_from_32be; m_write_entry = &memory_array::write8_to_32be; break;
case 1*1000 + 64*10 + 0: m_read_entry = &memory_array::read8_from_64le; m_write_entry = &memory_array::write8_to_64le; break;
case 1*1000 + 64*10 + 1: m_read_entry = &memory_array::read8_from_64be; m_write_entry = &memory_array::write8_to_64be; break;
case 2*1000 + 8*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read16_from_8le; m_write_entry = &memory_array::write16_to_8le; break;
case 2*1000 + 8*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read16_from_8be; m_write_entry = &memory_array::write16_to_8be; break;
case 2*1000 + 16*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read16_from_16; m_write_entry = &memory_array::write16_to_16; break;
case 2*1000 + 16*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read16_from_16; m_write_entry = &memory_array::write16_to_16; break;
case 2*1000 + 32*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read16_from_32le; m_write_entry = &memory_array::write16_to_32le; break;
case 2*1000 + 32*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read16_from_32be; m_write_entry = &memory_array::write16_to_32be; break;
case 2*1000 + 64*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read16_from_64le; m_write_entry = &memory_array::write16_to_64le; break;
case 2*1000 + 64*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read16_from_64be; m_write_entry = &memory_array::write16_to_64be; break;
case 2*1000 + 8*10 + 0: m_read_entry = &memory_array::read16_from_8le; m_write_entry = &memory_array::write16_to_8le; break;
case 2*1000 + 8*10 + 1: m_read_entry = &memory_array::read16_from_8be; m_write_entry = &memory_array::write16_to_8be; break;
case 2*1000 + 16*10 + 0: m_read_entry = &memory_array::read16_from_16; m_write_entry = &memory_array::write16_to_16; break;
case 2*1000 + 16*10 + 1: m_read_entry = &memory_array::read16_from_16; m_write_entry = &memory_array::write16_to_16; break;
case 2*1000 + 32*10 + 0: m_read_entry = &memory_array::read16_from_32le; m_write_entry = &memory_array::write16_to_32le; break;
case 2*1000 + 32*10 + 1: m_read_entry = &memory_array::read16_from_32be; m_write_entry = &memory_array::write16_to_32be; break;
case 2*1000 + 64*10 + 0: m_read_entry = &memory_array::read16_from_64le; m_write_entry = &memory_array::write16_to_64le; break;
case 2*1000 + 64*10 + 1: m_read_entry = &memory_array::read16_from_64be; m_write_entry = &memory_array::write16_to_64be; break;
case 4*1000 + 8*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read32_from_8le; m_write_entry = &memory_array::write32_to_8le; break;
case 4*1000 + 8*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read32_from_8be; m_write_entry = &memory_array::write32_to_8be; break;
case 4*1000 + 16*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read32_from_16le; m_write_entry = &memory_array::write32_to_16le; break;
case 4*1000 + 16*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read32_from_16be; m_write_entry = &memory_array::write32_to_16be; break;
case 4*1000 + 32*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read32_from_32; m_write_entry = &memory_array::write32_to_32; break;
case 4*1000 + 32*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read32_from_32; m_write_entry = &memory_array::write32_to_32; break;
case 4*1000 + 64*10 + ENDIANNESS_LITTLE: m_read_entry = &memory_array::read32_from_64le; m_write_entry = &memory_array::write32_to_64le; break;
case 4*1000 + 64*10 + ENDIANNESS_BIG: m_read_entry = &memory_array::read32_from_64be; m_write_entry = &memory_array::write32_to_64be; break;
case 4*1000 + 8*10 + 0: m_read_entry = &memory_array::read32_from_8le; m_write_entry = &memory_array::write32_to_8le; break;
case 4*1000 + 8*10 + 1: m_read_entry = &memory_array::read32_from_8be; m_write_entry = &memory_array::write32_to_8be; break;
case 4*1000 + 16*10 + 0: m_read_entry = &memory_array::read32_from_16le; m_write_entry = &memory_array::write32_to_16le; break;
case 4*1000 + 16*10 + 1: m_read_entry = &memory_array::read32_from_16be; m_write_entry = &memory_array::write32_to_16be; break;
case 4*1000 + 32*10 + 0: m_read_entry = &memory_array::read32_from_32; m_write_entry = &memory_array::write32_to_32; break;
case 4*1000 + 32*10 + 1: m_read_entry = &memory_array::read32_from_32; m_write_entry = &memory_array::write32_to_32; break;
case 4*1000 + 64*10 + 0: m_read_entry = &memory_array::read32_from_64le; m_write_entry = &memory_array::write32_to_64le; break;
case 4*1000 + 64*10 + 1: m_read_entry = &memory_array::read32_from_64be; m_write_entry = &memory_array::write32_to_64be; break;
default: throw emu_fatalerror("Illegal memory bits/bus width combo in memory_array");
}

View File

@ -179,17 +179,7 @@ int sol_lua_push(sol::types<map_handler_type>, lua_State *L, map_handler_type &&
int sol_lua_push(sol::types<endianness_t>, lua_State *L, endianness_t &&value)
{
char const *endianness = "unknown";
switch (value)
{
case endianness_t::ENDIANNESS_BIG:
endianness = "big";
break;
case endianness_t::ENDIANNESS_LITTLE:
endianness = "little";
break;
}
return sol::stack::push(L, endianness);
return sol::stack::push(L, util::endian_to_string_view(value));
}

76
src/lib/util/endianness.h Normal file
View File

@ -0,0 +1,76 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
endianness.h
Endianness types and utility functions.
***************************************************************************/
#ifndef MAME_LIB_UTIL_ENDIANNESS_H
#define MAME_LIB_UTIL_ENDIANNESS_H
#pragma once
#include <string_view>
namespace util {
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// constants for expression endianness
enum class endianness
{
little,
big,
#ifdef LSB_FIRST
native = little
#else
native = big
#endif
};
//**************************************************************************
// MACROS AND INLINE FUNCTIONS
//**************************************************************************
constexpr std::string_view endian_to_string_view(endianness e) { return e == endianness::little ? "little" : "big"; }
// endian-based value: first value is if native endianness is little-endian, second is if native is big-endian
#define NATIVE_ENDIAN_VALUE_LE_BE(leval,beval) ((util::endianness::native == util::endianness::little) ? (leval) : (beval))
// inline functions for accessing bytes and words within larger chunks
// read/write a byte to a 16-bit space
template <typename T> constexpr T BYTE_XOR_BE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0); }
template <typename T> constexpr T BYTE_XOR_LE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(0,1); }
// read/write a byte to a 32-bit space
template <typename T> constexpr T BYTE4_XOR_BE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(3,0); }
template <typename T> constexpr T BYTE4_XOR_LE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(0,3); }
// read/write a word to a 32-bit space
template <typename T> constexpr T WORD_XOR_BE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(2,0); }
template <typename T> constexpr T WORD_XOR_LE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(0,2); }
// read/write a byte to a 64-bit space
template <typename T> constexpr T BYTE8_XOR_BE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(7,0); }
template <typename T> constexpr T BYTE8_XOR_LE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(0,7); }
// read/write a word to a 64-bit space
template <typename T> constexpr T WORD2_XOR_BE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(6,0); }
template <typename T> constexpr T WORD2_XOR_LE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(0,6); }
// read/write a dword to a 64-bit space
template <typename T> constexpr T DWORD_XOR_BE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(4,0); }
template <typename T> constexpr T DWORD_XOR_LE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(0,4); }
} // namespace util
#endif // MAME_LIB_UTIL_ENDIANNESS_H

View File

@ -197,6 +197,7 @@ using util::BIT;
#include "corefile.h"
#include "corestr.h"
#include "eminline.h"
#include "endianness.h"
#include <algorithm>
#include <cctype>
@ -334,12 +335,13 @@ struct nec_unidasm_t : nec_disassembler::config
} nec_unidasm;
enum endianness { le, be };
static constexpr auto le = util::endianness::little;
static constexpr auto be = util::endianness::big;
struct dasm_table_entry
{
const char * name;
endianness endian;
util::endianness endian;
int8_t pcshift;
std::function<util::disasm_interface *()> alloc;
};