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

📄 data_process_instruction.cpp

📁 浙江大学的悟空嵌入式系统模拟器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*
*  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/Data_Process__Instruction.h
*
*  $Id: Data_Process_Instruction.cpp,v 1.6 2005/06/21 02:30:55 qilj Exp $
*
*  \author  Jie Chen <alt_alt@163.com> 
Lingjie Qi <lingjie_qi@163.com> 
*/
//=============================================================================

#include "Data_Process_Instruction.h"
namespace ARM{

	DEFINE_SINGLETON(Data_Process_Instruction)

		void Data_Process_Instruction::execute(Core::Instruction_Unit  binary)
	{
		Core::Binary_32Bit bits(binary);
		u32 opcode = bits.convert_to_int(21,24);
		switch(opcode)
		{
		case 2:
			return SUB(binary);
		case 13:
			return MOV(binary);
		case 11:
			if(bits.test(20))
				return CMN(binary);
			//v5
			else
				if( bits.convert_to_int(16,19) == 0xf && bits.convert_to_int(4,11) == 0xF1)
					return CLZ(binary);   //Version 5 and above
				else
					return SMULxy(binary);  //Version 5E 
		case 10:
			if(bits.convert_to_int(4,11) == 9 && bits.convert_to_int(20,24) == 0x14)
				return SWPB(binary);
			else
				return CMP(binary);
		case 4:
			if(bits.convert_to_int(4,7) == 9 && !bits.test(25))
				return UMULL(binary);
			else
				return ADD(binary);
		case 8:
			if(bits.convert_to_int(4,11) == 9 && bits.convert_to_int(20,24) == 0x10)
				return SWP(binary);
			else
				return TST(binary);
		case 0:
			if( bits.convert_to_int(12,15) == 0 && bits.convert_to_int(4,7) == 9 && !bits.test(25))
				return MUL(binary);
			else
				return AND(binary);
		case 12:
			return ORR(binary);
		case 3:
			return RSB(binary);
		case 14:
			return BIC(binary);
		case 1:
			if(bits.convert_to_int(4,7) == 9 && !bits.test(25))
				return MLA(binary);
			else
				return EOR(binary);
		case 9:
			return TEQ(binary);
		case 15:
			return MVN(binary);
		case 6:
			if(bits.convert_to_int(4,7) == 9 && !bits.test(25))
				return SMULL(binary);
			else
				return SBC(binary);
		case 5:
			if(bits.convert_to_int(4,7) == 9 && !bits.test(25))
				return UMLAL(binary);
			else
				return ADC(binary);
		case 7:
			if(bits.convert_to_int(4,7) == 9 && !bits.test(25))
				return SMLAL(binary);
			else
				return RSC(binary);
			//		default:
			//			return UND;
		}
	}

	void Data_Process_Instruction::MOV(Core::Instruction_Unit & binary) 
	{
		Core::Binary_32Bit bits(binary);
		u32 rd_index = bits.convert_to_int(12,15);
		//		Register_32bit & cpsr = get_register("CPSR");
		// Register_32bit & rd = get_register(rd_index);
		u32 shifter_operand;
		if(bits.get(25))
		{	
			shifter_operand = this->immediate_generator(bits);
		}
		else
		{
			shifter_operand = this->shift_imm_generator(bits);
		}
		this->get_cpu()->write_register(rd_index,shifter_operand);
		u32 rd_data = shifter_operand;
		Core::Binary_32Bit rd_bits(rd_data);
		if(bits.get(20) && rd_index == 15) 
		{
			// if s ==1 && rd == r15
			u32 spsr_data = get_cpu()->get_spsr().convert_to_int();
			get_cpu()->get_cpsr().convert_from_int(spsr_data);
			ARM_CPU::CPU_Interrupt temp_iter = get_cpu()->pop_exception();
			get_cpu()->set_exp_priority(temp_iter);
			get_cpu()->set_cpu_mode();
		}
		else if(bits.get(20))
		{
			get_cpu()->get_cpsr().set(31,rd_bits.get(31));
			if(rd_data == 0 )
				get_cpu()->get_cpsr().set(30,1);
			else
				get_cpu()->get_cpsr().set(30,0);
			get_cpu()->get_cpsr().set(29,get_cpu()->get_shifter_carry_out());
		}
		return;
	}

