#include "Behavioural/include/SPR_access_mode.h"

#include "Common/include/Debug.h"

namespace morpheo {
namespace behavioural {


    // SM    : Supervisor Mode
    //           * 0 : User Mode
    //           * 1 : Supervisor Mode
    // SUMRA : SPRs User Mode Read Access
    //           * 0 : All SPRs are inaccessible in user mode
    //           * 1 : Certain SPRs can be read in user mode
    
  bool SPR_access_mode::read (spr_address_t address, Tcontrol_t SM, Tcontrol_t SUMRA)
    {
//       log_printf(TRACE,true,"SPR_access_mode::read","address [%d][%d]",address._group,address._register);
//       log_printf(TRACE,true,"SPR_access_mode::read","sm        : %d",SM   );
//       log_printf(TRACE,true,"SPR_access_mode::read","sumra     : %d",SUMRA);

      if (not exist(address))
	return false;

      spr_access_mode_t mode = _spr_generic [address._group][address._register];

//       log_printf(TRACE,true,"SPR_access_mode::read","kernel    : %d",(int)mode._supervisor_access_mode);
//       log_printf(TRACE,true,"SPR_access_mode::read","user      : %d",(int)mode._supervisor_access_mode);

      return (((SM == 1) and ( (mode._supervisor_access_mode == SPR_ACCESS_MODE_READ_ONLY     ) or
			       (mode._supervisor_access_mode == SPR_ACCESS_MODE_READ_WRITE    ))) or
	      ((SM == 0) and ( (mode._user_access_mode       == SPR_ACCESS_MODE_READ_ONLY     ) or
			       (mode._user_access_mode       == SPR_ACCESS_MODE_READ_WRITE    ) or
			      ((mode._user_access_mode       == SPR_ACCESS_MODE_READ_ONLY_COND) and (SUMRA == 1)))));
    }

  bool SPR_access_mode::write(spr_address_t address, Tcontrol_t SM, Tcontrol_t SUMRA)
    {
      if (not exist(address))
	return false;

      spr_access_mode_t mode = _spr_generic [address._group][address._register];
      
      return (((SM == 1) and ( (mode._supervisor_access_mode == SPR_ACCESS_MODE_WRITE_ONLY    ) or
			       (mode._supervisor_access_mode == SPR_ACCESS_MODE_READ_WRITE    ))) or
	      ((SM == 0) and ( (mode._user_access_mode       == SPR_ACCESS_MODE_WRITE_ONLY    ) or
			       (mode._user_access_mode       == SPR_ACCESS_MODE_READ_WRITE    )))) ;
    }

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

