diff options
-rw-r--r-- | src/devices/bus/hp_dio/hp_dio.cpp | 2 | ||||
-rw-r--r-- | src/devices/bus/hp_dio/hp_dio.h | 3 | ||||
-rw-r--r-- | src/devices/cpu/drcbearm64.cpp | 4 | ||||
-rw-r--r-- | src/devices/cpu/drcbeut.cpp | 196 | ||||
-rw-r--r-- | src/devices/cpu/drcbeut.h | 45 | ||||
-rw-r--r-- | src/devices/cpu/drcbex64.cpp | 14 |
6 files changed, 128 insertions, 136 deletions
diff --git a/src/devices/bus/hp_dio/hp_dio.cpp b/src/devices/bus/hp_dio/hp_dio.cpp index 1b6ca8aab75..3675180350f 100644 --- a/src/devices/bus/hp_dio/hp_dio.cpp +++ b/src/devices/bus/hp_dio/hp_dio.cpp @@ -295,7 +295,7 @@ void device_dio16_card_interface::set_bus(dio16_device &bus) device_dio16_card_interface::device_dio16_card_interface(const machine_config &mconfig, device_t &device) : device_interface(device, "hpdio"), - m_dio_dev(nullptr), m_next(nullptr) + m_dio_dev(nullptr) { } diff --git a/src/devices/bus/hp_dio/hp_dio.h b/src/devices/bus/hp_dio/hp_dio.h index 700f911add0..7cc29f84ce7 100644 --- a/src/devices/bus/hp_dio/hp_dio.h +++ b/src/devices/bus/hp_dio/hp_dio.h @@ -164,12 +164,10 @@ protected: class device_dio16_card_interface : public device_interface { friend class dio16_device; - template <class ElementType> friend class simple_list; public: // construction/destruction virtual ~device_dio16_card_interface(); - device_dio16_card_interface *next() const { return m_next; } // inline configuration void set_diobus(dio16_device &dio_device) { m_dio_dev = &dio_device; @@ -221,7 +219,6 @@ protected: private: void set_bus(dio16_device & bus); - device_dio16_card_interface *m_next; unsigned int m_index; }; diff --git a/src/devices/cpu/drcbearm64.cpp b/src/devices/cpu/drcbearm64.cpp index 6281f2fb0cf..a49745e9533 100644 --- a/src/devices/cpu/drcbearm64.cpp +++ b/src/devices/cpu/drcbearm64.cpp @@ -1655,10 +1655,10 @@ void drcbe_arm64::op_recover(a64::Assembler &a, const uml::instruction &inst) be_parameter dstp(*this, inst.param(0), PTYPE_MR); - get_imm_relative(a, REG_PARAM1, m_drcmap_get_value.obj); a.ldr(REG_PARAM2, arm::Mem(a64::x29, -8)); // saved LR (x30) from first level CALLH/EXH or failed hash jump - a.sub(REG_PARAM2, REG_PARAM2, 4); + get_imm_relative(a, REG_PARAM1, m_drcmap_get_value.obj); a.mov(REG_PARAM3, inst.param(1).mapvar()); + a.sub(REG_PARAM2, REG_PARAM2, 4); call_arm_addr(a, m_drcmap_get_value.func); diff --git a/src/devices/cpu/drcbeut.cpp b/src/devices/cpu/drcbeut.cpp index fa22d799cab..23526e1a8aa 100644 --- a/src/devices/cpu/drcbeut.cpp +++ b/src/devices/cpu/drcbeut.cpp @@ -2,8 +2,6 @@ // copyright-holders:Aaron Giles /*************************************************************************** - drcbeut.c - Utility functions for dynamic recompiling backends. ***************************************************************************/ @@ -11,6 +9,9 @@ #include "emu.h" #include "drcbeut.h" +#include <algorithm> + + namespace drc { using namespace uml; @@ -199,11 +200,11 @@ bool drc_hash_table::set_codeptr(uint32_t mode, uint32_t pc, drccodeptr code) // drc_map_variables - constructor //------------------------------------------------- -drc_map_variables::drc_map_variables(drc_cache &cache, uint64_t uniquevalue) - : m_cache(cache), - m_uniquevalue(uniquevalue) +drc_map_variables::drc_map_variables(drc_cache &cache, uint64_t uniquevalue) : + m_cache(cache), + m_uniquevalue(uniquevalue) { - memset(m_mapvalue, 0, sizeof(m_mapvalue)); + std::fill(std::begin(m_mapvalue), std::end(m_mapvalue), 0); } @@ -213,9 +214,6 @@ drc_map_variables::drc_map_variables(drc_cache &cache, uint64_t uniquevalue) drc_map_variables::~drc_map_variables() { - // must detach all items from the entry list so that the list object - // doesn't try to free them on exit - m_entry_list.detach_all(); } @@ -226,12 +224,11 @@ drc_map_variables::~drc_map_variables() void drc_map_variables::block_begin(drcuml_block &block) { // release any remaining live entries - map_entry *entry; - while ((entry = m_entry_list.detach_head()) != nullptr) - m_cache.dealloc(entry, sizeof(*entry)); + m_entry_list.clear(); + m_entry_list.reserve(128); // reset the variable values - memset(m_mapvalue, 0, sizeof(m_mapvalue)); + std::fill(std::begin(m_mapvalue), std::end(m_mapvalue), 0); } @@ -242,71 +239,80 @@ void drc_map_variables::block_begin(drcuml_block &block) void drc_map_variables::block_end(drcuml_block &block) { // only process if we have data - if (m_entry_list.first() == nullptr) + if (m_entry_list.empty()) return; // begin "code generation" aligned to an 8-byte boundary - drccodeptr *top = m_cache.begin_codegen(sizeof(uint64_t) + sizeof(uint32_t) + 2 * sizeof(uint32_t) * m_entry_list.count()); - if (top == nullptr) + drccodeptr *top = m_cache.begin_codegen(sizeof(uint64_t) + sizeof(uint32_t) + 2 * sizeof(uint32_t) * m_entry_list.size()); + if (!top) block.abort(); - uint32_t *dest = (uint32_t *)(((uintptr_t)*top + 7) & ~7); + auto dest = reinterpret_cast<uint32_t *>((uintptr_t(*top) + 7) & ~uintptr_t(7)); // store the cookie first *(uint64_t *)dest = m_uniquevalue; dest += 2; // get the pointer to the first item and store an initial backwards offset - drccodeptr lastptr = m_entry_list.first()->m_codeptr; - *dest = (drccodeptr)dest - lastptr; + drccodeptr lastptr = m_entry_list.front().codeptr; + *dest = drccodeptr(dest) - lastptr; dest++; // now iterate over entries and store them - uint32_t curvalue[MAPVAR_COUNT] = { 0 }; - bool changed[MAPVAR_COUNT] = { false }; - for (map_entry *entry = m_entry_list.first(); entry != nullptr; entry = entry->next()) + std::array<uint32_t, MAPVAR_COUNT> curvalue; + std::array<bool, MAPVAR_COUNT> changed; + std::fill(curvalue.begin(), curvalue.end(), 0); + std::fill(changed.begin(), changed.end(), false); + auto entry = m_entry_list.begin(); + while (m_entry_list.end() != entry) { // update the current value of the variable and detect changes - if (curvalue[entry->m_mapvar] != entry->m_newval) + if (curvalue[entry->mapvar] != entry->newval) { - curvalue[entry->m_mapvar] = entry->m_newval; - changed[entry->m_mapvar] = true; + curvalue[entry->mapvar] = entry->newval; + changed[entry->mapvar] = true; } // if the next code pointer is different, or if we're at the end, flush changes - if (entry->next() == nullptr || entry->next()->m_codeptr != entry->m_codeptr) + auto const next = std::next(entry); + if ((m_entry_list.end() == next) || (next->codeptr != entry->codeptr)) { // build a mask of changed variables int numchanged = 0; uint32_t varmask = 0; for (int varnum = 0; varnum < std::size(changed); varnum++) + { if (changed[varnum]) { changed[varnum] = false; varmask |= 1 << varnum; numchanged++; } + } // if nothing really changed, skip it - if (numchanged == 0) - continue; - - // first word is a code delta plus mask of changed variables - uint32_t codedelta = entry->m_codeptr - lastptr; - while (codedelta > 0xffff) + if (numchanged) { - *dest++ = 0xffff << 16; - codedelta -= 0xffff; - } - *dest++ = (codedelta << 16) | (varmask << 4) | numchanged; + // first word is a code delta plus mask of changed variables + uint32_t codedelta = entry->codeptr - lastptr; + while (codedelta > 0xffff) + { + *dest++ = uint32_t(0xffff) << 16; + codedelta -= 0xffff; + } + *dest++ = (codedelta << 16) | (varmask << 4) | numchanged; - // now output updated variable values - for (int varnum = 0; varnum < std::size(changed); varnum++) - if ((varmask >> varnum) & 1) - *dest++ = curvalue[varnum]; + // now output updated variable values + for (int varnum = 0; varnum < changed.size(); varnum++) + { + if (BIT(varmask, varnum)) + *dest++ = curvalue[varnum]; + } - // remember our lastptr - lastptr = entry->m_codeptr; + // remember our lastptr + lastptr = entry->codeptr; + } } + entry = next; } // add a terminator @@ -325,21 +331,17 @@ void drc_map_variables::block_end(drcuml_block &block) void drc_map_variables::set_value(drccodeptr codebase, uint32_t mapvar, uint32_t newvalue) { - assert(mapvar >= MAPVAR_M0 && mapvar < MAPVAR_END); + assert((mapvar >= MAPVAR_M0) && (mapvar < MAPVAR_END)); // if this value isn't different, skip it if (m_mapvalue[mapvar - MAPVAR_M0] == newvalue) return; // allocate a new entry and fill it in - map_entry *entry = (map_entry *)m_cache.alloc(sizeof(*entry)); - entry->m_next = nullptr; - entry->m_codeptr = codebase; - entry->m_mapvar = mapvar - MAPVAR_M0; - entry->m_newval = newvalue; - - // hook us into the end of the list - m_entry_list.append(*entry); + auto &entry = m_entry_list.emplace_back(); + entry.codeptr = codebase; + entry.mapvar = mapvar - MAPVAR_M0; + entry.newval = newvalue; // update our state in the table as well m_mapvalue[mapvar - MAPVAR_M0] = newvalue; @@ -353,27 +355,27 @@ void drc_map_variables::set_value(drccodeptr codebase, uint32_t mapvar, uint32_t uint32_t drc_map_variables::get_value(drccodeptr codebase, uint32_t mapvar) const { - assert(mapvar >= MAPVAR_M0 && mapvar < MAPVAR_END); + assert((mapvar >= MAPVAR_M0) && (mapvar < MAPVAR_END)); mapvar -= MAPVAR_M0; // get an aligned pointer to start scanning - uint64_t *curscan = (uint64_t *)(((uintptr_t)codebase | 7) + 1); - uint64_t *endscan = (uint64_t *)m_cache.top(); + auto curscan = reinterpret_cast<uint64_t const *>((uintptr_t(codebase) | 7) + 1); + auto const endscan = reinterpret_cast<uint64_t const *>(m_cache.top()); // look for the signature - while (curscan < endscan && *curscan++ != m_uniquevalue) {}; + while ((curscan < endscan) && (*curscan++ != m_uniquevalue)) { } if (curscan >= endscan) return 0; // switch to 32-bit pointers for processing the rest - uint32_t *data = (uint32_t *)curscan; + auto data = reinterpret_cast<uint32_t const *>(curscan); // first get the 32-bit starting offset to the code drccodeptr curcode = (drccodeptr)data - *data; data++; // now loop until we advance past our target - uint32_t varmask = 0x10 << mapvar; + uint32_t const varmask = 0x10 << mapvar; uint32_t result = 0; while (true) { @@ -388,7 +390,7 @@ uint32_t drc_map_variables::get_value(drccodeptr codebase, uint32_t mapvar) cons break; // if our mapvar has changed, process this word - if ((controlword & varmask) != 0) + if (controlword & varmask) { // count how many words precede the one we care about int dataoffs = 0; @@ -430,9 +432,9 @@ uint32_t drc_map_variables::get_last_value(uint32_t mapvar) // drc_label_list - constructor //------------------------------------------------- -drc_label_list::drc_label_list(drc_cache &cache) - : m_cache(cache), - m_oob_callback_delegate(&drc_label_list::oob_callback, this) +drc_label_list::drc_label_list(drc_cache &cache) : + m_cache(cache), + m_oob_callback_delegate(&drc_label_list::oob_callback, this) { } @@ -443,9 +445,6 @@ drc_label_list::drc_label_list(drc_cache &cache) drc_label_list::~drc_label_list() { - // must detach all items from the entry list so that the list object - // doesn't try to free them on exit - m_list.detach_all(); } @@ -470,12 +469,7 @@ void drc_label_list::block_end(drcuml_block &block) assert(!m_cache.generating_code()); // free all of the pending fixup requests - label_fixup *fixup; - while ((fixup = m_fixup_list.detach_head()) != nullptr) - { - fixup->~label_fixup(); - m_cache.dealloc(fixup, sizeof(*fixup)); - } + m_free_fixups.splice(m_free_fixups.begin(), m_fixup_list); // make sure the label list is clear, and fatalerror if we missed anything reset(true); @@ -490,18 +484,22 @@ void drc_label_list::block_end(drcuml_block &block) drccodeptr drc_label_list::get_codeptr(uml::code_label label, drc_label_fixup_delegate const &callback, void *param) { - label_entry *const curlabel = find_or_allocate(label); + label_entry &curlabel = find_or_allocate(label); // if no code pointer, request an OOB callback - if (!curlabel->m_codeptr && !callback.isnull()) + if (!curlabel.codeptr && !callback.isnull()) { - label_fixup *fixup = reinterpret_cast<label_fixup *>(m_cache.alloc(sizeof(*fixup))); - new (fixup) label_fixup{ nullptr, curlabel, callback }; - m_fixup_list.append(*fixup); - m_cache.request_oob_codegen(drc_oob_delegate(m_oob_callback_delegate), fixup, param); + label_fixup_list::iterator fixup = m_free_fixups.begin(); + if (m_free_fixups.end() == fixup) + fixup = m_fixup_list.emplace(m_fixup_list.end()); + else + m_fixup_list.splice(m_fixup_list.end(), m_free_fixups, fixup); + fixup->label = &curlabel; + fixup->callback = callback; + m_cache.request_oob_codegen(drc_oob_delegate(m_oob_callback_delegate), &*fixup, param); } - return curlabel->m_codeptr; + return curlabel.codeptr; } @@ -512,9 +510,9 @@ drccodeptr drc_label_list::get_codeptr(uml::code_label label, drc_label_fixup_de void drc_label_list::set_codeptr(uml::code_label label, drccodeptr codeptr) { // set the code pointer - label_entry *curlabel = find_or_allocate(label); - assert(curlabel->m_codeptr == nullptr); - curlabel->m_codeptr = codeptr; + label_entry &curlabel = find_or_allocate(label); + assert(!curlabel.codeptr); + curlabel.codeptr = codeptr; } @@ -526,15 +524,14 @@ void drc_label_list::set_codeptr(uml::code_label label, drccodeptr codeptr) void drc_label_list::reset(bool fatal_on_leftovers) { // loop until out of labels - label_entry *curlabel; - while ((curlabel = m_list.detach_head()) != nullptr) + while (!m_list.empty()) { // fatal if we were a leftover - if (fatal_on_leftovers && curlabel->m_codeptr == nullptr) - fatalerror("Label %08X never defined!\n", curlabel->m_label.label()); + if (fatal_on_leftovers && !m_list.front().codeptr) + throw emu_fatalerror("Label %08X never defined!\n", m_list.front().label.label()); // free the label - m_cache.dealloc(curlabel, sizeof(*curlabel)); + m_free_labels.splice(m_free_labels.begin(), m_list, m_list.begin()); } } @@ -544,23 +541,24 @@ void drc_label_list::reset(bool fatal_on_leftovers) // allocate a new one if not found //------------------------------------------------- -drc_label_list::label_entry *drc_label_list::find_or_allocate(uml::code_label label) +drc_label_list::label_entry &drc_label_list::find_or_allocate(uml::code_label label) { // find the label, or else allocate a new one - label_entry *curlabel; - for (curlabel = m_list.first(); curlabel != nullptr; curlabel = curlabel->next()) - if (curlabel->m_label == label) - break; - - // if none found, allocate - if (curlabel == nullptr) + for (auto curlabel = m_list.begin(); m_list.end() != curlabel; ++curlabel) { - curlabel = (label_entry *)m_cache.alloc(sizeof(*curlabel)); - curlabel->m_label = label; - curlabel->m_codeptr = nullptr; - m_list.append(*curlabel); + if (curlabel->label == label) + return *curlabel; } - return curlabel; + + // if none found, allocate + auto newlabel = m_free_labels.begin(); + if (m_free_labels.end() == newlabel) + newlabel = m_list.emplace(m_list.end()); + else + m_list.splice(m_list.end(), m_free_labels, newlabel); + newlabel->label = label; + newlabel->codeptr = nullptr; + return *newlabel; } @@ -572,7 +570,7 @@ drc_label_list::label_entry *drc_label_list::find_or_allocate(uml::code_label la void drc_label_list::oob_callback(drccodeptr *codeptr, void *param1, void *param2) { label_fixup *fixup = reinterpret_cast<label_fixup *>(param1); - fixup->m_callback(param2, fixup->m_label->m_codeptr); + fixup->callback(param2, fixup->label->codeptr); } diff --git a/src/devices/cpu/drcbeut.h b/src/devices/cpu/drcbeut.h index 05a4a78fdc2..5a8c309e7b8 100644 --- a/src/devices/cpu/drcbeut.h +++ b/src/devices/cpu/drcbeut.h @@ -2,8 +2,6 @@ // copyright-holders:Aaron Giles /*************************************************************************** - drcbeut.h - Utility functions for dynamic recompiling backends. ***************************************************************************/ @@ -17,6 +15,7 @@ #include "mfpresolve.h" +#include <list> #include <utility> #include <vector> @@ -99,21 +98,19 @@ public: uint32_t get_last_value(uint32_t mapvar); private: + struct map_entry + { + drccodeptr codeptr; // pointer to the relevant code + uint32_t mapvar; // map variable id + uint32_t newval; // value of the variable starting at codeptr + }; + 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 - - // 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 - }; - simple_list<map_entry> m_entry_list; // list of entries + map_entry_vector m_entry_list; // list of entries }; @@ -140,30 +137,30 @@ 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; }; diff --git a/src/devices/cpu/drcbex64.cpp b/src/devices/cpu/drcbex64.cpp index 7a99a5709ee..1d2033f2977 100644 --- a/src/devices/cpu/drcbex64.cpp +++ b/src/devices/cpu/drcbex64.cpp @@ -1887,13 +1887,13 @@ void drcbe_x64::op_recover(Assembler &a, const instruction &inst) be_parameter dstp(*this, inst.param(0), PTYPE_MR); // call the recovery code - a.mov(rax, MABS(&m_near.stacksave)); // mov rax,stacksave - a.mov(rax, ptr(rax, -8)); // mov rax,[rax-8] - mov_r64_imm(a, Gpq(REG_PARAM1), m_drcmap_get_value.obj); // mov param1,m_map - a.lea(Gpq(REG_PARAM2), ptr(rax, -1)); // lea param2,[rax-1] - mov_r64_imm(a, Gpq(REG_PARAM3), inst.param(1).mapvar()); // mov param3,param[1].value - smart_call_r64(a, m_drcmap_get_value.func, rax); // call drcmap_get_value - mov_param_reg(a, dstp, eax); // mov dstp,eax + a.mov(rax, MABS(&m_near.stacksave)); + mov_r64_imm(a, Gpq(REG_PARAM1), m_drcmap_get_value.obj); + mov_r64_imm(a, Gpq(REG_PARAM3), inst.param(1).mapvar()); + a.mov(Gpq(REG_PARAM2), ptr(rax, -8)); + a.sub(Gpq(REG_PARAM2), 1); + smart_call_r64(a, m_drcmap_get_value.func, rax); + mov_param_reg(a, dstp, eax); } |