	void Data_Process_Instruction::MVN(Core::Instruction_Unit & binary)
	{
		Core::Binary_32Bit bits(binary);
		u32 rd_index = bits.convert_to_int(12,15);
		//	Register_32bit & cpsr = get_register("CPSR");
		// Register_32bit & rd = get_register(rd_index);
		u32 shifter_operand;
		if(bits.get(25))
		{	
			shifter_operand = this->immediate_generator(bits);
		}
		else
		{
			shifter_operand = this->shift_imm_generator(bits);
		}
		shifter_operand = ~shifter_operand;
		this->get_cpu()->write_register(rd_index,shifter_operand);
		u32 rd_data = shifter_operand;
		Core::Binary_32Bit rd_bits(rd_data);
		if(bits.get(20) && rd_index == 15) 
		{
			// if s ==1 && rd == r15
			u32 spsr_data = get_cpu()->get_spsr().convert_to_int();
			get_cpu()->get_cpsr().convert_from_int(spsr_data);
			ARM_CPU::CPU_Interrupt temp_iter = get_cpu()->pop_exception();
			get_cpu()->set_exp_priority(temp_iter);
			get_cpu()->set_cpu_mode();
		}
		else if(bits.get(20))
		{
			get_cpu()->get_cpsr().set(31,rd_bits.get(31));
			if(rd_data == 0 )
				get_cpu()->get_cpsr().set(30,1);
			else
				get_cpu()->get_cpsr().set(30,0);
			get_cpu()->get_cpsr().set(29,get_cpu()->get_shifter_carry_out());
		}
		return;
	}

	void Data_Process_Instruction::CMP(Core::Instruction_Unit & binary)
	{
		Core::Binary_32Bit bits(binary);
		u32 rn_index = bits.convert_to_int(16,19);
		u32 rn_data;
		this->get_cpu()->read_register(rn_index,rn_data);
		u32 shifter_operand,cmp_fact;
		u32 extra = 0;
		if(bits.get(25))
		{
			shifter_operand = this->immediate_generator(bits);
		}
		else
		{
			shifter_operand = this->shift_imm_generator(bits);
		}
		if(rn_index == 15)
			extra = 4;
		rn_data += extra;
		cmp_fact = rn_data  - shifter_operand;
		Core::Binary_32Bit fact_bits(cmp_fact);
		Core::Binary_32Bit operand_bits(shifter_operand);//used for V flag
		get_cpu()->get_cpsr().set(31,fact_bits.get(31));
		if(cmp_fact == 0 )
			get_cpu()->get_cpsr().set(30,1);
		else
			get_cpu()->get_cpsr().set(30,0);
		if(rn_data  >= shifter_operand)	
			get_cpu()->get_cpsr().set(29,1);
		else
			get_cpu()->get_cpsr().set(29,0);
		Core::Binary_32Bit rn_extra(rn_data);
		if(rn_extra.get(31) != operand_bits.get(31) && rn_extra.get(31) != fact_bits.get(31))
			get_cpu()->get_cpsr().set(28,1);
		else
			get_cpu()->get_cpsr().set(28,0);
		return;
	}

	void Data_Process_Instruction::CMN(Core::Instruction_Unit & binary)
	{
		Core::Binary_32Bit bits(binary);
		u32 rn_index = bits.convert_to_int(16,19);
		u32 rn_data;
		this->get_cpu()->read_register(rn_index,rn_data);
		u32 shifter_operand,cmp_fact;
		u32 extra = 0;
		if(bits.get(25))
		{
			shifter_operand = this->immediate_generator(bits);
		}
		else
		{
			shifter_operand = this->shift_imm_generator(bits);
		}
		if(rn_index == 15)
			extra = 4;
		rn_data += extra;
		cmp_fact = rn_data  + shifter_operand;
		Core::Binary_32Bit fact_bits(cmp_fact);
		Core::Binary_32Bit operand_bits(shifter_operand);//used for V flag
		get_cpu()->get_cpsr().set(31,fact_bits.get(31));
		if(cmp_fact == 0 )
			get_cpu()->get_cpsr().set(30,1);
		else
			get_cpu()->get_cpsr().set(30,0);
		if(cmp_fact  < shifter_operand || cmp_fact < rn_data)	
			get_cpu()->get_cpsr().set(29,1);
		else
			get_cpu()->get_cpsr().set(29,0);
		Core::Binary_32Bit rn_extra(rn_data);
		if(rn_extra.get(31) == operand_bits.get(31) && rn_extra.get(31) != fact_bits.get(31))
			get_cpu()->get_cpsr().set(28,1);
		else
			get_cpu()->get_cpsr().set(28,0);
		return;
	}

	void Data_Process_Instruction::TST(Core::Instruction_Unit & binary)
	{
		Core::Binary_32Bit bits(binary);
		u32 rn_index = bits.convert_to_int(16,19);
		u32 rn_data;
		this->get_cpu()->read_register(rn_index,rn_data);
		u32 shifter_operand,cmp_fact;
		u32 extra = 0;
		if(bits.get(25))
		{
			shifter_operand = this->immediate_generator(bits);
		}
		else
		{
			shifter_operand = this->shift_imm_generator(bits);
		}
		if(rn_index == 15)
			extra = 4;
		rn_data += extra;
		cmp_fact = rn_data & shifter_operand;
		Core::Binary_32Bit fact_bits(cmp_fact);
		get_cpu()->get_cpsr().set(31,fact_bits.get(31));
		if(cmp_fact == 0 )
			get_cpu()->get_cpsr().set(30,1);
		else
			get_cpu()->get_cpsr().set(30,0);
		get_cpu()->get_cpsr().set(29,get_cpu()->get_shifter_carry_out());
		return;
	}

