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

📄 cpsr_instruction.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/CPSR_Instruction.cpp
*
*  $Id: CPSR_Instruction.cpp,v 1.3 2005/06/08 07:40:44 qilj Exp $
*
*  \author  Lingjie Qi <lingjie_qi@163.com> 
*/
//=============================================================================

#include "./CPSR_Instruction.h"

namespace ARM {

	DEFINE_SINGLETON(CPSR_Instruction)

		void CPSR_Instruction::execute(Core::Instruction_Unit  binary)
	{
		Core::Binary_32Bit bits(binary);
		u32 opcode_0 = bits.convert_to_int(20,21);
		u32 opcode_1 = bits.convert_to_int(25,25);

		switch(opcode_0)
		{
			//! This is a MSR instruction
		case 0x2:
			if(opcode_1 == 0)
				return MSR2(binary);
			else
				return MSR1(binary);

			//! This is a MRS instruction
		case 0x0:
			return MRS(binary);
			//default: return UND;
		}
	}

	void CPSR_Instruction::MRS(Core::Instruction_Unit & binary)
	{
		Core::Binary_32Bit bits(binary);
		u32 Rd;
		int Rd_index;

		Rd_index = bits.convert_to_int(12,15);
		if ( bits.test(22) )
		{
			Core::Register &spsr = get_cpu()->get_spsr();
			Rd = spsr.convert_to_int();
			get_cpu()->write_register( Rd_index, Rd );
		}
		else
		{
			Rd = get_cpu()->get_cpsr().convert_to_int();
			get_cpu()->write_register( Rd_index, Rd );
		}
		return;
	}

	void CPSR_Instruction::MSR1(Core::Instruction_Unit &binary)
	{
		Core::Binary_32Bit bits(binary);
		u32  val, operand;

		operand = this->immediate_generator(bits);   

		if( !bits.test(22) )  // R==0
		{
			if(bits.test(16)  && get_cpu()->get_cpu_mode() != ARM_CPU::User)
			{
				val = operand & 0xFF;
				assign( get_cpu() ->get_cpsr(), 0, 7, val);
				// set CPU mode
				get_cpu()->set_cpu_mode();
			}
			if(bits.test(17)  && get_cpu()->get_cpu_mode() != ARM_CPU::User)
			{
				val=( operand>>8 ) & 0xFF;
				assign( get_cpu() ->get_cpsr(), 8, 15, val);
			}
			if(bits.test(18)  && get_cpu()->get_cpu_mode() != ARM_CPU::User)
			{
				val=( operand>>16 ) & 0xFF;
				assign( get_cpu()->get_cpsr(), 16, 23, val);
			}
			if(bits.test(19) )
			{
				val=( operand>>24 ) & 0xFF;
				assign( get_cpu()->get_cpsr(), 24, 31, val);
			}
		}
		else  // R==1
		{
			Core::Register &spsr = get_cpu()->get_spsr();
			if(bits.test(16)  && get_cpu()->get_cpu_mode() != ARM_CPU::User && get_cpu()->get_cpu_mode() !=ARM_CPU::Sys) 
			{
				val = operand & 0xFF;
				assign_register(spsr, 0, 7, val);
			}
			if(bits.test(17)  && get_cpu()->get_cpu_mode() != ARM_CPU::User && get_cpu()->get_cpu_mode() !=ARM_CPU::Sys)
			{
				val=( operand>>8 ) & 0xFF;
				assign_register(spsr, 8, 15, val);
			}
			if(bits.test(18)  && get_cpu()->get_cpu_mode() != ARM_CPU::User && get_cpu()->get_cpu_mode() !=ARM_CPU::Sys)
			{
				val=( operand>>16 ) & 0xFF;
				assign_register(spsr, 16, 23, val);
			}
			if(bits.test(19)  && get_cpu()->get_cpu_mode() != ARM_CPU::User && get_cpu()->get_cpu_mode() !=ARM_CPU::Sys)
			{
				val=( operand>>24 ) & 0xFF;
				assign_register(spsr, 24, 31, val);
			}
		}
		return;
	}

	void CPSR_Instruction::MSR2(Core::Instruction_Unit &binary)
	{
		Core::Binary_32Bit bits(binary);
		u32 Rm_index, val, operand;

		Rm_index = bits.convert_to_int(0,3);
		get_cpu() -> read_register( Rm_index,  operand );
		if( !bits.test(22) )  // R==0
		{
			if(bits.test(16)   && get_cpu()->get_cpu_mode() != ARM_CPU::User)
			{
				val = operand & 0xFF;
				assign(get_cpu() ->get_cpsr(), 0, 7, val);
				// set CPU mode
				get_cpu()->set_cpu_mode();
			}
			if(bits.test(17)  && get_cpu()->get_cpu_mode() != ARM_CPU::User)
			{
				val=( operand>>8 ) & 0xFF;
				assign( get_cpu()->get_cpsr(), 8, 15, val);
			}
			if(bits.test(18)  && get_cpu()->get_cpu_mode() != ARM_CPU::User)
			{
				val=( operand>>16 ) & 0xFF;
				assign( get_cpu()->get_cpsr(), 16, 23, val);
			}
			if(bits.test(19) )
			{
				val=( operand>>24 ) & 0xFF;
				assign( get_cpu()->get_cpsr(), 24, 31, val);
			}
		}
		else  // R==1
		{	
			Core::Register &spsr = get_cpu()->get_spsr();
			if(bits.test(16)  && get_cpu()->get_cpu_mode() != ARM_CPU::User && get_cpu()->get_cpu_mode() !=ARM_CPU::Sys) 
			{
				val = operand & 0xFF;
				assign_register(spsr, 0, 7, val);
			}
			if(bits.test(17)  && get_cpu()->get_cpu_mode() != ARM_CPU::User && get_cpu()->get_cpu_mode() !=ARM_CPU::Sys)
			{
				val=( operand>>8 ) & 0xFF;
				assign_register(spsr, 8, 15, val);
			}
			if(bits.test(18)  && get_cpu()->get_cpu_mode() != ARM_CPU::User && get_cpu()->get_cpu_mode() !=ARM_CPU::Sys)
			{
				val=( operand>>16 ) & 0xFF;
				assign_register(spsr, 16, 23, val);
			}
			if(bits.test(19)  && get_cpu()->get_cpu_mode() != ARM_CPU::User && get_cpu()->get_cpu_mode() !=ARM_CPU::Sys)
			{
				val=( operand>>24 ) & 0xFF;
				assign_register(spsr, 24, 31, val);
			}
		}
		return;
	}

} //namespace

⌨️ 快捷键说明

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