#ifndef morpheo_behavioural_core_multi_ooo_engine_ooo_engine_rename_unit_register_translation_unit_stat_list_unit_Types_h
#define morpheo_behavioural_core_multi_ooo_engine_ooo_engine_rename_unit_register_translation_unit_stat_list_unit_Types_h

/*
 * $Id: Types.h 117 2009-05-16 14:42:39Z rosiere $
 *
 * [ Description ]
 * 
 */

#include "Behavioural/include/Types.h"

namespace morpheo {
namespace behavioural {

namespace core {
namespace multi_ooo_engine {
namespace ooo_engine {
namespace rename_unit {
namespace register_translation_unit {
namespace stat_list_unit {

  class stat_list_entry_t
  {
  public : bool     _is_free      ; // set = is present in free list
  public : bool     _is_link      ; // set = is present in rat
  public : bool     _is_use       ; // set = is present in ROB (used by an instruction as destination)
                                    // not necesseray in single thread mode : because an thread can't rename when they have an event
                                    // in multi thread, the renaming continue and an old register can be reused

  public :  stat_list_entry_t (void) {};
  public : ~stat_list_entry_t (void) {};

  public : void reset (bool is_link)
    {
      _is_free  = 0;
      _is_link  = is_link;
      _is_use   = is_link;
    }

  public : void insert_write_old (void)
    {
      // old is not in the rat, but is already used (if miss prediction or event)
      _is_link  = 0;
    }

  public : void insert_write_new (void)
    {
      _is_free  = 0;
      _is_link  = 1;
      _is_use   = 1;
    }

  public : void retire_write_old (bool restore, bool restore_old)
    {
      // restore restore_old is_link
      // 0       x           0       - normal case : unallocate
      // 1       0           0       - event and previous update
      // 1       1           1       - event and first update
   
      if (restore and restore_old)
        {
          _is_link = 1;
//        _is_use  = 1; // already set
        }
      else
        {
//        _is_link = 0; // already unset
          _is_use  = 0;
        }
        
    }

  public : void retire_write_new (bool restore, bool restore_old)
    {
      // restore restore_old is_link
      // 0       x           1       - normal case : allocate
      // 1       x           0       - event, need restore oldest register

      if (restore)
        {
          // test if is the actual mapping (in RAT)
          if (_is_link)
            _is_use = 0;

          _is_link = 0;
        }
    }

  public : void free (void)
    {
      _is_free  = 1;
    }

  public : bool can_free (void)
    {
      return ((_is_free  == 0) and
	      (_is_link  == 0) and
              (_is_use   == 0));
    }

  public : friend std::ostream& operator<< (std::ostream& output,
					    stat_list_entry_t & x)
    {
      output << x._is_free  << " "
             << x._is_link  << " "
             << x._is_use ;
      
      return output;
    }

  };


}; // end namespace stat_list_unit
}; // end namespace register_translation_unit
}; // end namespace rename_unit
}; // end namespace ooo_engine
}; // end namespace multi_ooo_engine
}; // end namespace core

}; // end namespace behavioural
}; // end namespace morpheo              

#endif
