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

📄 ls_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/LS_Instruction.h
*
*  $Id: LS_Instruction.cpp,v 1.7 2005/06/08 07:40:45 qilj Exp $
*
*  \author  Jie Chen <alt_alt@163.com> 
*/
//=============================================================================

#include "./LS_Instruction.h"

namespace ARM{

	//	bool LS_Instruction::test_and_parse(Core::Instruction_Unit & binary)
	//	{
	/*
	Core::Binary_32Bit bits(binary);
	cond_code_ = (u8)bits.convert_to_int(28, 31);
	return true;
	*/
	//	}
	DEFINE_SINGLETON(LS_Instruction)

		void LS_Instruction::execute(Core::Instruction_Unit  binary)
	{
		Core::Binary_32Bit bits(binary);
		u32 opcode1 = bits.convert_to_int(4,7);
		u32 opcode2 = bits.convert_to_int(24,24);
		opcode2 = (opcode2<<3) + bits.convert_to_int(20,22);
		if( bits.test(26) )
			switch(opcode2)
		{	
			case 0x9:
				return LDR(binary);
			case 0x4:
				return STRB(binary);
			case 0x5:
				return LDRB(binary);
			case 0x8:
				return STR(binary);
			case 0xd:
				return LDRB(binary);
			case 0xc:
				return STRB(binary);
			case 0x0:
				return STR(binary);
			case 0x1:
				return LDR(binary);
			case 0xa:	
				return STR(binary);
			case 0xf:
				return LDRB(binary);
			case 0xb:
				return LDR(binary);
			case 0xe:
				return STRB(binary);
			case 0x2:
				//WUKONG_STDOUT<<"STRT\n";
				return STRT(binary);
			case 0x3:
				//WUKONG_STDOUT<<"LDRT\n";
				return LDRT(binary);
			case 0x6:
				//WUKONG_STDOUT<<"STRBT\n";
				return STRBT(binary);
			case 0x7:
				//WUKONG_STDOUT<<"LDRBT\n";
				return LDRBT(binary);
		}
		else
			switch(opcode1)
		{
			case 0xb:
				if (bits.test(20))
					return LDRH(binary);
				else
					return STRH(binary);
			case 0xd:
				return LDRSB(binary);
			case 0xf:
				return LDRSH(binary);
				//		default: return UND;
		}
	}

	/*	void LS_Instruction::execute(Core::Instruction_Unit  binary)
	{
	Core::Binary_32Bit bits(binary);
	u32 opcode = bits.convert_to_int(24,24);
	opcode = (opcode<<3) + bits.convert_to_int(20,22);
	switch(opcode)
	{	
	case 0x0:
	return STR(binary);
	case 0x1:
	return LDR(binary);
	case 0x2:
	return STRT(binary);
	case 0x3:
	return LDRT(binary);
	case 0x4:
	return STRB(binary);
	case 0x5:
	return LDRB(binary);
	case 0x6:
	return STRBT(binary);
	case 0x7:
	return LDRBT(binary);
	case 0x8:
	return STR(binary);
	case 0x9:
	return LDR(binary);
	case 0xa:	
	return STR(binary);
	case 0xb:
	return LDR(binary);
	case 0xc:
	return STRB(binary);
	case 0xd:
	return LDRB(binary);
	case 0xe:
	return STRB(binary);
	case 0xf:
	return LDRB(binary);
	//		default: return UND;
	}
	//need modify?
	}*/

