📄 data_process_instruction.cpp
字号:
u32 Rd_index = bits.convert_to_int(12,15);
if( Rm_index == 15 || Rn_index== 15 || Rd_index== 15 )
return ;
get_cpu()->read_register(Rn_index, addr);
get_cpu()->read_register(Rm_index, Rm);
switch( addr % 4)
{
case 0:
{
//value = [addr]
//get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr,4,buffer);
if ( (get_cpu()->get_mmu().access(Core::Memory_32Bit::MEMORY_READ, addr, 4, buffer)) == MMU::PAGE_TRANSLATION_FAULT)
{
get_cpu()->on_dataabt_exception();
return;
}
Wukong_Get_System().convert_from_bytecode(buffer,value);
break;
}
case 1:
{
//value = [addr - 1]
//value = value rotate right 8
//get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr-1,4,buffer);
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;
}
Core::Wukong_Get_System().convert_from_bytecode(buffer,value);
this->rotate_right(value,8);
break;
}
case 2:
{
//value = [addr - 2]
//value = value rotate right 16
//get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr-2,4,buffer) ;
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;
}
Core::Wukong_Get_System().convert_from_bytecode(buffer,value);
this->rotate_right(value,16);
break;
}
case 3:
{
//value = [addr - 3]
//value = value rotate right 24
//get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr-3,4,buffer);
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;
}
Core::Wukong_Get_System().convert_from_bytecode(buffer,value);
this->rotate_right(value,24);
break;
}
}
Core::Wukong_Get_System().convert_to_bytecode(Rm, buffer);
addr = addr & 0xfffffffc;
//get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_WRITE,addr,4,buffer);
if ( (get_cpu()->get_mmu().access(Core::Memory_32Bit::MEMORY_WRITE, addr, 4, buffer)) == MMU::PAGE_TRANSLATION_FAULT)
{
get_cpu()->on_dataabt_exception();
return;
}
get_cpu()->write_register(Rd_index,value);
return ;
}
void Data_Process_Instruction::SWPB(Core::Instruction_Unit & binary)
{
Core::Binary_32Bit bits(binary);
Core::Bytecode_Type buffer;
u32 Rm, addr;
u32 Rm_index = bits.convert_to_int(0,3);
u32 Rn_index = bits.convert_to_int(16,19);
u32 Rd_index = bits.convert_to_int(12,15);
u8 value_8,temp;
if( Rm_index == 15 || Rn_index== 15 || Rd_index== 15 )
return ;
get_cpu()->read_register(Rn_index, addr);
get_cpu()->read_register(Rm_index, Rm);
//get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr,1,buffer);
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,temp);
value_8 = (u8)(Rm);
Core::Wukong_Get_System().convert_to_bytecode(value_8, buffer);
//get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_WRITE,addr,1,buffer);
if ( (get_cpu()->get_mmu().access(Core::Memory_32Bit::MEMORY_WRITE, addr, 1, buffer)) == MMU::PAGE_TRANSLATION_FAULT)
{
get_cpu()->on_dataabt_exception();
return;
}
get_cpu()->write_register(Rd_index,temp);
return ;
}
void Data_Process_Instruction::MUL(Core::Instruction_Unit & binary)
{
Core::Binary_32Bit bits(binary);
int Rm_index, Rs_index, Rd_index;
u32 Rm, Rs, Rd;
Rm_index = bits.convert_to_int(0,3);
Rs_index = bits.convert_to_int(8,11);
Rd_index = bits.convert_to_int(16,19);
if( Rm_index == 15 || Rs_index== 15 || Rd_index== 15 )
return ;
get_cpu()->read_register(Rm_index, Rm);
get_cpu()->read_register(Rs_index, Rs);
Rd = static_cast<u32>(Rm * Rs);
get_cpu()->write_register( Rd_index, Rd );
if( bits.test(20) )
{
get_cpu()->get_cpsr().set( 31, Rd>>31 );
if(Rd == 0)
get_cpu()->get_cpsr().set( 30, 1 );
else
get_cpu()->get_cpsr().set( 30, 0 );
}
return ;
}
void Data_Process_Instruction::MLA(Core::Instruction_Unit & binary)
{
Core::Binary_32Bit bits(binary);
int Rm_index, Rs_index , Rn_index, Rd_index;
u32 Rm, Rs, Rd,Rn;
Rm_index = bits.convert_to_int(0,3);
Rs_index = bits.convert_to_int(8,11);
Rn_index = bits.convert_to_int(12,15);
Rd_index = bits.convert_to_int(16,19);
if(Rm_index == 15 || Rs_index== 15 || Rd_index== 15 || Rn_index == 15 )
return ;
get_cpu()->read_register(Rm_index, Rm);
get_cpu()->read_register(Rs_index, Rs);
get_cpu()->read_register(Rn_index, Rn);
Rd = static_cast<u32>(Rm * Rs + Rn);
get_cpu()->write_register( Rd_index, Rd );
if(bits.test(20))
{
get_cpu()->get_cpsr().set( 31, Rd>>31 );
if(Rd == 0)
get_cpu()->get_cpsr().set( 30, 1 );
else
get_cpu()->get_cpsr().set( 30, 0 );
}
return;
}
void Data_Process_Instruction::SMULL(Core::Instruction_Unit & binary)
{
Core::Binary_32Bit bits(binary);
int Rm_index, Rs_index , RdLo_index ,RdHi_index;
u32 Rm, Rs,RdLo,RdHi;
Rm_index = bits.convert_to_int(0,3);
Rs_index = bits.convert_to_int(8,11);
RdLo_index = bits.convert_to_int(12,15);
RdHi_index = bits.convert_to_int(16,19);
if( Rm_index == 15 || Rs_index== 15 || RdLo_index == 15 || RdHi_index == 15 )
return ;
get_cpu()->read_register(Rm_index, Rm);
get_cpu()->read_register(Rs_index, Rs);
RdLo = static_cast<u32>( signed_immed_64( Rm ) * signed_immed_64( Rs ) );
RdHi = static_cast<u32>( ( signed_immed_64( Rm) * signed_immed_64( Rs ) ) >> 32);
get_cpu()->write_register( RdLo_index, RdLo );
get_cpu()->write_register( RdHi_index, RdHi );
if(bits.test(20))
{
get_cpu()->get_cpsr().set( 31, RdHi>>31 );
if( RdHi == 0 && RdLo == 0 )
get_cpu()->get_cpsr().set( 30, 1 );
else
get_cpu()->get_cpsr().set( 30, 0 );
}
return;
}
void Data_Process_Instruction::SMLAL(Core::Instruction_Unit & binary)
{
Core::Binary_32Bit bits(binary);
int Rm_index, Rs_index , RdLo_index ,RdHi_index;
u32 Rm, Rs,RdLo,RdHi;
Rm_index = bits.convert_to_int(0,3);
Rs_index = bits.convert_to_int(8,11);
RdLo_index = bits.convert_to_int(12,15);
RdHi_index = bits.convert_to_int(16,19);
if( Rm_index == 15 || Rs_index== 15 || RdLo_index == 15 || RdHi_index == 15 )
return ;
get_cpu()->read_register(Rm_index, Rm);
get_cpu()->read_register(Rs_index, Rs);
get_cpu()->read_register(RdLo_index, RdLo);
get_cpu()->read_register(RdHi_index, RdHi);
signed long signed_carry;
if ( ( (u64)( static_cast<u32>( signed_immed_64(Rm) * signed_immed_64(Rs) ) ) + (u64)RdLo -
(u32)( static_cast<u32>( signed_immed_64(Rm) * signed_immed_64(Rs) ) + RdLo) ) != 0)
signed_carry=1;
else
signed_carry=0;
// RdLo=(Rm*Rs)[31:0]+RdLo
RdLo = static_cast<u32>( signed_immed_64(Rm) * signed_immed_64(Rs) + signed_immed_64(RdLo) );
// RdHi=(Rm*Rs)[63:32]+RdHi+CarryFrom((Rm*Rs)[31:0]+RdLo)
RdHi =static_cast<u32>( static_cast<u32>( (signed_immed_64(Rm) * signed_immed_64(Rs)) >> 32)
+ RdHi
+ signed_carry );
get_cpu()->write_register( RdLo_index, RdLo );
get_cpu()->write_register( RdHi_index, RdHi );
if(bits.test(20))
{
get_cpu()->get_cpsr().set( 31, RdHi>>31 );
if( RdHi == 0 && RdLo == 0 )
get_cpu()->get_cpsr().set( 30, 1 );
else
get_cpu()->get_cpsr().set( 30, 0 );
}
return;
}
void Data_Process_Instruction::UMULL(Core::Instruction_Unit & binary)
{
Core::Binary_32Bit bits(binary);
int Rm_index, Rs_index , RdLo_index , RdHi_index;
u32 Rm, Rs,RdLo,RdHi;
Rm_index = bits.convert_to_int(0,3);
Rs_index = bits.convert_to_int(8,11);
RdLo_index = bits.convert_to_int(12,15);
RdHi_index = bits.convert_to_int(16,19);
if( Rm_index == 15 || Rs_index== 15 || RdLo_index == 15 || RdHi_index == 15 )
return;
get_cpu()->read_register(Rm_index, Rm);
get_cpu()->read_register(Rs_index, Rs);
RdLo = static_cast<u32>( (u64) Rm * Rs);
RdHi = static_cast<u32>(((u64) Rm * (u64)Rs)>>32);
get_cpu()->write_register( RdLo_index, RdLo );
get_cpu()->write_register( RdHi_index, RdHi );
if(bits.test(20))
{
get_cpu()->get_cpsr().set( 31, RdHi>>31 );
if( RdHi == 0 && RdLo == 0 )
get_cpu()->get_cpsr().set( 30, 1 );
else
get_cpu()->get_cpsr().set( 30, 0 );
}
return;
}
void Data_Process_Instruction::UMLAL(Core::Instruction_Unit & binary)
{
Core::Binary_32Bit bits(binary);
int Rm_index, Rs_index , RdLo_index , RdHi_index;
u32 Rm, Rs,RdLo,RdHi;
Rm_index = bits.convert_to_int(0,3);
Rs_index = bits.convert_to_int(8,11);
RdLo_index = bits.convert_to_int(12,15);
RdHi_index = bits.convert_to_int(16,19);
if( Rm_index == 15 || Rs_index== 15 || RdLo_index == 15 || RdHi_index == 15 )
return;
get_cpu()->read_register(Rm_index, Rm);
get_cpu()->read_register(Rs_index, Rs);
get_cpu()->read_register(RdLo_index, RdLo);
get_cpu()->read_register(RdHi_index, RdHi);
unsigned long carry;
if ( ( (u64)( (u32)( (u64) Rm * (u64) Rs ) ) + (u64)RdLo -
(u32)( Rm * Rs + RdLo) ) != 0)
carry=1;
else
carry=0;
// RdLo=(Rm*Rs)[31:0]+RdLo
RdLo = static_cast<u32>((u64) Rm * (u64) Rs + RdLo);
// RdHi=(Rm*Rs)[63:32]+RdHi+CarryFrom((Rm*Rs)[31:0]+RdLo)
RdHi =static_cast<u32>( static_cast<u32>( ( (u64)Rm * (u64)Rs )>>32 )
+ RdHi
+ carry );
get_cpu()->write_register( RdLo_index, RdLo );
get_cpu()->write_register( RdHi_index, RdHi );
if(bits.test(20))
{
get_cpu()->get_cpsr().set( 31, RdHi>>31 );
if( RdHi == 0 && RdLo == 0 )
get_cpu()->get_cpsr().set( 30, 1 );
else
get_cpu()->get_cpsr().set( 30, 0 );
}
return;
}
//! Multiplication instructions use sign-extend
s64 Data_Process_Instruction::signed_immed_64( u32 & val)
{
if(val >> 31)
{
return ( (s64) val | (s64)0xffffffff00000000);
}
else
{
return ( (s64) val | (s64)0x0000000000000000);
}
}
//CLZ for version5 and above
void Data_Process_Instruction::CLZ(Core::Instruction_Unit & binary)
{
Core::Binary_32Bit bits(binary);
Core::u32 Rm,Rd;
int i;
int Rd_index = bits.convert_to_int(12,15);
int Rm_index = bits.convert_to_int(0,3);
get_cpu()->read_register(Rm_index, Rm);
if( Rm == 0)
get_cpu()->write_register(Rd_index, 32);
else
{
for(i=31; i>=0; i--)
{
if(Rm>>i == 1)
break;
}
Rd = 31 - i;
get_cpu()->write_register(Rd_index, Rd);
}
}
//SMULxy for version5E
void Data_Process_Instruction::SMULxy(Core::Instruction_Unit & binary)
{
Core::Binary_32Bit bits(binary);
Core::u32 op1,op2,Rd;
int op1_index, op2_index ,Rd_index;
op1_index = bits.convert_to_int(0,3);
op2_index = bits.convert_to_int(8,11);
Rd_index = bits.convert_to_int(16,19);
get_cpu()->read_register(op1_index, op1);
get_cpu()->read_register(op2_index, op2);
if ( bits.test (5))
op1 >>= 16;
if ( bits.test(6))
op2 >>= 16;
op1 &= 0xFFFF;
op2 &= 0xFFFF;
if (op1 & 0x8000)
op1 -= 65536;
if (op2 & 0x8000)
op2 -= 65536;
Rd = op1 * op2;
get_cpu()->write_register(Rd_index, Rd);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -