📄 ls_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/LS_Instruction.h
*
* $Id: LS_Instruction.cpp,v 1.7 2005/06/08 07:40:45 qilj Exp $
*
* \author Jie Chen <alt_alt@163.com>
*/
//=============================================================================
#include "./LS_Instruction.h"
namespace ARM{
// bool LS_Instruction::test_and_parse(Core::Instruction_Unit & binary)
// {
/*
Core::Binary_32Bit bits(binary);
cond_code_ = (u8)bits.convert_to_int(28, 31);
return true;
*/
// }
DEFINE_SINGLETON(LS_Instruction)
void LS_Instruction::execute(Core::Instruction_Unit binary)
{
Core::Binary_32Bit bits(binary);
u32 opcode1 = bits.convert_to_int(4,7);
u32 opcode2 = bits.convert_to_int(24,24);
opcode2 = (opcode2<<3) + bits.convert_to_int(20,22);
if( bits.test(26) )
switch(opcode2)
{
case 0x9:
return LDR(binary);
case 0x4:
return STRB(binary);
case 0x5:
return LDRB(binary);
case 0x8:
return STR(binary);
case 0xd:
return LDRB(binary);
case 0xc:
return STRB(binary);
case 0x0:
return STR(binary);
case 0x1:
return LDR(binary);
case 0xa:
return STR(binary);
case 0xf:
return LDRB(binary);
case 0xb:
return LDR(binary);
case 0xe:
return STRB(binary);
case 0x2:
//WUKONG_STDOUT<<"STRT\n";
return STRT(binary);
case 0x3:
//WUKONG_STDOUT<<"LDRT\n";
return LDRT(binary);
case 0x6:
//WUKONG_STDOUT<<"STRBT\n";
return STRBT(binary);
case 0x7:
//WUKONG_STDOUT<<"LDRBT\n";
return LDRBT(binary);
}
else
switch(opcode1)
{
case 0xb:
if (bits.test(20))
return LDRH(binary);
else
return STRH(binary);
case 0xd:
return LDRSB(binary);
case 0xf:
return LDRSH(binary);
// default: return UND;
}
}
/* void LS_Instruction::execute(Core::Instruction_Unit binary)
{
Core::Binary_32Bit bits(binary);
u32 opcode = bits.convert_to_int(24,24);
opcode = (opcode<<3) + bits.convert_to_int(20,22);
switch(opcode)
{
case 0x0:
return STR(binary);
case 0x1:
return LDR(binary);
case 0x2:
return STRT(binary);
case 0x3:
return LDRT(binary);
case 0x4:
return STRB(binary);
case 0x5:
return LDRB(binary);
case 0x6:
return STRBT(binary);
case 0x7:
return LDRBT(binary);
case 0x8:
return STR(binary);
case 0x9:
return LDR(binary);
case 0xa:
return STR(binary);
case 0xb:
return LDR(binary);
case 0xc:
return STRB(binary);
case 0xd:
return LDRB(binary);
case 0xe:
return STRB(binary);
case 0xf:
return LDRB(binary);
// default: return UND;
}
//need modify?
}*/
void LS_Instruction::LDR(Core::Instruction_Unit & binary)
{
u32 value;
u32 addr;
u8 addr_tale;
Core::Binary_32Bit bits(binary);
u32 rd_index = bits.convert_to_int(12,15);
this->get_address(binary,addr);
Core::Bytecode_Type buffer;
addr_tale = (u8)(addr % 4);
switch(addr_tale)
{
case 0:
{
//value = [addr]
/*if((error_no = get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr,4,buffer)) != 0);
// Core::Wukong_Get_System() .set_last_error(error_no);
Wukong_Get_System().convert_from_bytecode(buffer,value);
break;*/
if ( (get_cpu()->get_mmu().access(Core::Memory_32Bit::MEMORY_READ, addr, 4, buffer)) == MMU::PAGE_TRANSLATION_FAULT)
{
get_cpu()->on_dataabt_exception();
return;
}
else
Wukong_Get_System().convert_from_bytecode(buffer,value);
break;
}
case 1:
{
//value = [addr - 1]
//value = value rotate right 8
/*if((error_no = get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr-1,4,buffer)) != 0);
// Core::Wukong_Get_System() .set_last_error(error_no);
Core::Wukong_Get_System().convert_from_bytecode(buffer,value);
this->rotate_right(value,8);
break;*/
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;
}
else
Wukong_Get_System().convert_from_bytecode(buffer,value);
this->rotate_right(value,8);
break;
}
case 2:
{
//value = [addr - 2]
//value = value rotate right 16
/*if(error_no = get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr-2,4,buffer) != 0);
// Core::Wukong_Get_System() .set_last_error(error_no);
Core::Wukong_Get_System().convert_from_bytecode(buffer,value);
this->rotate_right(value,16);
break;*/
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;
}
else
Wukong_Get_System().convert_from_bytecode(buffer,value);
this->rotate_right(value,16);
break;
}
case 3:
{
//value = [addr - 3]
//value = value rotate right 24
/*if(error_no = get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr-3,4,buffer) != 0);
// Core::Wukong_Get_System() .set_last_error(error_no);
Core::Wukong_Get_System().convert_from_bytecode(buffer,value);
this->rotate_right(value,24);
break;*/
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;
}
else
Wukong_Get_System().convert_from_bytecode(buffer,value);
this->rotate_right(value,24);
break;
}
}
if(rd_index == 15)
{
this->get_cpu()->write_register(15,value & 0xfffffffe);
Core::Binary_32Bit value_bits(value);
get_cpu()->get_cpsr().set(5,int(value_bits.get(0)));
}
else
this->get_cpu()->write_register(rd_index,value);
}
void LS_Instruction::LDRB(Core::Instruction_Unit & binary)
{
u8 value;
u32 addr,value_32;
Core::Binary_32Bit bits(binary);
u32 rd_index = bits.convert_to_int(12,15);
this->get_address(binary,addr);
Core::Bytecode_Type buffer;
/*if((error_no = get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr,1,buffer)) != 0);
// Core::Wukong_Get_System() .set_last_error(error_no);*/
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,value);
value_32 =u32 (value);
get_cpu()->write_register(rd_index,value_32);
}
void LS_Instruction::LDRBT(Core::Instruction_Unit & binary)
{
u8 value;
u32 addr,value_32;
Core::Binary_32Bit bits(binary);
u32 rd_index = bits.convert_to_int(12,15);//need get usermode register here!
this->get_usermode_address(binary,addr);
Core::Bytecode_Type buffer;
/*if((error_no = get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr,1,buffer)) != 0);
// Core::Wukong_Get_System() .set_last_error(error_no);*/
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,value);
value_32 =u32 (value);
get_cpu()->write_register(rd_index,value_32);
}
void LS_Instruction::LDRH(Core::Instruction_Unit & binary)
{
u32 addr,value_32;
u16 value;
Core::Binary_32Bit bits(binary);
u32 rd_index = bits.convert_to_int(12,15);
this->get_sh_address(binary,addr);
if((addr % 2) == 0)
{
Core::Bytecode_Type buffer;
/*if((error_no = get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr,2,buffer)) != 0);
// Core::Wukong_Get_System() .set_last_error(error_no);*/
if ( (get_cpu()->get_mmu().access(Core::Memory_32Bit::MEMORY_READ, addr, 2, buffer)) == MMU::PAGE_TRANSLATION_FAULT)
{
get_cpu()->on_dataabt_exception();
return;
}
Wukong_Get_System().convert_from_bytecode(buffer,value);
value_32 =u32 (value);
}
else
{
printf("LDRH error!");
//value_32 unpredictable
}
get_cpu()->write_register(rd_index,value_32);
}
void LS_Instruction::LDRSB(Core::Instruction_Unit & binary)
{
u8 value;
u32 addr,value_32;
Core::Binary_32Bit bits(binary);
u32 rd_index = bits.convert_to_int(12,15);
this->get_sh_address(binary,addr);
Core::Bytecode_Type buffer;
/*if((error_no = get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr,1,buffer)) != 0);
// Core::Wukong_Get_System() .set_last_error(error_no);*/
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,value);
//need to opertimise
if(value >= 0x80)
value_32 = 0xffffff00 + u32(value);
else
value_32 = u32(value);
//
get_cpu()->write_register(rd_index,value_32);
}
void LS_Instruction::LDRSH(Core::Instruction_Unit & binary)
{
u32 addr,value_32;
u16 value;
Core::Binary_32Bit bits(binary);
u32 rd_index = bits.convert_to_int(12,15);
this->get_sh_address(binary,addr);
if((addr % 2) == 0)
{
Core::Bytecode_Type buffer;
/*if((error_no = get_cpu()->get_mmu().access(Memory_32Bit::MEMORY_READ,addr,2,buffer)) != 0);
// Core::Wukong_Get_System() .set_last_error(error_no);*/
if ( (get_cpu()->get_mmu().access(Core::Memory_32Bit::MEMORY_READ, addr, 2, buffer)) == MMU::PAGE_TRANSLATION_FAULT)
{
get_cpu()->on_dataabt_exception();
return;
}
Wukong_Get_System().convert_from_bytecode(buffer,value);
//need opertimise here
if(value >= 0x1000)
value_32 = 0xffff0000 + u32(value);
else
value_32 =u32 (value);
}
else
{
printf("LDRH error!");
//value_32 unpredictable
}
get_cpu()->write_register(rd_index,value_32);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -