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

📄 integer_store_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        Integer_Store_Instruction.h
* @brief       
* @author      Chenfeng Zhou <ini_autumn@163.com> 
*
* Created    : <2005-02-24 12:58:27 by Cheney Chow>
* Last update: <2005-05-26 21:05:36 by Cheney Chow>
*
* $Id: Integer_Store_Instruction.cpp,v 1.1 2005/06/16 06:01:47 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"
#include "MMU.h"


/**
* If there's a data page fault, we exit immediately;
* including the multi-store instructions;
*/

namespace PPC {

	PPC_INSTRUCTION_IMPL(op_stb)
	{
		PPC_s32 S, A;
		PPC_u32 imm;

		D_Form_Parser::parse_simm (instr, S, A, imm);

		PPC_Address_T start = (A ? REG_TO_INT(REG(A)) : 0) + imm;
		Core::Bytecode_Type buffer;
		Core::u8 val = (Core::u8)REG_TO_INT(REG(S));

		PPC_TRACE_1("stb", (Core::u32)start);

		Core::Wukong_Get_System().convert_to_bytecode(val, buffer);

		if (MMU::ACCESS_FAULT == 
			GET_MMU().access(Core::Memory_32Bit::MEMORY_WRITE, start, 1, buffer))
			PPC_TRACE_RETURN("mmu access fault!\n");
	}

	PPC_INSTRUCTION_IMPL(op_stbu)
	{
		PPC_s32 S, A;
		PPC_u32 imm;

		D_Form_Parser::parse_simm (instr, S, A, imm);

		PPC_ASSERT(A != 0);

		PPC_Address_T start = REG_TO_INT(REG(A)) + imm;
		Core::Bytecode_Type buffer;
		Core::u8 val = (Core::u8)REG_TO_INT(REG(S));

		PPC_TRACE_1("stbu", (Core::u32)start);

		Core::Wukong_Get_System().convert_to_bytecode(val, buffer);

		if (MMU::ACCESS_FAULT == GET_MMU().access(Core::Memory_32Bit::MEMORY_WRITE, start, 1, buffer))
			PPC_TRACE_RETURN("mmu access fault!\n");

		REG(A).convert_from_int(REG_TO_INT(REG(A)) + imm);
	}

	PPC_INSTRUCTION_IMPL(op_stbux)
	{
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		PPC_ASSERT(A != 0);

		PPC_Address_T start = REG_TO_INT(REG(A)) + REG_TO_INT(REG(B));
		Core::Bytecode_Type buffer;
		Core::u8 val = (Core::u8)REG_TO_INT(REG(S));
        
		PPC_TRACE_1("stbux", (Core::u32)start);
        
		Core::Wukong_Get_System().convert_to_bytecode(val, buffer);
        
		if (MMU::ACCESS_FAULT == GET_MMU().access(Core::Memory_32Bit::MEMORY_WRITE, start, 1, buffer))
            PPC_TRACE_RETURN("mmu access fault!\n");

		REG(A).convert_from_int(REG_TO_INT(REG(A)) + REG_TO_INT(REG(B)));
	}

	PPC_INSTRUCTION_IMPL(op_stbx)
	{
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		PPC_Address_T start = (A? REG_TO_INT(REG(A)) : 0) + REG_TO_INT(REG(B));
		Core::Bytecode_Type buffer;
		Core::u8 val = (Core::u8)REG_TO_INT(REG(S));

        PPC_TRACE_1("stbx", (Core::u32)start);

		Core::Wukong_Get_System().convert_to_bytecode(val, buffer);
            
		if (MMU::ACCESS_FAULT == GET_MMU().access(Core::Memory_32Bit::MEMORY_WRITE, start, 1, buffer))
			PPC_TRACE_RETURN("mmu access fault!\n");
	}

	PPC_INSTRUCTION_IMPL(op_sth)
	{
		PPC_s32 S, A;
		PPC_u32 imm;

		D_Form_Parser::parse_simm (instr, S, A, imm);

		PPC_Address_T start = (A ? REG_TO_INT(REG(A)) : 0) + imm;
		Core::Bytecode_Type buffer;
		Core::u16 val = (Core::u16)REG_TO_INT(REG(S));

        PPC_TRACE_1("sth", (Core::u32)start);
        
		Core::Wukong_Get_System().convert_to_bytecode(val, buffer);
        
		if( MMU::ACCESS_FAULT == GET_MMU().access(Core::Memory_32Bit::MEMORY_WRITE, start, 2, buffer))
            PPC_TRACE_RETURN("mmu access fault!\n");
	}

	PPC_INSTRUCTION_IMPL(op_sthu)
	{
		PPC_s32 S, A;
		PPC_u32 imm;

		D_Form_Parser::parse_simm (instr, S, A, imm);

		PPC_ASSERT(A != 0);

		PPC_Address_T start = REG_TO_INT(REG(A)) + imm;
		Core::Bytecode_Type buffer;
		Core::u16 val = (Core::u16)REG_TO_INT(REG(S));

        PPC_TRACE_1("sthu", (Core::u32)start);
        
		Core::Wukong_Get_System().convert_to_bytecode(val, buffer);
        
		if (MMU::ACCESS_FAULT == GET_MMU().access(Core::Memory_32Bit::MEMORY_WRITE, start, 2, buffer))
            PPC_TRACE_RETURN("mmu access fault!\n");

		REG(A).convert_from_int(REG_TO_INT(REG(A)) + imm);
	}

