summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/cpu/drcbeut.h
blob: 8987edb49c23955a2c25d85afa8f437591c37a35 (plain) (tree)
1
2
3
4
5
6
7
8

                                





                                                                            









                                                                            


                                                                            
 
                                         
 

                               
 


                                                                                         
 








                                                                                       
 




                                                  
                                                                                                








                                                                                                                                                                   

                                                                                    
 
                                                                                                    
 





                                                                                                    
 


                                                                                        


  
                                            
 

                                 
 


















                                                                                                   


                                                                                                    




                                                          



                                                                                                
          
                                                                  
  

 
                                         
 

                                                                     
                                          
                    
 









                                              
                                                                                                   
                                                                    




                                                            


                                                                                   
          
 


                                                            

                                                                              

                                                                


                                            
                                                             
                                                                           

                         



                                                                             
  

 
                          
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************

    drcbeut.h

    Utility functions for dynamic recompiling backends.

***************************************************************************/

#pragma once

#ifndef __DRCBEUT_H__
#define __DRCBEUT_H__

#include "drcuml.h"


//**************************************************************************
//  TYPE DEFINITIONS
//**************************************************************************

// ======================> drc_hash_table

// common hash table management
class drc_hash_table
{
public:
	// construction/destruction
	drc_hash_table(drc_cache &cache, UINT32 modes, UINT8 addrbits, UINT8 ignorebits);

	// getters
	drccodeptr ***base() const { return m_base; }
	UINT8 l1bits() const { return m_l1bits; }
	UINT8 l2bits() const { return m_l2bits; }
	UINT8 l1shift() const { return m_l1shift; }
	UINT8 l2shift() const { return m_l2shift; }
	offs_t l1mask() const { return m_l1mask; }
	offs_t l2mask() const { return m_l2mask; }
	bool is_mode_populated(UINT32 mode) const { return m_base[mode] != m_emptyl1; }

	// set up and configuration
	bool reset();
	void set_default_codeptr(drccodeptr code);

	// block begin/end
	void block_begin(drcuml_block &block, const uml::instruction *instlist, UINT32 numinst);
	void block_end(drcuml_block &block);

	// code pointer access
	bool set_codeptr(UINT32 mode, UINT32 pc, drccodeptr code);
	drccodeptr get_codeptr(UINT32 mode, UINT32 pc) { assert(mode < m_modes); return m_base[mode][(pc >> m_l1shift) & m_l1mask][(pc >> m_l2shift) & m_l2mask]; }
	bool code_exists(UINT32 mode, UINT32 pc) { return get_codeptr(mode, pc) != m_nocodeptr; }

private:
	// internal state
	drc_cache &     m_cache;                // cache where allocations come from
	UINT32          m_modes;                // number of modes supported

	drccodeptr      m_nocodeptr;            // pointer to code which will handle missing entries

	UINT8           m_l1bits;               // bits worth of entries in l1 hash tables
	UINT8           m_l2bits;               // bits worth of entries in l2 hash tables
	UINT8           m_l1shift;              // shift to apply to the PC to get the l1 hash entry
	UINT8           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

	drccodeptr ***  m_base;                 // pointer to the l1 table for each mode
	drccodeptr **   m_emptyl1;              // pointer to empty l1 hash table
	drccodeptr *    m_emptyl2;              // pointer to empty l2 hash table
};


// ======================> drc_map_variables

// common map variable management
class drc_map_variables
{
public:
	// construction/destruction
	drc_map_variables(drc_cache &cache, UINT64 uniquevalue);
	~drc_map_variables();

	// block begin/end
	void block_begin(drcuml_block &block);
	void block_end(drcuml_block &block);

	// get/set values
	void set_value(drccodeptr codebase, UINT32 mapvar, UINT32 newvalue);
	UINT32 get_value(drccodeptr codebase, UINT32 mapvar) const;
	UINT32 get_last_value(UINT32 mapvar);

	// static accessors to be called directly by generated code
	static UINT32 static_get_value(drc_map_variables &map, drccodeptr codebase, UINT32 mapvar);

private:
	// internal state
	drc_cache &         m_cache;            // pointer to the cache
	UINT64              m_uniquevalue;      // unique value used to find the table
	UINT32              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          m_mapvar;           // map variable id
		UINT32          m_newval;           // value of the variable starting at codeptr
	};
	simple_list<map_entry> m_entry_list;    // list of entries
};


// ======================> drc_label_list

typedef delegate<void (void *, drccodeptr)> drc_label_fixup_delegate;

// structure holding a live list of labels
class drc_label_list
{
public:
	// construction/destruction
	drc_label_list(drc_cache &cache);
	~drc_label_list();

	// block begin/end
	void block_begin(drcuml_block &block);
	void block_end(drcuml_block &block);

	// get/set values
	drccodeptr get_codeptr(uml::code_label label, drc_label_fixup_delegate fixup, void *param);
	void set_codeptr(uml::code_label label, drccodeptr codeptr);

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
	};

	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
	};

	// internal helpers
	void reset(bool fatal_on_leftovers);
	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
	drc_oob_delegate    m_oob_callback_delegate; // pre-computed delegate
};


#endif /* __DRCBEUT_H__ */