	void LS_Instruction::LDR(Core::Instruction_Unit & binary)
	{
		u32 value;
		u32 addr;
		u8 addr_tale;
		Core::Binary_32Bit bits(binary);
		u32 rd_index = bits.convert_to_int(12,15);
		this->get_address(binary,addr);
		Core::Bytecode_Type buffer;
		addr_tale = (u8)(addr % 4);

		switch(addr_tale)
		{
		case 0:
			{
				//value = [addr]
				/*if((error_no = get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr,4,buffer)) != 0);
				//					Core::Wukong_Get_System()	.set_last_error(error_no);
				Wukong_Get_System().convert_from_bytecode(buffer,value);
				break;*/
				if ( (get_cpu()->get_mmu().access(Core::Memory_32Bit::MEMORY_READ, addr, 4, buffer)) == MMU::PAGE_TRANSLATION_FAULT)
				{
					get_cpu()->on_dataabt_exception(); 
					return;
				}
				else
					Wukong_Get_System().convert_from_bytecode(buffer,value);
				break;
			}
		case 1:
			{	
				//value = [addr - 1]
				//value = value rotate right 8
				/*if((error_no = get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr-1,4,buffer)) != 0);
				//					Core::Wukong_Get_System()	.set_last_error(error_no);
				Core::Wukong_Get_System().convert_from_bytecode(buffer,value);
				this->rotate_right(value,8);
				break;*/
				if ( (get_cpu()->get_mmu().access(Core::Memory_32Bit::MEMORY_READ, addr-1, 4, buffer)) == MMU::PAGE_TRANSLATION_FAULT)
				{
					get_cpu()->on_dataabt_exception(); 
					return;
				}
				else
					Wukong_Get_System().convert_from_bytecode(buffer,value);
				this->rotate_right(value,8);
				break;
			}
		case 2:
			{
				//value = [addr - 2]
				//value = value rotate right 16
				/*if(error_no = get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr-2,4,buffer) != 0);
				//					Core::Wukong_Get_System()	.set_last_error(error_no);
				Core::Wukong_Get_System().convert_from_bytecode(buffer,value);
				this->rotate_right(value,16);
				break;*/
				if ( (get_cpu()->get_mmu().access(Core::Memory_32Bit::MEMORY_READ, addr-2, 4, buffer)) == MMU::PAGE_TRANSLATION_FAULT)
				{
					get_cpu()->on_dataabt_exception(); 
					return;
				}
				else
					Wukong_Get_System().convert_from_bytecode(buffer,value);
				this->rotate_right(value,16);
				break;
			}
		case 3:
			{
				//value = [addr - 3]
				//value = value rotate right 24
				/*if(error_no = get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr-3,4,buffer) != 0);
				//					Core::Wukong_Get_System()	.set_last_error(error_no);
				Core::Wukong_Get_System().convert_from_bytecode(buffer,value);
				this->rotate_right(value,24);
				break;*/
				if ( (get_cpu()->get_mmu().access(Core::Memory_32Bit::MEMORY_READ, addr-3, 4, buffer)) == MMU::PAGE_TRANSLATION_FAULT)
				{
					get_cpu()->on_dataabt_exception(); 
					return;
				}
				else
					Wukong_Get_System().convert_from_bytecode(buffer,value);
				this->rotate_right(value,24);
				break;
			}
		}
		if(rd_index == 15)
		{
			this->get_cpu()->write_register(15,value & 0xfffffffe);
			Core::Binary_32Bit value_bits(value);
			get_cpu()->get_cpsr().set(5,int(value_bits.get(0)));
		}
		else
			this->get_cpu()->write_register(rd_index,value);
	}

	void LS_Instruction::LDRB(Core::Instruction_Unit & binary)
	{
		u8 value;
		u32 addr,value_32;
		Core::Binary_32Bit bits(binary);
		u32 rd_index = bits.convert_to_int(12,15);
		this->get_address(binary,addr);
		Core::Bytecode_Type buffer;

		/*if((error_no = get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr,1,buffer)) != 0);
		//			Core::Wukong_Get_System()	.set_last_error(error_no);*/

		if ( (get_cpu()->get_mmu().access(Core::Memory_32Bit::MEMORY_READ, addr, 1, buffer)) == MMU::PAGE_TRANSLATION_FAULT)
		{
			get_cpu()->on_dataabt_exception(); 
			return;
		}
		Wukong_Get_System().convert_from_bytecode(buffer,value);
		value_32 =u32 (value);
		get_cpu()->write_register(rd_index,value_32);
	}