	PPC_INSTRUCTION_IMPL(op_sthux)
	{
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		PPC_ASSERT(A != 0);

		PPC_Address_T start = REG_TO_INT(REG(A)) + REG_TO_INT(REG(B));
		Core::Bytecode_Type buffer;
		Core::u16 val = (Core::u16)REG_TO_INT(REG(S));

        PPC_TRACE_1("sthux", (Core::u32)start);
        
		Core::Wukong_Get_System().convert_to_bytecode(val, buffer);
        
		if (MMU::ACCESS_FAULT == GET_MMU().access(Core::Memory_32Bit::MEMORY_WRITE, start, 2, buffer))
            PPC_TRACE_RETURN("mmu access fault!\n");

		REG(A).convert_from_int(REG_TO_INT(REG(A)) + REG_TO_INT(REG(B)));
	}

	PPC_INSTRUCTION_IMPL(op_sthx)
	{
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		PPC_Address_T start = (A? REG_TO_INT(REG(A)) : 0) + REG_TO_INT(REG(B));
		Core::Bytecode_Type buffer;
		Core::u16 val = (Core::u16)REG_TO_INT(REG(S));

        PPC_TRACE_1("sthx", (Core::u32)start);
        
		Core::Wukong_Get_System().convert_to_bytecode(val, buffer);

        if(MMU::ACCESS_FAULT == GET_MMU().access(Core::Memory_32Bit::MEMORY_WRITE, start, 2, buffer))
            PPC_TRACE_RETURN("mmu access fault!\n");
	}

	PPC_INSTRUCTION_IMPL(op_stw)
	{
		PPC_s32 S, A;
		PPC_u32 imm;

		D_Form_Parser::parse_simm (instr, S, A, imm);

		PPC_Address_T start = (A ? REG_TO_INT(REG(A)) : 0) + imm;
		Core::Bytecode_Type buffer;
		Core::u32 val = (Core::u32)REG_TO_INT(REG(S));

        PPC_TRACE_1("stw", (Core::u32)start);
        
		Core::Wukong_Get_System().convert_to_bytecode(val, buffer);

        if( MMU::ACCESS_FAULT == GET_MMU().access(Core::Memory_32Bit::MEMORY_WRITE, start, 4, buffer))
            PPC_TRACE_RETURN("mmu access fault!\n");
	}

	PPC_INSTRUCTION_IMPL(op_stwu)
	{
		PPC_s32 S, A;
		PPC_u32 imm;

		D_Form_Parser::parse_simm (instr, S, A, imm);
        
		PPC_ASSERT(A != 0);

		PPC_Address_T start = REG_TO_INT(REG(A)) + imm;
		Core::Bytecode_Type buffer;
		Core::u32 val = (Core::u32)REG_TO_INT(REG(S));

        PPC_TRACE_1("stwu", (Core::u32)start);
        
		Core::Wukong_Get_System().convert_to_bytecode(val, buffer);
        
		if (MMU::ACCESS_FAULT == GET_MMU().access(Core::Memory_32Bit::MEMORY_WRITE, start, 4, buffer))
            PPC_TRACE_RETURN("mmu access fault!\n");

		REG(A).convert_from_int(REG_TO_INT(REG(A)) + imm);
	}

	PPC_INSTRUCTION_IMPL(op_stwux)
	{
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		PPC_ASSERT(A != 0);

		PPC_Address_T start = REG_TO_INT(REG(A)) + REG_TO_INT(REG(B));
		Core::Bytecode_Type buffer;
		Core::u32 val = (Core::u32)REG_TO_INT(REG(S));

        PPC_TRACE_1("stwux", (Core::u32)start);
        
		Core::Wukong_Get_System().convert_to_bytecode(val, buffer);

        if (MMU::ACCESS_FAULT == GET_MMU().access(Core::Memory_32Bit::MEMORY_WRITE, start, 4, buffer))
            PPC_TRACE_RETURN("mmu access fault!\n");

		REG(A).convert_from_int(REG_TO_INT(REG(A)) + REG_TO_INT(REG(B)));
	}

	PPC_INSTRUCTION_IMPL(op_stwx)
	{
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		PPC_Address_T start = (A? REG_TO_INT(REG(A)) : 0) + REG_TO_INT(REG(B));
		Core::Bytecode_Type buffer;
		Core::u32 val = (Core::u32)REG_TO_INT(REG(S));

        PPC_TRACE_1("stwx", (Core::u32)start);
        
		Core::Wukong_Get_System().convert_to_bytecode(val, buffer);

        if (MMU::ACCESS_FAULT == GET_MMU().access(Core::Memory_32Bit::MEMORY_WRITE, start, 4, buffer))
            PPC_TRACE_RETURN("mmu access fault!\n");
	}

