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

📄 integer_logical_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    Processor/PPC/Integer_Shift_Instruction.cpp
 *
 *  $Id: Integer_Logical_Instruction.cpp,v 1.1 2005/06/16 06:01:47 qilj Exp $
 *
 *  \author  Wei He <hwzd1997@163.com>
 *
 */
//=============================================================================
#include "Instruction.h"
#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"

namespace PPC {

	// AND
	PPC_INSTRUCTION_IMPL(op_andx){
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		PPC_TRACE_3("andx", S, A, B);

		//REG(A) = REG(S) & REG(B)
		REG(A).convert_from_int(REG_TO_INT(REG(S)) & REG_TO_INT(REG(B)));

		if (instr & Op_Flag::RC) {
			REG_UPDATE_CR0 (REG(A));
		}
	
	}


	// AND with Complement
	PPC_INSTRUCTION_IMPL(op_andcx){
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		PPC_TRACE_3("andcx", S, A, B);

		//REG(A) = REG(S) & ~ REG(B)
		REG(A).convert_from_int( REG_TO_INT(REG(S)) \
			&  ~REG_TO_INT(REG(B)));

		if (instr & Op_Flag::RC) {
			REG_UPDATE_CR0 (REG(A));
		}
	
	}


	// AND Immediate
	PPC_INSTRUCTION_IMPL(op_andi_)
	{
		PPC_s32 S, A;
		PPC_u32 imm;
		D_Form_Parser::parse_uimm(instr, S, A, imm);

		PPC_TRACE_3("andi_", S, A, imm);

		//REG(A) = REG(S) & imm;
		REG(A).convert_from_int(REG_TO_INT(REG(S)) & imm );
		REG_UPDATE_CR0 (REG(A));
	}

	//AND Immediate Shifted
	PPC_INSTRUCTION_IMPL(op_andis_)
	{
		PPC_s32 S, A;
		PPC_u32 imm;
		D_Form_Parser::parse_shift16(instr, S, A, imm);

		PPC_TRACE_3("andis_", S, A, imm);

		//REG(A) = REG(S) & imm;
		REG(A).convert_from_int(REG_TO_INT(REG(S)) & imm );
		REG_UPDATE_CR0 (REG(A));
	
	}


	// Count Leading Zeros Word
	PPC_INSTRUCTION_IMPL(op_cntlzwx){
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		PPC_TRACE_3("cntlzwx", S, A, B);

		PPC_ASSERT(B == 0);
		PPC_u32 n = 0;
		PPC_u32 x=0x80000000;
		PPC_u32 v = REG_TO_INT(REG(S));

		while (!(v & x)) {
			n++;
			if (n==32) break;
			x>>=1;
		}
		//REG(A) = n;
		REG(A).convert_from_int(n);
		if (instr & Op_Flag::RC) {
			REG_UPDATE_CR0 (REG(A));
		}
	
	}


	// Equivalent
	PPC_INSTRUCTION_IMPL(op_eqvx){
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		PPC_TRACE_3("eqvx", S, A, B);

		//REG(A) = ~(REG(S) ^ REG(B))
		REG(A).convert_from_int( ~(REG_TO_INT(REG(S)) \
			^ REG_TO_INT(REG(B))));

		if (instr & Op_Flag::RC) {
			REG_UPDATE_CR0 (REG(A));
		}
	
	}


	// Extend Sign Byte
	PPC_INSTRUCTION_IMPL(op_extsbx){
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		PPC_TRACE_3("extsbx", S, A, B);

		PPC_ASSERT(B == 0);
		//REG(A) = REG(S)
		REG(A).convert_from_int(REG_TO_INT(REG(S)));

		if(REG_TO_INT(REG(A)) & 0x80){
			REG(A).convert_from_int(REG_TO_INT(REG(A)) | 0xffffff00);
		}else{
			REG(A).convert_from_int(REG_TO_INT(REG(A)) & ~0xffffff00);
		}
		if (instr & Op_Flag::RC) {
			REG_UPDATE_CR0 (REG(A));
		}
	
	}


	// Extend Sign Half Word
	PPC_INSTRUCTION_IMPL(op_extshx)
	{
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		PPC_TRACE_3("extshx", S, A, B);

		PPC_ASSERT(B == 0);
		//REG(A) = REG(S)
		REG(A).convert_from_int(REG_TO_INT(REG(S)));

		if(REG_TO_INT(REG(A)) & 0x8000){
			REG(A).convert_from_int(REG_TO_INT(REG(A)) | 0xffff0000);
		}else{
			REG(A).convert_from_int(REG_TO_INT(REG(A)) & ~0xffff0000);
		}
		if (instr & Op_Flag::RC) {
			REG_UPDATE_CR0 (REG(A));
		}	
	}



