diff options
Diffstat (limited to 'src/devices/cpu/drcbeut.h')
-rw-r--r-- | src/devices/cpu/drcbeut.h | 148 |
1 files changed, 101 insertions, 47 deletions
diff --git a/src/devices/cpu/drcbeut.h b/src/devices/cpu/drcbeut.h index 7317b0ba30b..88945913429 100644 --- a/src/devices/cpu/drcbeut.h +++ b/src/devices/cpu/drcbeut.h @@ -2,19 +2,26 @@ // copyright-holders:Aaron Giles /*************************************************************************** - drcbeut.h - Utility functions for dynamic recompiling backends. ***************************************************************************/ -#pragma once +#ifndef MAME_CPU_DRCBEUT_H +#define MAME_CPU_DRCBEUT_H -#ifndef __DRCBEUT_H__ -#define __DRCBEUT_H__ +#pragma once #include "drcuml.h" +#include "mfpresolve.h" + +#include <cassert> +#include <list> +#include <utility> +#include <vector> + + +namespace drc { //************************************************************************** // TYPE DEFINITIONS @@ -30,14 +37,14 @@ public: drc_hash_table(drc_cache &cache, uint32_t modes, uint8_t addrbits, uint8_t ignorebits); // getters - drccodeptr ***base() const { return m_base; } - uint8_t l1bits() const { return m_l1bits; } - uint8_t l2bits() const { return m_l2bits; } - uint8_t l1shift() const { return m_l1shift; } - uint8_t l2shift() const { return m_l2shift; } - offs_t l1mask() const { return m_l1mask; } - offs_t l2mask() const { return m_l2mask; } - bool is_mode_populated(uint32_t mode) const { return m_base[mode] != m_emptyl1; } + drccodeptr ***base() const noexcept { return m_base; } + uint8_t l1bits() const noexcept { return m_l1bits; } + uint8_t l2bits() const noexcept { return m_l2bits; } + uint8_t l1shift() const noexcept { return m_l1shift; } + uint8_t l2shift() const noexcept { return m_l2shift; } + offs_t l1mask() const noexcept { return m_l1mask; } + offs_t l2mask() const noexcept { return m_l2mask; } + bool is_mode_populated(uint32_t mode) const noexcept { return m_base[mode] != m_emptyl1; } // set up and configuration bool reset(); @@ -49,20 +56,20 @@ public: // code pointer access bool set_codeptr(uint32_t mode, uint32_t pc, drccodeptr code); - drccodeptr get_codeptr(uint32_t mode, uint32_t pc) { assert(mode < m_modes); return m_base[mode][(pc >> m_l1shift) & m_l1mask][(pc >> m_l2shift) & m_l2mask]; } - bool code_exists(uint32_t mode, uint32_t pc) { return get_codeptr(mode, pc) != m_nocodeptr; } + drccodeptr get_codeptr(uint32_t mode, uint32_t pc) const noexcept { assert(mode < m_modes); return m_base[mode][(pc >> m_l1shift) & m_l1mask][(pc >> m_l2shift) & m_l2mask]; } + bool code_exists(uint32_t mode, uint32_t pc) const noexcept { return get_codeptr(mode, pc) != m_nocodeptr; } private: // internal state drc_cache & m_cache; // cache where allocations come from - uint32_t m_modes; // number of modes supported + uint32_t m_modes; // number of modes supported drccodeptr m_nocodeptr; // pointer to code which will handle missing entries - uint8_t m_l1bits; // bits worth of entries in l1 hash tables - uint8_t m_l2bits; // bits worth of entries in l2 hash tables - uint8_t m_l1shift; // shift to apply to the PC to get the l1 hash entry - uint8_t m_l2shift; // shift to apply to the PC to get the l2 hash entry + uint8_t m_l1bits; // bits worth of entries in l1 hash tables + uint8_t m_l2bits; // bits worth of entries in l2 hash tables + uint8_t m_l1shift; // shift to apply to the PC to get the l1 hash entry + uint8_t m_l2shift; // shift to apply to the PC to get the l2 hash entry offs_t m_l1mask; // mask to apply after shifting offs_t m_l2mask; // mask to apply after shifting @@ -91,25 +98,20 @@ public: uint32_t get_value(drccodeptr codebase, uint32_t mapvar) const; uint32_t get_last_value(uint32_t mapvar); - // static accessors to be called directly by generated code - static uint32_t static_get_value(drc_map_variables &map, drccodeptr codebase, uint32_t mapvar); - private: - // internal state - drc_cache & m_cache; // pointer to the cache - uint64_t m_uniquevalue; // unique value used to find the table - uint32_t m_mapvalue[uml::MAPVAR_END - uml::MAPVAR_M0]; // array of current values - - // list of entries struct map_entry { - map_entry *next() const { return m_next; } - map_entry * m_next; // pointer to next map entry - drccodeptr m_codeptr; // pointer to the relevant code - uint32_t m_mapvar; // map variable id - uint32_t m_newval; // value of the variable starting at codeptr + drccodeptr codeptr; // pointer to the relevant code + uint32_t mapvar; // map variable id + uint32_t newval; // value of the variable starting at codeptr }; - simple_list<map_entry> m_entry_list; // list of entries + using map_entry_vector = std::vector<map_entry>; + + // internal state + drc_cache & m_cache; // pointer to the cache + uint64_t m_uniquevalue; // unique value used to find the table + uint32_t m_mapvalue[uml::MAPVAR_END - uml::MAPVAR_M0]; // array of current values + map_entry_vector m_entry_list; // list of entries }; @@ -136,31 +138,83 @@ public: private: struct label_entry { - label_entry *next() const { return m_next; } - label_entry * m_next; // pointer to next label - uml::code_label m_label; // the label specified - drccodeptr m_codeptr; // pointer to the relevant code + uml::code_label label; // the label specified + drccodeptr codeptr; // pointer to the relevant code }; + using label_entry_list = std::list<label_entry>; struct label_fixup { - label_fixup *next() const { return m_next; } - label_fixup * m_next; // pointer to the next oob - label_entry * m_label; // the label in question - drc_label_fixup_delegate m_callback; // callback + label_entry * label; // the label in question + drc_label_fixup_delegate callback; // callback }; + using label_fixup_list = std::list<label_fixup>; // internal helpers void reset(bool fatal_on_leftovers); - label_entry *find_or_allocate(uml::code_label label); + label_entry &find_or_allocate(uml::code_label label); void oob_callback(drccodeptr *codeptr, void *param1, void *param2); // internal state drc_cache & m_cache; // pointer to the cache - simple_list<label_entry> m_list; // head of the live list - simple_list<label_fixup> m_fixup_list; // list of pending oob fixups + label_entry_list m_list; // head of the live list + label_fixup_list m_fixup_list; // list of pending oob fixups drc_oob_delegate m_oob_callback_delegate; // pre-computed delegate + label_entry_list m_free_labels; + label_fixup_list m_free_fixups; }; -#endif /* __DRCBEUT_H__ */ +// ======================> resolved_member_function + +struct resolved_member_function +{ + uintptr_t obj = uintptr_t(nullptr); + uint8_t *func = nullptr; + + explicit operator bool() const noexcept + { + return bool(func); + } + + template <typename C, typename F> + void set(C &&instance, F &&mfp) noexcept + { + auto const [entrypoint, adjusted] = util::resolve_member_function(std::forward<F>(mfp), std::forward<C>(instance)); + obj = adjusted; + func = reinterpret_cast<uint8_t *>(entrypoint); + } +}; + + +// ======================> resolved_memory_accessors + +struct resolved_memory_accessors +{ + resolved_member_function read_byte; + resolved_member_function read_byte_masked; + resolved_member_function read_word; + resolved_member_function read_word_masked; + resolved_member_function read_dword; + resolved_member_function read_dword_masked; + resolved_member_function read_qword; + resolved_member_function read_qword_masked; + + resolved_member_function write_byte; + resolved_member_function write_byte_masked; + resolved_member_function write_word; + resolved_member_function write_word_masked; + resolved_member_function write_dword; + resolved_member_function write_dword_masked; + resolved_member_function write_qword; + resolved_member_function write_qword_masked; + + void set(address_space &space); +}; + +using resolved_memory_accessors_vector = std::vector<resolved_memory_accessors>; + +} // namespace drc + + +#endif // MAME_CPU_DRCBEUT_H |