⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reg_utils.h

📁 浙江大学的悟空嵌入式系统模拟器
💻 H
字号:
/* -*- C++ -*- */

/**
 *  Copyright (c) 2005 Zhejiang University, P.R.China
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */ 


///==================================================
/**
 * @file        Reg_Utils.h
 * @brief       Register Utilities
 *
 * @author      Chenfeng Zhou <ini_autumn@163.com> 
 *
 * Created    : <2005-02-24 12:58:27 by Cheney Chow>
 * Last update: <2005-02-28 21:49:04 by Cheney Chow>
 *
 * $Id: Reg_Utils.h,v 1.1 2005/06/16 06:01:51 qilj Exp $
 */
///==================================================


#ifndef _REG_UTILS_
#define _REG_UTILS_

#include "Core/Global.h"
#include "Core/System.h"

#include "CPU.h"
#include "Register.h"
#include "Reg_Flag.h"
#include "Types.h"
#include "Utils/Debug.h"

namespace PPC
{

    inline PPC_CPU &GET_CPU ()
    {
		PPC_CPU *cpu = (PPC_CPU*)Core::Wukong_Get_System().get_cpu();
		PPC_ASSERT(cpu);
		
		return *cpu;
    }

	inline PPC_MMU &GET_MMU ()
	{
		return GET_CPU().get_mmu();
	}

    inline PPC_Register &REG (int index)
    {
        return GET_CPU().get_register (index);
    }
    
	inline PPC_Register& SPR_REG(unsigned int index)
	{
		return GET_CPU().get_regfile().get_spr(index);
	}

    //! Get the value of a register
    inline PPC_Register_Int REG_TO_INT (const PPC_Register &reg)
    {
        return reg.convert_to_int ();
    }

    inline void REG_SET_BIT (Reg_Index reg_index, int bit_index)
    {
        REG (reg_index).set (bit_index, 1);
    }

    inline void REG_CLEAR_BIT (Reg_Index reg_index, int bit_index)
    {
        REG (reg_index).set (bit_index, 0);
    }

    inline bool REG_BIT_IS_SET (Reg_Index reg_index, int bit_index)
    {
        return REG (reg_index).test (bit_index);
    }
    
	//! Compare the values of two registers
    inline bool operator<(const PPC_Register& r1, const PPC_Register &r2)
    {
        return REG_TO_INT (r1) < REG_TO_INT (r2);
    }
    
	//! Add two registers
	inline void REG_ADD (PPC_Register& res, const PPC_Register &s1, const PPC_Register &s2)
	{
		res.convert_from_int(s1.convert_to_int() + s2.convert_to_int());
	}

    //! Overload
    inline void REG_ADD (PPC_Register &res, const PPC_Register &s, PPC_Register_Int imm)
    {
        res.convert_from_int (s.convert_to_int () + imm);
    }
    
	//! Subtract two registers
	inline void REG_SUB (PPC_Register& res, const PPC_Register &s1, const PPC_Register &s2)
	{
		res.convert_from_int(s1.convert_to_int() - s2.convert_to_int());
	}

    inline void REG_MUL (PPC_Register &res, const PPC_Register &s1, const PPC_Register &s2)
    {
        res.convert_from_int (s1.convert_to_int () * s2.convert_to_int ());
    }
    
	//! Signed Divide
	inline void REG_SDIV (PPC_Register& res, const PPC_Register &s1, const PPC_Register &s2)
	{
		res.convert_from_int((PPC_s32)s1.convert_to_int() / (PPC_s32)s2.convert_to_int());
	}

	//! Unsigned Divide
	inline void REG_UDIV (PPC_Register& res, const PPC_Register &s1, const PPC_Register &s2)
	{
		res.convert_from_int(s1.convert_to_int() / s2.convert_to_int());
	}

    //! Clear the highest 4 bits;
    //! For implict result of integer operations
    inline void REG_CLEAR_CR0 ()
    {
		GET_CPU ().get_register (CR).set (Reg_Flag::CR0_LOW, Reg_Flag::CR0_HIGH, 0);
    }
    
    inline void REG_UPDATE_CR0 (const PPC_Register & reg)
    {
        REG_CLEAR_CR0 ();

		if (reg.convert_to_int() == 0) 
			REG (CR).set (Reg_Flag::CR0_EQ, 1);
        else if (reg.test (31))
            REG (CR).set (Reg_Flag::CR0_LT, 1);
        else
            REG (CR).set (Reg_Flag::CR0_GT, 1);

        if (REG (XER).test (Reg_Flag::XER_SO))
            REG (CR).set (Reg_Flag::CR0_SO, 1);
    }

	//? TODO:
	//		1. handle `singlestep'
	//		2. check new_msr's validation;
	inline void REG_SET_MSR (Core::u32 new_msr)
	{
		if (REG_BIT_IS_SET(MSR, Reg_Flag::MSR_POW))
			// We don't need power management;
			REG_CLEAR_BIT(MSR, Reg_Flag::MSR_POW);

		REG(MSR).convert_from_int(new_msr);
	}

    inline bool JUDGE_CARRY_3 (PPC_Register_Int a, PPC_Register_Int b, PPC_Register_Int c)
    {
        if ((a + b) < a )
            return true;
        if ((a + b + c) < c)
            return true;

        return false;
    }
    
} // namespace PPC

#endif  // _REG_UTILS_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -