diff options
Diffstat (limited to 'trunk/src/emu/cpu/drcuml.h')
-rw-r--r-- | trunk/src/emu/cpu/drcuml.h | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/drcuml.h b/trunk/src/emu/cpu/drcuml.h new file mode 100644 index 00000000000..6cb0cab285a --- /dev/null +++ b/trunk/src/emu/cpu/drcuml.h @@ -0,0 +1,268 @@ +/*************************************************************************** + + drcuml.h + + Universal machine language for dynamic recompiling CPU cores. + +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +***************************************************************************/ + +#pragma once + +#ifndef __DRCUML_H__ +#define __DRCUML_H__ + +#include "drccache.h" +#include "uml.h" + + +//************************************************************************** +// CONSTANTS +//************************************************************************** + +// these options are passed into drcuml_alloc() and control global behaviors +const UINT32 DRCUML_OPTION_USE_C = 0x0001; // always use the C back-end +const UINT32 DRCUML_OPTION_LOG_UML = 0x0002; // generate a UML disassembly of each block +const UINT32 DRCUML_OPTION_LOG_NATIVE = 0x0004; // tell the back-end to generate a native disassembly of each block + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// determine the type of the native DRC, falling back to C +#ifndef NATIVE_DRC +class drcbe_c; +typedef drcbe_c drcbe_native; +#else +class NATIVE_DRC; +typedef NATIVE_DRC drcbe_native; +#endif + + +// opaque structure describing UML generation state +class drcuml_state; + + +// an integer register, with low/high parts +union drcuml_ireg +{ +#ifdef LSB_FIRST + struct { UINT32 l,h; } w; // 32-bit low, high parts of the register +#else + struct { UINT32 h,l; } w; // 32-bit low, high parts of the register +#endif + UINT64 d; // 64-bit full register +}; + + +// a floating-point register, with low/high parts +union drcuml_freg +{ +#ifdef LSB_FIRST + struct { float l,h; } s; // 32-bit low, high parts of the register +#else + struct { float h,l; } s; // 32-bit low, high parts of the register +#endif + double d; // 64-bit full register +}; + + +// the collected machine state of a system +struct drcuml_machine_state +{ + drcuml_ireg r[uml::REG_I_COUNT]; // integer registers + drcuml_freg f[uml::REG_F_COUNT]; // floating-point registers + UINT32 exp; // exception parameter register + UINT8 fmod; // fmod (floating-point mode) register + UINT8 flags; // flags state +}; + + +// hints and information about the back-end +struct drcbe_info +{ + UINT8 direct_iregs; // number of direct-mapped integer registers + UINT8 direct_fregs; // number of direct-mapped floating point registers +}; + + +// a drcuml_block describes a basic block of instructions +class drcuml_block +{ + friend class simple_list<drcuml_block>; + +public: + // construction/destruction + drcuml_block(drcuml_state &drcuml, UINT32 maxinst); + ~drcuml_block(); + + // getters + drcuml_block *next() const { return m_next; } + bool inuse() const { return m_inuse; } + UINT32 maxinst() const { return m_maxinst; } + + // code generation + void begin(); + void end(); + void abort(); + + // instruction appending + uml::instruction &append(); + void append_comment(const char *format, ...); + + // this class is thrown if abort() is called + class abort_compilation : public emu_exception + { + friend class drcuml_block; + abort_compilation() { } + }; + +private: + // internal helpers + void optimize(); + void disassemble(); + const char *get_comment_text(const uml::instruction &inst, astring &comment); + + // internal state + drcuml_state & m_drcuml; // pointer back to the owning UML + drcuml_block * m_next; // pointer to next block + UINT32 m_nextinst; // next instruction to fill in the cache + UINT32 m_maxinst; // maximum number of instructions + uml::instruction * m_inst; // pointer to the instruction list + bool m_inuse; // this block is in use +}; + + +// interface structure for a back-end +class drcbe_interface +{ +public: + // construction/destruction + drcbe_interface(drcuml_state &drcuml, drc_cache &cache, device_t &device); + virtual ~drcbe_interface(); + + // required overrides + virtual void reset() = 0; + virtual int execute(uml::code_handle &entry) = 0; + virtual void generate(drcuml_block &block, const uml::instruction *instlist, UINT32 numinst) = 0; + virtual bool hash_exists(UINT32 mode, UINT32 pc) = 0; + virtual void get_info(drcbe_info &info) = 0; + +protected: + // internal state + drcuml_state & m_drcuml; // pointer back to our owner + drc_cache & m_cache; // pointer to the cache + device_t & m_device; // CPU device we are associated with + address_space * m_space[ADDRESS_SPACES];// pointers to CPU's address space + drcuml_machine_state & m_state; // state of the machine (in near cache) + data_accessors * m_accessors; // memory accessors (in near cache) +}; + + +// structure describing UML generation state +class drcuml_state +{ +public: + // construction/destruction + drcuml_state(device_t &device, drc_cache &cache, UINT32 flags, int modes, int addrbits, int ignorebits); + ~drcuml_state(); + + // getters + device_t &device() const { return m_device; } + drc_cache &cache() const { return m_cache; } + + // reset the state + void reset(); + int execute(uml::code_handle &entry) { return m_beintf.execute(entry); } + + // code generation + drcuml_block *begin_block(UINT32 maxinst); + + // back-end interface + void get_backend_info(drcbe_info &info) { m_beintf.get_info(info); } + bool hash_exists(UINT32 mode, UINT32 pc) { return m_beintf.hash_exists(mode, pc); } + void generate(drcuml_block &block, uml::instruction *instructions, UINT32 count) { m_beintf.generate(block, instructions, count); } + + // handle management + uml::code_handle *handle_alloc(const char *name); + + // symbol management + void symbol_add(void *base, UINT32 length, const char *name); + const char *symbol_find(void *base, UINT32 *offset = NULL); + + // logging + bool logging() const { return (m_umllog != NULL); } + void log_printf(const char *format, ...); + void log_flush() { if (logging()) fflush(m_umllog); } + +private: + // symbol class + class symbol + { + friend class drcuml_state; + friend class simple_list<symbol>; + + // construction/destruction + symbol(void *base, UINT32 length, const char *name) + : m_next(NULL), + m_base(drccodeptr(base)), + m_length(length), + m_name(name) { } + + public: + // getters + symbol *next() const { return m_next; } + + private: + // internal state + symbol * m_next; // link to the next symbol + drccodeptr m_base; // base of the symbol + UINT32 m_length; // length of the region covered + astring m_name; // name of the symbol + }; + + // internal state + device_t & m_device; // CPU device we are associated with + drc_cache & m_cache; // pointer to the codegen cache + drcbe_interface & m_beintf; // backend interface pointer + FILE * m_umllog; // handle to the UML logfile + simple_list<drcuml_block> m_blocklist; // list of active blocks + simple_list<uml::code_handle> m_handlelist; // list of active handles + simple_list<symbol> m_symlist; // list of symbols +}; + + + +#endif /* __DRCUML_H__ */ |