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

📄 branch_instruction.cpp

📁 浙江大学的悟空嵌入式系统模拟器
💻 CPP
字号:
/* -*- 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        Branch_Instruction.h
* @brief       
* @author      Chenfeng Zhou <ini_autumn@163.com> 
*
* Created    : <2005-02-24 12:58:27 by Cheney Chow>
* Last update: <2005-03-03 17:59:27 by Cheney Chow>
*
* $Id: Branch_Instruction.cpp,v 1.1 2005/06/16 06:01:43 qilj Exp $
*/
///==================================================

#include "Instr_Flag.h"
#include "Instr_Declare.h"
#include "Parser.h"
#include "Register.h"
#include "Types.h"
#include "Reg_Utils.h"
#include "Utils/Debug.h"

namespace PPC {

	PPC_INSTRUCTION_IMPL(op_bx)
	{
		Core::u32 li;
		I_Form_Parser::parse(instr, li);

		bool aa = true, lk = false;

		// Relative address?
		if (!(instr & Op_Flag::AA) ) {
			li += GET_CPU().get_pc();
			aa = false;
		}

		if (instr & Op_Flag::LK) {
			REG(LR).convert_from_int(GET_CPU().get_pc() + 4);
			lk = true;
		}

		PPC_TRACE_3("bx", (Core::u32*)li, (aa? "AA" : "NO_AA"), (lk? "LK" : "NO_LK"));

		GET_CPU().set_npc(li);
	}

	PPC_INSTRUCTION_IMPL(op_bcx)
	{
		PPC_u32 BO, BD, BI;
		B_Form_Parser::parse(instr, BO, BD, BI);

		bool aa = true, lk = false;

		if ( !(BO & 4) )
			REG(CTR).convert_from_int(REG_TO_INT(REG(CTR)) - 1);

		bool bo2 = (BO & 2);
		bool bo8 = (BO & 8);
		bool cr = REG_BIT_IS_SET(CR, 31 - BI);

		bool ctr_ok = (BO & 4) || ((REG_TO_INT(REG(CTR)) != 0) ^ bo2);
		bool cond_ok = (BO & 16) || (!(cr ^ bo8));

		if (ctr_ok && cond_ok) {
			if (!(instr & Op_Flag::AA) ) {
				BD += GET_CPU().get_pc();
				aa = false;
			}

			if (instr & Op_Flag::LK) {
				REG(LR).convert_from_int(GET_CPU().get_pc() + 4);
				lk = true;
			}

			PPC_TRACE_3("bcx", (Core::u32*)BD,  (aa? "AA" : "NO_AA"), (lk? "LK" : "NO_LK"));

			GET_CPU().set_npc(BD);
		}

		else {
			PPC_TRACE("bcx: npc not set!\n");
		}
	}

	PPC_INSTRUCTION_IMPL(op_bcctrx)
	{
		PPC_u32 BO, BD, BI;
		X_Form_Parser::parse_xl(instr, BO, BI, BD);

		PPC_TRACE_3("bcctrx", BO, BI, BD);

		PPC_ASSERT(BD == 0);
		PPC_ASSERT(!(BO & 2));

		bool bo8 = (BO & 8);
		bool cr = REG_BIT_IS_SET(CR, 31 - BI);

		if ((BO & 16) || (!(cr ^ bo8))) {
			if (instr & Op_Flag::LK)
				REG(LR).convert_from_int(GET_CPU().get_pc() + 4);

			GET_CPU().set_npc(REG_TO_INT(REG(CTR)) & 0xfffffffc);

			PPC_TRACE_3("---bcctrx ", (Core::u32*)GET_CPU().get_npc(), "", "");
		}

		else 
			PPC_TRACE("bcctrx: npc not set!\n");
	}

	PPC_INSTRUCTION_IMPL(op_bclrx)
	{
		PPC_u32 BO, BD, BI;
		X_Form_Parser::parse_xl(instr, BO, BI, BD);

		bool lk = false;

		PPC_ASSERT(BD == 0);

		if ( !(BO & 4) )
			REG(CTR).convert_from_int(REG_TO_INT(REG(CTR)) - 1);

		bool bo2 = (BO & 2);
		bool bo8 = (BO & 8);
		bool cr = REG_BIT_IS_SET(CR, 31 - BI);

		bool ctr_ok = (BO & 4) || ((REG_TO_INT(REG(CTR)) != 0) ^ bo2);
		bool cond_ok = (BO & 16) || (!(cr ^ bo8));

		if (ctr_ok && cond_ok) {
			BD = (REG_TO_INT(REG(LR)) & 0xfffffffc);
			
			if (instr & Op_Flag::LK) {
				REG(LR).convert_from_int(GET_CPU().get_pc() + 4);
				lk = true;
			}

			PPC_TRACE_3("bclrx", (Core::u32*)BD, "", (lk? "LK" : "NO_LK"));

			GET_CPU().set_npc(BD);
		}

		else {
			PPC_TRACE("bclrx: npc not set!\n");
		}
	}

} //namespace PPC

⌨️ 快捷键说明

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