summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/cpu/drcuml.h
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/cpu/drcuml.h')
-rw-r--r--trunk/src/emu/cpu/drcuml.h268
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__ */