ARMv5 additions to ARM7

This commit is contained in:
trap15 2017-02-10 22:16:10 -08:00
parent 4a7f62957b
commit 976647a292
4 changed files with 131 additions and 14 deletions

View File

@ -655,6 +655,7 @@ void arm7_cpu_device::execute_run()
insn = m_direct->read_dword(raddr);
int op_offset = 0;
/* process condition codes for this instruction */
if ((insn >> INSN_COND_SHIFT) != COND_AL)
{
@ -717,13 +718,17 @@ void arm7_cpu_device::execute_run()
{ UNEXECUTED(); goto skip_exec; }
break;
case COND_NV:
{ UNEXECUTED(); goto skip_exec; }
if (m_archRev < 5)
{ UNEXECUTED(); goto skip_exec; }
else
op_offset = 0x10;
break;
}
}
/*******************************************************************/
/* If we got here - condition satisfied, so decode the instruction */
/*******************************************************************/
(this->*ops_handler[((insn & 0xF000000) >> 24)])(insn);
(this->*ops_handler[((insn & 0xF000000) >> 24) + op_offset])(insn);
}
skip_exec:

View File

@ -126,7 +126,7 @@ protected:
void HandleCoProcDO(uint32_t insn);
void HandleCoProcRT(uint32_t insn);
void HandleCoProcDT(uint32_t insn);
void HandleBranch(uint32_t insn);
void HandleBranch(uint32_t insn, bool h_bit);
void HandleMemSingle(uint32_t insn);
void HandleHalfWordDT(uint32_t insn);
void HandleSwap(uint32_t insn);
@ -136,6 +136,7 @@ protected:
void HandleSMulLong(uint32_t insn);
void HandleUMulLong(uint32_t insn);
void HandleMemBlock(uint32_t insn);
void arm7ops_0123(uint32_t insn);
void arm7ops_4567(uint32_t insn);
void arm7ops_89(uint32_t insn);
@ -143,6 +144,15 @@ protected:
void arm7ops_cd(uint32_t insn);
void arm7ops_e(uint32_t insn);
void arm7ops_f(uint32_t insn);
void arm9ops_undef(uint32_t insn);
void arm9ops_1(uint32_t insn);
void arm9ops_57(uint32_t insn);
void arm9ops_89(uint32_t insn);
void arm9ops_ab(uint32_t insn);
void arm9ops_c(uint32_t insn);
void arm9ops_e(uint32_t insn);
void set_cpsr(uint32_t val);
bool arm7_tlb_translate(offs_t &addr, int flags);
uint32_t arm7_tlb_get_second_level_descriptor( uint32_t granularity, uint32_t first_desc, uint32_t vaddr );
@ -268,7 +278,7 @@ protected:
static const arm7thumb_ophandler thumb_handler[0x40*0x10];
typedef void ( arm7_cpu_device::*arm7ops_ophandler )(uint32_t);
static const arm7ops_ophandler ops_handler[0x10];
static const arm7ops_ophandler ops_handler[0x20];
//
// DRC

View File