	void LS_Instruction::LDRBT(Core::Instruction_Unit & binary)
	{
		u8 value;
		u32 addr,value_32;
		Core::Binary_32Bit bits(binary);
		u32 rd_index = bits.convert_to_int(12,15);//need get usermode register here!
		this->get_usermode_address(binary,addr);
		Core::Bytecode_Type buffer;

		/*if((error_no = get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr,1,buffer)) != 0);
		//			Core::Wukong_Get_System()	.set_last_error(error_no);*/

		if ( (get_cpu()->get_mmu().access(Core::Memory_32Bit::MEMORY_READ, addr, 1, buffer)) == MMU::PAGE_TRANSLATION_FAULT)
		{
			get_cpu()->on_dataabt_exception(); 
			return;
		}
		Wukong_Get_System().convert_from_bytecode(buffer,value);
		value_32 =u32 (value);
		get_cpu()->write_register(rd_index,value_32);

	}

	void LS_Instruction::LDRH(Core::Instruction_Unit & binary)
	{
		u32 addr,value_32;
		u16 value;
		Core::Binary_32Bit bits(binary);
		u32 rd_index = bits.convert_to_int(12,15);

		this->get_sh_address(binary,addr);
		if((addr % 2) == 0)
		{
			Core::Bytecode_Type buffer;
			/*if((error_no = get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr,2,buffer)) != 0);
			//				Core::Wukong_Get_System()	.set_last_error(error_no);*/

			if ( (get_cpu()->get_mmu().access(Core::Memory_32Bit::MEMORY_READ, addr, 2, buffer)) == MMU::PAGE_TRANSLATION_FAULT)
			{
				get_cpu()->on_dataabt_exception(); 
				return;
			}
			Wukong_Get_System().convert_from_bytecode(buffer,value);
			value_32 =u32 (value);
		}
		else
		{
			printf("LDRH error!");
			//value_32 unpredictable
		}
		get_cpu()->write_register(rd_index,value_32);
	}

	void LS_Instruction::LDRSB(Core::Instruction_Unit & binary)
	{
		u8 value;
		u32 addr,value_32;
		Core::Binary_32Bit bits(binary);
		u32 rd_index = bits.convert_to_int(12,15);
		this->get_sh_address(binary,addr);
		Core::Bytecode_Type buffer;

		/*if((error_no = get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr,1,buffer)) != 0);
		//			Core::Wukong_Get_System()	.set_last_error(error_no);*/

		if ( (get_cpu()->get_mmu().access(Core::Memory_32Bit::MEMORY_READ, addr, 1, buffer)) == MMU::PAGE_TRANSLATION_FAULT)
		{
			get_cpu()->on_dataabt_exception(); 
			return;
		}
		Wukong_Get_System().convert_from_bytecode(buffer,value);
		//need to opertimise
		if(value >= 0x80)
			value_32 = 0xffffff00 + u32(value);
		else
			value_32 = u32(value);
		//
		get_cpu()->write_register(rd_index,value_32);
	}

	void LS_Instruction::LDRSH(Core::Instruction_Unit & binary)
	{
		u32 addr,value_32;
		u16 value;
		Core::Binary_32Bit bits(binary);
		u32 rd_index = bits.convert_to_int(12,15);

		this->get_sh_address(binary,addr);
		if((addr % 2) == 0)
		{
			Core::Bytecode_Type buffer;
			/*if((error_no = get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr,2,buffer)) != 0);
			//				Core::Wukong_Get_System()	.set_last_error(error_no);*/

			if ( (get_cpu()->get_mmu().access(Core::Memory_32Bit::MEMORY_READ, addr, 2, buffer)) == MMU::PAGE_TRANSLATION_FAULT)
			{
				get_cpu()->on_dataabt_exception(); 
				return;
			}
			Wukong_Get_System().convert_from_bytecode(buffer,value);
			//need opertimise here
			if(value >= 0x1000)
				value_32 = 0xffff0000 + u32(value);
			else
				value_32 =u32 (value);
		}
		else
		{
			printf("LDRH error!");
			//value_32 unpredictable
		}
		get_cpu()->write_register(rd_index,value_32);

⌨️ 快捷键说明

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