📄 data_process_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/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 + -