	// NAND
	PPC_INSTRUCTION_IMPL(op_nandx){
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		PPC_TRACE_3("nandx", S, A, B);

		//REG(A) = ~(REG(S) & REG(B))
		REG(A).convert_from_int( ~(REG_TO_INT(REG(S)) \
			& REG_TO_INT(REG(B))));

		if (instr & Op_Flag::RC) {
			REG_UPDATE_CR0 (REG(A));
		}
	
	}


	//NOR
	PPC_INSTRUCTION_IMPL(op_norx){
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		PPC_TRACE_3("norx", S, A, B);

		//REG(A) = ~((REG(S) | REG(B))
		REG(A).convert_from_int( ~(REG_TO_INT(REG(S)) \
			| REG_TO_INT(REG(B))));

		if (instr & Op_Flag::RC) {
			REG_UPDATE_CR0 (REG(A));
		}
	
	}

	//OR
	PPC_INSTRUCTION_IMPL(op_orx){
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		PPC_TRACE_3("orx", S, A, B);

		//REG(A) = REG(S) | REG(B)
		REG(A).convert_from_int( REG_TO_INT(REG(S)) \
			| REG_TO_INT(REG(B)));

		if (instr & Op_Flag::RC) {
			REG_UPDATE_CR0 (REG(A));
		}
	
	}



	//OR with Complement
	PPC_INSTRUCTION_IMPL(op_orcx){
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		PPC_TRACE_3("orcx", S, A, B);

		//REG(A) = REG(S) | ~REG(B)
		REG(A).convert_from_int( REG_TO_INT(REG(S)) \
			| ~REG_TO_INT(REG(B)));

		if (instr & Op_Flag::RC) {
			REG_UPDATE_CR0 (REG(A));
		}
	
	}


	//OR Immediate
	PPC_INSTRUCTION_IMPL(op_ori)
	{
		PPC_s32 S, A;
		PPC_u32 imm;
		D_Form_Parser::parse_uimm(instr, S, A, imm);

		PPC_TRACE_3("ori", S, A, imm);

		//REG(A) = REG(S) | imm
		REG(A).convert_from_int(REG_TO_INT(REG(S)) | imm );
	
	}


	//OR Immediate Shifted
	PPC_INSTRUCTION_IMPL(op_oris)
	{
		PPC_s32 S, A;
		PPC_u32 imm;
		D_Form_Parser::parse_shift16(instr, S, A, imm);

		PPC_TRACE_3("oris", S, A, imm);

		//REG(A) = REG(S) | imm
		REG(A).convert_from_int(REG_TO_INT(REG(S)) | imm );
	
	}


	// XOR
	PPC_INSTRUCTION_IMPL(op_xorx){
		PPC_s32 S, A, B;
		X_Form_Parser::parse_x(instr, S, A, B);

		PPC_TRACE_3("xorx", S, A, B);

		//REG(A) = REG(S) ^ REG(B)
		REG(A).convert_from_int( REG_TO_INT(REG(S)) \
			^ REG_TO_INT(REG(B)));

		if (instr & Op_Flag::RC) {
			REG_UPDATE_CR0 (REG(A));
		}
	
	}

	//XOR Immediate
	PPC_INSTRUCTION_IMPL(op_xori)
	{
		PPC_s32 S, A;
		PPC_u32 imm;
		D_Form_Parser::parse_uimm(instr, S, A, imm);

		PPC_TRACE_3("xori", S, A, imm);

		//REG(A) = REG(S) ^ imm;
		REG(A).convert_from_int(REG_TO_INT(REG(S)) ^ imm );
	
	}

	//XOR Immediate Shifted
	PPC_INSTRUCTION_IMPL(op_xoris)
	{
		PPC_s32 S, A;
		PPC_u32 imm;
		D_Form_Parser::parse_shift16(instr, S, A, imm);

		PPC_TRACE_3("xoris", S, A, imm);

		//REG(A) = REG(S) ^ imm
		REG(A).convert_from_int(REG_TO_INT(REG(S)) ^ imm );
	}




} //namespace PPC

⌨️ 快捷键说明

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