@ -172,14 +172,19 @@ static void WriteRegisterOperand1( std::ostream &stream, uint32_t opcode )
} /* WriteRegisterOperand */
static void WriteBranchAddress( std::ostream &stream, uint32_t pc, uint32_t opcode )
static void WriteBranchAddress( std::ostream &stream, uint32_t pc, uint32_t opcode, bool h_bit )
{
opcode &= 0x00ffffff;
if( opcode&0x00800000 )
opcode <<= 2;
if (h_bit && (opcode & 0x04000000))
{
opcode |= 0xff000000; /* sign-extend */
opcode |= 2;
}
pc += 8+4*opcode;
opcode &= 0x03fffffe;
if( opcode & 0x02000000 )
{
opcode |= 0xfc000000; /* sign-extend */
}
pc += 8+opcode;
util::stream_format( stream, "$%x", pc );
} /* WriteBranchAddress */
@ -205,7 +210,18 @@ static uint32_t arm7_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode
pConditionCode= pConditionCodeTable[opcode>>28];
if( (opcode&0x0ffffff0)==0x012fff10 ) { //bits 27-4 == 000100101111111111110001
if( (opcode&0xfe000000)==0xfa000000 ) //bits 31-25 == 1111 101 (BLX - v5)
{
/* BLX */
util::stream_format( stream, "BLX" );
dasmflags = DASMFLAG_STEP_OVER;
WritePadding(stream, start_position);
WriteBranchAddress( stream, pc, opcode, true );
}
else if( (opcode&0x0ffffff0)==0x012fff10 ) //bits 27-4 == 000100101111111111110001
{
/* Branch and Exchange (BX) */
util::stream_format( stream, "B");
util::stream_format( stream, "%sX", pConditionCode );
@ -636,7 +652,7 @@ static uint32_t arm7_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode
WritePadding(stream, start_position);
WriteBranchAddress( stream, pc, opcode );
WriteBranchAddress( stream, pc, opcode, false );
}
else if( (opcode&0x0e000000)==0x0c000000 ) //bits 27-25 == 110
{

View File

@ -378,9 +378,14 @@ void arm7_cpu_device::HandleCoProcDT(uint32_t insn)
SetRegister(rn, ornv);
}
void arm7_cpu_device::HandleBranch(uint32_t insn)
void arm7_cpu_device::HandleBranch(uint32_t insn, bool h_bit)
{
uint32_t off = (insn & INSN_BRANCH) << 2;
if (h_bit)
{
// H goes to bit1
off |= (insn & 0x01000000) >> 23;
}
/* Save PC into LR if this is a branch with link */
if (insn & INSN_BL)
@ -1519,14 +1524,95 @@ void arm7_cpu_device::HandleMemBlock(uint32_t insn)
} /* HandleMemBlock */
const arm7_cpu_device::arm7ops_ophandler arm7_cpu_device::ops_handler[0x10] =
const arm7_cpu_device::arm7ops_ophandler arm7_cpu_device::ops_handler[0x20] =
{
&arm7_cpu_device::arm7ops_0123, &arm7_cpu_device::arm7ops_0123, &arm7_cpu_device::arm7ops_0123, &arm7_cpu_device::arm7ops_0123,
&arm7_cpu_device::arm7ops_4567, &arm7_cpu_device::arm7ops_4567, &arm7_cpu_device::arm7ops_4567, &arm7_cpu_device::arm7ops_4567,
&arm7_cpu_device::arm7ops_89, &arm7_cpu_device::arm7ops_89, &arm7_cpu_device::arm7ops_ab, &arm7_cpu_device::arm7ops_ab,
&arm7_cpu_device::arm7ops_cd, &arm7_cpu_device::arm7ops_cd, &arm7_cpu_device::arm7ops_e, &arm7_cpu_device::arm7ops_f,
&arm7_cpu_device::arm9ops_undef,&arm7_cpu_device::arm9ops_1, &arm7_cpu_device::arm9ops_undef,&arm7_cpu_device::arm9ops_undef,
&arm7_cpu_device::arm9ops_undef,&arm7_cpu_device::arm9ops_57, &arm7_cpu_device::arm9ops_undef,&arm7_cpu_device::arm9ops_57,
&arm7_cpu_device::arm9ops_89, &arm7_cpu_device::arm9ops_89, &arm7_cpu_device::arm9ops_ab, &arm7_cpu_device::arm9ops_ab,
&arm7_cpu_device::arm9ops_c, &arm7_cpu_device::arm9ops_undef,&arm7_cpu_device::arm9ops_e, &arm7_cpu_device::arm9ops_undef,
};
void arm7_cpu_device::arm9ops_undef(uint32_t insn)
{
}
void arm7_cpu_device::arm9ops_1(uint32_t insn)
{
/* Change processor state (CPS) */
if ((insn & 0x00f10020) == 0x00000000)
{
// unsupported (armv6 onwards only)
}
else if ((insn & 0x00ff00f0) == 0x00010000) /* set endianness (SETEND) */
{
// unsupported (armv6 onwards only)
}
else
{
arm9ops_undef(insn);
}
}
void arm7_cpu_device::arm9ops_57(uint32_t insn)
{
/* Cache Preload (PLD) */
if ((insn & 0x0070f000) == 0x0050f000)
{
// unsupported (armv6 onwards only)
}
else
{
arm9ops_undef(insn);
}
}
void arm7_cpu_device::arm9ops_89(uint32_t insn)
{
/* Save Return State (SRS) */
if ((insn & 0x005f0f00) == 0x004d0500)
{
// unsupported (armv6 onwards only)
}
else if ((insn & 0x00500f00) == 0x00100a00) /* Return From Exception (RFE) */
{
// unsupported (armv6 onwards only)
}
else
{
arm9ops_undef(insn);
}
}
void arm7_cpu_device::arm9ops_ab(uint32_t insn)
{
// blx
HandleBranch(insn, true);
}
void arm7_cpu_device::arm9ops_c(uint32_t insn)
{
/* Additional coprocessor double register transfer */
if ((insn & 0x00e00000) == 0x00400000)
{
// unsupported
}
else
{
arm9ops_undef(insn);
}
}
void arm7_cpu_device::arm9ops_e(uint32_t insn)
{
/* Additional coprocessor register transfer */
// unsupported
}
void arm7_cpu_device::arm7ops_0123(uint32_t insn)
{
//case 0:
@ -1824,7 +1910,7 @@ void arm7_cpu_device::arm7ops_ab(uint32_t insn) /* Branch or Branch & Link */
{
//case 0xa:
//case 0xb:
HandleBranch(insn);
HandleBranch(insn, false);
// break;
}