	PPC_INSTRUCTION_IMPL(op_sthbrx)
	{
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		PPC_Address_T start = (A? REG_TO_INT(REG(A)) : 0) + REG_TO_INT(REG(B));
		Core::Bytecode_Type buffer;
		Core::u16 val = (Core::u16)REG_TO_INT(REG(S));

        PPC_TRACE_1("sthbrx", (Core::u32)start);
        
		Core::Wukong_Get_System().convert_to_bytecode(val, buffer);

        if (MMU::ACCESS_FAULT == GET_MMU().access(Core::Memory_32Bit::MEMORY_WRITE, start, 2, buffer))
            PPC_TRACE_RETURN("mmu access fault!\n");
	}

	PPC_INSTRUCTION_IMPL(op_stwbrx)
	{
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		PPC_Address_T start = (A? REG_TO_INT(REG(A)) : 0) + REG_TO_INT(REG(B));
		Core::Bytecode_Type buffer;
		Core::u32 val = (Core::u32)REG_TO_INT(REG(S));

        PPC_TRACE_1("stwbrx", (Core::u32)start);
        
		Core::Wukong_Get_System().convert_to_bytecode(val, buffer);
        
		if (MMU::ACCESS_FAULT == GET_MMU().access(Core::Memory_32Bit::MEMORY_WRITE, start, 4, buffer))
            PPC_TRACE_RETURN("mmu access fault!\n");
	}

	PPC_INSTRUCTION_IMPL(op_stmw)
	{
		PPC_TRACE("stmw\n");
		PPC_s32 S, A;
		PPC_u32 imm;

		D_Form_Parser::parse_simm (instr, S, A, imm);

		PPC_Address_T ea = (A? REG_TO_INT(REG(A)) : 0) + imm;
		Core::Bytecode_Type buffer;
		Core::u32 val;

		if (ea % 4 != 0) {
			PPC_ERROR(("stmw: address's not multiple of 4. DSI exception may be caused.\n" 
				"But only warning here. Result value undefined\n"));
		}

		
		while (S <= 31) {
			val = (Core::u32)REG_TO_INT(REG(S));
			Core::Wukong_Get_System().convert_to_bytecode(val, buffer);

			if (MMU::ACCESS_FAULT == GET_MMU().access(Core::Memory_32Bit::MEMORY_WRITE, ea, 4, buffer))
                PPC_TRACE_RETURN("mmu access fault!\n");

			S++;
			ea += 4;
		}
	}

	PPC_INSTRUCTION_IMPL(op_stswi)
	{
		PPC_TRACE("stswi\n");
		PPC_s32 S, A, NB;
		X_Form_Parser::parse_x(instr, S, A, NB);

		if ( 0 == NB )
			NB = 32;

		PPC_Address_T ea = (A? REG_TO_INT(REG(A)) : 0);

		// Temp register value (32bits)
		PPC_u32 r = 0;

		// Bytes per word
		size_t bpw = 0;

		// Temp byte value (8bits)
		Core::u8 b;
		Core::Bytecode_Type buffer;

		while (NB > 0) {
			// A word complete
			if (bpw == 0) {
				r = REG_TO_INT(REG(S));
				S = (S + 1) % 32;
				bpw = 4;
			}

			b = (Core::u8)(r >> 24);
			Core::Wukong_Get_System().convert_to_bytecode(b, buffer);

			if (GET_MMU().access(Core::Memory_32Bit::MEMORY_WRITE, ea, 1, buffer) == MMU::ACCESS_FAULT)
                PPC_TRACE_RETURN("mmu access fault!\n");
			
			r <<= 8;
			ea++;
			bpw--;
			NB--;
		}
	}

	PPC_INSTRUCTION_IMPL(op_stswx)
	{
		PPC_TRACE("stswx\n");
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		int NB = Reg_Flag::XER_N(REG_TO_INT(REG(XER)));

		PPC_Address_T ea = (A? REG_TO_INT(REG(A)) : 0) + REG_TO_INT(REG(B));

		// Temp register value (32bits)
		PPC_u32 r = 0;

		// Bytes per word
		size_t bpw = 0;

		// Temp byte value (8bits)
		Core::u8 b;
		Core::Bytecode_Type buffer;

		while (NB > 0) {
			// A word complete
			if (bpw == 0) {
				r = REG_TO_INT(REG(S));
				S = (S + 1) % 32;
				bpw = 4;
			}

			b = (Core::u8)(r >> 24);
			Core::Wukong_Get_System().convert_to_bytecode(b, buffer);

			if (GET_MMU().access(Core::Memory_32Bit::MEMORY_WRITE, ea, 1, buffer) == MMU::ACCESS_FAULT)
                PPC_TRACE_RETURN("mmu access fault!\n");

			r <<= 8;
			ea++;
			bpw--;
			NB--;
		}
	}

} //namespace PPC

⌨️ 快捷键说明

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