📄 cpsr_instruction.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 + -