	void Data_Process_Instruction::TEQ(Core::Instruction_Unit & binary)
	{
		Core::Binary_32Bit bits(binary);
		u32 rn_index = bits.convert_to_int(16,19);
		u32 rn_data;
		this->get_cpu()->read_register(rn_index,rn_data);
		u32 shifter_operand,cmp_fact;
		u32 extra = 0;
		if(bits.get(25))
		{
			shifter_operand = this->immediate_generator(bits);
		}
		else
		{
			shifter_operand = this->shift_imm_generator(bits);
		}
		if(rn_index == 15)
			extra = 4;
		rn_data += extra;
		cmp_fact = rn_data ^ shifter_operand;
		Core::Binary_32Bit fact_bits(cmp_fact);
		get_cpu()->get_cpsr().set(31,fact_bits.get(31));
		if(cmp_fact == 0 )
			get_cpu()->get_cpsr().set(30,1);
		else
			get_cpu()->get_cpsr().set(30,0);
		get_cpu()->get_cpsr().set(29,get_cpu()->get_shifter_carry_out());
		return;
	}

	void Data_Process_Instruction::ADD(Core::Instruction_Unit & binary)
	{
		Core::Binary_32Bit bits(binary);
		u32 rn_index = bits.convert_to_int(16,19);
		u32 rd_index = bits.convert_to_int(12,15);
		u32 rn_data;
		get_cpu()->read_register(rn_index,rn_data);
		u32 shifter_operand;
		u32 extra = 0;
		if(bits.get(25))
		{
			shifter_operand = this->immediate_generator(bits);
		}
		else
		{
			shifter_operand = this->shift_imm_generator(bits);
		}
		if(rn_index == 15)
			extra = 4;
		rn_data += extra;
		Core::Binary_32Bit operand_bits(shifter_operand);
		u32 fact = rn_data + shifter_operand;
		Core::Binary_32Bit fact_bits(fact);
		get_cpu()->write_register(rd_index,fact);
		if(bits.get(20) && rd_index == 15) // if s ==1 && rd == r15
		{
			u32 spsr_data = get_cpu()->get_spsr().convert_to_int();
			get_cpu()->get_cpsr().convert_from_int(spsr_data);
			ARM_CPU::CPU_Interrupt temp_iter = get_cpu()->pop_exception();
			get_cpu()->set_exp_priority(temp_iter);
			get_cpu()->set_cpu_mode();
		}
		else
			if(bits.get(20))
			{
				get_cpu()->get_cpsr().set(31,fact_bits.get(31));
				if(fact == 0)
					get_cpu()->get_cpsr().set(30,1);
				else
					get_cpu()->get_cpsr().set(30,0);			
				Core::Binary_32Bit rn_bits(rn_data);
				if(fact < shifter_operand || fact < rn_data)
					get_cpu()->get_cpsr().set(29,1);
				else 
					get_cpu()->get_cpsr().set(29,0);
				if(rn_bits.get(31) == operand_bits.get(31) && fact_bits.get(31) != rn_bits.get(31))
					get_cpu()->get_cpsr().set(28,1);
				else
					get_cpu()->get_cpsr().set(28,0);
			}
			return;
	}

	void Data_Process_Instruction::SUB(Core::Instruction_Unit & binary)
	{
		Core::Binary_32Bit bits(binary);
		u32 rn_index = bits.convert_to_int(16,19);
		u32 rd_index = bits.convert_to_int(12,15);
		u32 rn_data;
		get_cpu()->read_register(rn_index,rn_data);
		u32 shifter_operand;
		u32 extra = 0;
		if(bits.get(25))
		{
			shifter_operand = this->immediate_generator(bits);
		}
		else
		{
			shifter_operand = this->shift_imm_generator(bits);
		}
		if(rn_index == 15)
			extra = 4;
		rn_data += extra;
		Core::Binary_32Bit operand_bits(shifter_operand);
		u32 fact = rn_data - shifter_operand;
		Core::Binary_32Bit fact_bits(fact);
		get_cpu()->write_register(rd_index,fact);
		if(bits.get(20) && rd_index == 15) // if s ==1 && rd == r15
		{
			u32 spsr_data = get_cpu()->get_spsr().convert_to_int();
			get_cpu()->get_cpsr().convert_from_int(spsr_data);
			ARM_CPU::CPU_Interrupt temp_iter = get_cpu()->pop_exception();
			get_cpu()->set_exp_priority(temp_iter);
			get_cpu()->set_cpu_mode();
		}
		else
			if(bits.get(20))
			{
				get_cpu()->get_cpsr().set(31,fact_bits.get(31));
				if(fact == 0)

⌨️ 快捷键说明

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