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

📄 instruction_set.cpp

📁 浙江大学的悟空嵌入式系统模拟器
💻 CPP
字号:
/*
*  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    ARM/Instruction_Set.cpp
*
*  $Id: Instruction_Set.cpp,v 1.7 2005/06/16 11:25:20 qilj Exp $
*
*  \author  Lingjie Qi <lingjie_qi@163.com> 
*/
//=============================================================================

#include "Instruction_Set.h"
#include "LS_Instruction.h"
#include "MLS_Instruction.h"
#include "Data_Process_Instruction.h"
#include "Jump_Instruction.h"
#include "CPSR_Instruction.h"
#include "SWI_Instruction.h"
#include "Nop_Instruction.h"
#include "Debug_Instruction.h"
#include "Copro_Instruction.h"

namespace ARM {

	DEFINE_SINGLETON(ARM_Instruction_Set)

		bool ARM_Instruction_Set::EQ()
	{ 
		//Instruction & obj = ARM::Instruction::instance ();
		return  ((ARM_CPU *) Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(30);
	}

	bool ARM_Instruction_Set::NE()
	{
		return !( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(30);//z clear
	}

	bool ARM_Instruction_Set::CS()
	{
		return ( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(29); //c set
	}

	bool ARM_Instruction_Set::CC()
	{
		return !( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(29);	//c clear
	}

	bool ARM_Instruction_Set::MI()
	{
		return ( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(31);
	}

	bool ARM_Instruction_Set::PL()
	{
		return  !( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(31);
	}

	bool ARM_Instruction_Set::VS()
	{
		return ( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(28);
	}

	bool ARM_Instruction_Set::VC()
	{
		return !( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(28); 
	}

	bool ARM_Instruction_Set::HI()
	{
		return ( ( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(29) \
			&& !( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(30) );

	}

	bool ARM_Instruction_Set::LS()
	{
		return ( !( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(29) \
			|| ( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(30) ); //c clear | z set
	}


	bool ARM_Instruction_Set::GE()
	{
		return ( ( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(31) \
			== ( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(28) );  // n equals v
	}

	bool ARM_Instruction_Set::LT()
	{
		return (( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(31)\
			!=( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(28)); // n not equals v
	}

	bool ARM_Instruction_Set::GT()
	{
		return !( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(30) \
			&& (( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(31)\
			==( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(28)); //z clear and (n == v)
	}

	bool ARM_Instruction_Set::LE()
	{
		return 
			(( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(30) \
			|| (( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(31)\
			!= ( (ARM_CPU *)Core::Wukong_Get_System().get_cpu() )->get_cpsr().test(28))); //z set or (n!=v)

	}

	bool ARM_Instruction_Set::AL()
	{
		return true;
	}

	bool ARM_Instruction_Set::test_cond(Core::u8 &val)
	{
		switch(val)
		{
		case 14:
			return  AL();
		case 0:
			return EQ();
		case 1:
			return NE();
		case 2:
			return CS();
		case 3:
			return CC();
		case 4:
			return MI();
		case 5:
			return PL();
		case 6:
			return VS();
		case 7:
			return VC();
		case 8:
			return HI();
		case 9:
			return LS();
		case 10:
			return GE();
		case 11:
			return LT();
		case 12:
			return GT();
		case 13:
			return LE();
		default:
			return false;
		}
	}

	void ARM_Instruction_Set::register_instructions()
	{
		register_instruction(ARM::Nop_Instruction::instance());
		register_instruction(ARM::LS_Instruction::instance());
		register_instruction(ARM::MLS_Instruction::instance());
		register_instruction(ARM::Data_Process_Instruction::instance());
		register_instruction(ARM::Jump_Instruction::instance());
		register_instruction(ARM::CPSR_Instruction::instance());
		register_instruction(ARM::SWI_Instruction::instance());
		register_instruction(ARM::Debug_Instruction::instance());
		register_instruction(ARM::Copro_Instruction::instance());
	}

	Core::Instruction *  ARM_Instruction_Set::classify(Core::Instruction_Unit  binary)
	{
		Core::Binary_32Bit bits(binary);
		u32 op_code = bits.convert_to_int(20,27); 
		u8 cond_code = (u8) bits.convert_to_int(28,31);

		//! Debug_Instruction
		if(bits.convert_to_int(0,31) == 0xFFFFFFFF)
			return instructions_[7];

		//! NOP_Instruction
		if(bits.convert_to_int(0,31) == 0xFFFFFFFE  )
			return instructions_[0];

		//! Nop_Instruction (condition dissatisfy)
		if ( ! test_cond(cond_code) )
			return instructions_[0];

		//! LS_Instruction
		if ( op_code >=0x40 &&  op_code <= 0x7f )
			return instructions_[1];

		//! MLS_Instruction
		if ( op_code >=0x80 &&  op_code <= 0x9f )
			return instructions_[2];

		//! Data_Instruction or  CPSR_Instruction
		if( op_code >=0x00 &&  op_code <= 0x1f )
		{
			if( bits.convert_to_int(4,7) == 0xb || 
				(bits.convert_to_int(4,7) == 0xd && bits.test(20))|| 
				(bits.convert_to_int(4,7) == 0xf && bits.test(20)) )
				return instructions_[1];  //LS_Instruction
			if( op_code != 0x10 && op_code != 0x12 && op_code != 0x14 && op_code != 0x16)
				return instructions_[3];  
			if(( bits.convert_to_int(4,15) == 0xf00 && bits.convert_to_int(20,21) == 2)||
				(bits.convert_to_int(16,19) == 0xf && bits.convert_to_int(20,21) == 0))
				return instructions_[5];  //! CPSR_Instruction
			if(op_code == 0x12 && bits.convert_to_int(12,15) == 0)
				return instructions_[3];  
			if(op_code == 0x12 )
				return instructions_[4];  // BX/BLX Instruction for version5 and above
			else
				return instructions_[3]; 
		}

		//! Data_Instruction or  CPSR_Instruction
		if( op_code>= 0x20 &&  op_code <= 0x3f )
		{
			if( op_code != 0x32 && op_code != 0x36)
				return instructions_[3];   
			if( bits.convert_to_int(12,15) == 0xf && bits.convert_to_int(20,21) == 2 )	
				return instructions_[5];  //! CPSR_Instruction
			else
				return instructions_[3];
		}

		//! Jump_Instruction
		if( op_code>= 0xa0 &&  op_code <= 0xbf )
			return instructions_[4];

		//! Corp_Instruction
		if( op_code>= 0xc0 &&  op_code <= 0xef )
			return instructions_[8];

		//! SWI_Instruction
		if( op_code>= 0xf0 &&  op_code <= 0xff )
			return instructions_[6];

		return instructions_[0];
	}

}//namespace

⌨️ 快捷键说明

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