flycast/core/arm_emitter/arm_disasm.h

196 lines
3.9 KiB
C++

/*
* disasm.h, a horribly static yet (hopefully) correct disassembler
*
*/
#pragma once
namespace ARM
{
inline static void armdis_cc(u32 cond, char *ccbuff) // Length is always 8 for our static'{n,m}ess
{
switch(cond)
{
case EQ: sprintf(ccbuff, "EQ"); return;
case NE: sprintf(ccbuff, "NE"); return;
case CS: sprintf(ccbuff, "CS"); return;
case CC: sprintf(ccbuff, "CC"); return;
case MI: sprintf(ccbuff, "MI"); return;
case PL: sprintf(ccbuff, "PL"); return;
case VS: sprintf(ccbuff, "VS"); return;
case VC: sprintf(ccbuff, "VC"); return;
case HI: sprintf(ccbuff, "HI"); return;
case LS: sprintf(ccbuff, "LS"); return;
case GE: sprintf(ccbuff, "GE"); return;
case LT: sprintf(ccbuff, "LT"); return;
case GT: sprintf(ccbuff, "GT"); return;
case LE: sprintf(ccbuff, "LE"); return;
case AL: return; // sprintf(ccbuff, "AL"); -- ALways doesn't need to be specified
case UC: //
default: return; // DIE
}
}
inline static void armdis_dp(u32 dpop, char *dpbuff) // Length is always 8 ...
{
switch(dpop)
{
case DP_AND: sprintf(dpbuff, "AND"); return;
case DP_EOR: sprintf(dpbuff, "EOR"); return;
case DP_SUB: sprintf(dpbuff, "SUB"); return;
case DP_RSB: sprintf(dpbuff, "RSB"); return;
case DP_ADD: sprintf(dpbuff, "ADD"); return;
case DP_ADC: sprintf(dpbuff, "ADC"); return;
case DP_SBC: sprintf(dpbuff, "SBC"); return;
case DP_RSC: sprintf(dpbuff, "RSC"); return;
case DP_TST: sprintf(dpbuff, "TST"); return;
case DP_TEQ: sprintf(dpbuff, "TEQ"); return;
case DP_CMP: sprintf(dpbuff, "CMP"); return;
case DP_CMN: sprintf(dpbuff, "CMN"); return;
case DP_ORR: sprintf(dpbuff, "ORR"); return;
case DP_MOV: sprintf(dpbuff, "MOV"); return;
case DP_BIC: sprintf(dpbuff, "BIC"); return;
case DP_MVN: sprintf(dpbuff, "MVN"); return;
}
}
inline static void armdis(u32 op, char *disbuf, u32 len=512)
{
char ipref[8]={0}, isuff[8]={0}, icond[8]={0} ;
// u32 uOP = ((op>>12)&0xFF00) | ((op>>4)&255) ;
u32 uCC = ((op>>28) & 0x0F) ; //
u32 uO1 = ((op>>25) & 0x07) ; //
u32 uO2 = ((op>> 4) & 0x01) ; //
u32 uC1 = ((op>>21) & 0x0F) ; //
u32 uC2 = ((op>> 5) & 0x07) ; //
u32 uSB = ((op>>20) & 0x01) ; // Sign Change Bit
if (uCC == UC) {
printf ("DBG armdis has UC instruction %X\n", op);
sprintf (disbuf, "UNCONDITIONAL / UNHANDLED INSTRUCTION");
return;
}
if (uCC != AL) {
armdis_cc(uCC,isuff);
}
if (uO1 == 0)
{
if (uO2 == 0) {
if ((uC1 & 0xC) == 8) {
printf ("DBG armdis 0:0 10xx misc instruction \n", uCC);
sprintf (disbuf, "UNHANDLED INSTRUCTION 0:");
return;
}
// DP imm.shift
}
else if (uO2 == 1) {
sprintf (disbuf, "UNHANDLED INSTRUCTION 0:");
}
}
else if (uO1 == 1) {
sprintf (disbuf, "UNHANDLED INSTRUCTION 1:");
}
else if (uO1 == 2) {
sprintf (disbuf, "UNHANDLED INSTRUCTION 2:");
}
else if (uO1 == 3) {
sprintf (disbuf, "UNHANDLED INSTRUCTION 3:");
}
else if (uO1 == 4) {
sprintf (disbuf, "UNHANDLED INSTRUCTION 4:");
}
else if (uO1 == 5) {
sprintf (disbuf, "UNHANDLED INSTRUCTION 5:");
}
else if (uO1 == 6) {
sprintf (disbuf, "UNHANDLED INSTRUCTION 6:");
}
else if (uO1 == 7) {
sprintf (disbuf, "UNHANDLED INSTRUCTION 7:");
}
else if (uO1 == 8) {
sprintf (disbuf, "UNHANDLED INSTRUCTION 8:");
}
else if (uO1 == 9) {
sprintf (disbuf, "UNHANDLED INSTRUCTION 9:");
}
else if (uO1 == 10) {
sprintf (disbuf, "UNHANDLED INSTRUCTION 10:");
}
else if (uO1 == 11) {
sprintf (disbuf, "UNHANDLED INSTRUCTION 11:");
}
else if (uO1 == 12) {
sprintf (disbuf, "UNHANDLED INSTRUCTION 12:");
}
else if (uO1 == 13) {
sprintf (disbuf, "UNHANDLED INSTRUCTION 13:");
}
else if (uO1 == 14) {
sprintf (disbuf, "UNHANDLED INSTRUCTION 14:");
}
else if (uO1 == 15) {
sprintf (disbuf, "UNHANDLED INSTRUCTION 15:");
}
else {
sprintf (disbuf, "INVALID INSTRUCTION");
}
}
};