www.pudn.com > potemkin_sourceforPSP.rar > THUMBDataProcessing.cpp
#include "stdafx.h"
#include "../../Globals.h"
#include "ARM.h"
#include "ARMCompiler.h"
#include "ARMTables.h"
#include "ARMAnalyst.h"
#include "../IR/IR.h"
#include "../MemMap.h"
#include "THUMBDataProcessing.h"
//////////////////////////////////////////////////////////////////////////
// THUMB
//////////////////////////////////////////////////////////////////////////
namespace THUMBInstructions
{
void Comp_2Op_T(u16 op, IROpID opid)
{
InstructionInfo &info = CurrentAnalysis();
int rd = op&7;
int rm = (op>>3)&7;
IR_Add(opid,info.flagsOut,rd,IRRegT(rd),IRRegT(rm));
}
void Comp_2OpNoOut_T(u16 op, IROpID opid)
{
InstructionInfo &info = CurrentAnalysis();
int rm = op&7;
int rn = (op>>3)&7;
IR_Add(opid,info.flagsOut,0,IRRegT(rm),IRRegT(rn));
}
void Comp_1Op_T(u16 op, IROpID opid)
{
InstructionInfo &info = CurrentAnalysis();
int rd = op&7;
int rn = (op>>3)&7;
IR_Add(opid,info.flagsOut,rd,IRRegT(rn));
}
void Comp_T_ADDhi(u16 op)
{
InstructionInfo &info = CurrentAnalysis();
int rd = ((op>>4)&8)|(op&7);
int rm = (op>>3)&0xf;
IR_Add(IR_ADD,info.flagsOut,rd,IRRegT(rd),IRRegT(rm));
if (rd==15)
{
//_dbg_assert_msg_(CPU,0,"WARNING: trying to use ADDhi to change PC in thumb!!");
IR_Add(IR_LEAVE,0,0,ARM_REG_PC,IRL_BRTHUMB);
Compiler_ExitCompile();
Compiler_AddCycles(1); //2 for logical, but hey
}
}
void Comp_T_CMPhi(u16 op)
{
InstructionInfo &info = CurrentAnalysis();
int rd = ((op>>4)&8)|(op&7);
int rm = (op>>3)&0xf;
IR_Add(IR_CMP,info.flagsOut,0,IRRegT(rd),IRRegT(rm));
}
void Comp_T_MOVhi(u16 op)
{
InstructionInfo &info = CurrentAnalysis();
int rd = ((op>>4)&8)|(op&7);
int rm = (op>>3)&0xf;
IR_Add(IR_MOV,info.flagsOut,rd,IRRegT(rm));
if (rd==15)
{
//_dbg_assert_msg_(CPU,0,"WARNING: trying to use MOVhi to change PC in thumb!!");
IR_Add(IR_LEAVE,0,0,ARM_REG_PC,IRL_BRTHUMB);
Compiler_ExitCompile();
Compiler_AddCycles(1); //2 for logical, but hey
}
}
void Comp_3Op_T(u16 op, IROpID opid)
{
InstructionInfo &info = CurrentAnalysis();
int rd=op&7;
int rm=(op>>3)&7;
int rn=(op>>6)&7;
IR_Add(opid,info.flagsOut,rd,IRRegT(rm),IRRegT(rn));
}
void Comp_T_2opimm3(u16 op, IROpID opid)
{
InstructionInfo &info = CurrentAnalysis();
int rd=op&7;
int rm=(op>>3)&7;
int imm=(op>>6)&7;
IR_Add(opid,info.flagsOut,rd,IRRegT(rm),IRInput(imm,true));
}
void Comp_T_2opimm5(u16 op, IROpID opid)
{
InstructionInfo &info = CurrentAnalysis();
int rd=op&7;
int rm=(op>>3)&7;
int imm=(op>>6)&31;
IR_Add(opid,info.flagsOut,rd,IRRegT(rm),IRInput(imm,true));
}
void Comp_T_1opimm8NoOut(u16 op, IROpID opid)
{
InstructionInfo &info = CurrentAnalysis();
int rn=(op>>8)&7;
int imm=op&0xff;
IR_Add(opid,info.flagsOut,0,IRRegT(rn),IRInput(imm,true));
}
void Comp_T_1opimm8(u16 op, IROpID opid)
{
InstructionInfo &info = CurrentAnalysis();
int rn=(op>>8)&7;
int imm=op&0xff;
IR_Add(opid,info.flagsOut,rn,IRRegT(rn),IRInput(imm,true));
}
void Comp_T_OpSpImm(u16 op, IROpID opid)
{
InstructionInfo &info = CurrentAnalysis();
int imm=(op&0x7f)*4;
IR_Add(opid,info.flagsOut,ARM_REG_SP,ARM_REG_SP,IRInput(imm,true));
}
//Data process
void Comp_T_AND(u16 op) {Comp_2Op_T(op,IR_AND);}
void Comp_T_EOR(u16 op) {Comp_2Op_T(op,IR_XOR);}
void Comp_T_ORR(u16 op) {Comp_2Op_T(op,IR_OR); }
void Comp_T_BIC(u16 op) {Comp_2Op_T(op,IR_BIC);}
void Comp_T_ADC(u16 op) {Comp_2Op_T(op,IR_ADC);}
void Comp_T_SBC(u16 op) {Comp_2Op_T(op,IR_SBC);}
void Comp_T_MUL(u16 op) {Comp_2Op_T(op,IR_MUL);}
void Comp_T_LSL(u16 op)
{
int imm = (op>>6) & 0x1f;
if (imm==0)
Comp_1Op_T(op,IR_MOV);
else
Comp_2Op_T(op,IR_LSL);
}
void Comp_T_LSR(u16 op) {Comp_2Op_T(op,IR_LSR);}
void Comp_T_ASR(u16 op) {Comp_2Op_T(op,IR_ASR);}
void Comp_T_ROR(u16 op) {Comp_2Op_T(op,IR_ROR);}
void Comp_T_TST(u16 op) {Comp_2OpNoOut_T(op,IR_TST);}
void Comp_T_CMP(u16 op) {Comp_2OpNoOut_T(op,IR_CMP);}
void Comp_T_CMN(u16 op) {Comp_2OpNoOut_T(op,IR_CMN);}
void Comp_T_MVN(u16 op) {Comp_1Op_T(op,IR_NOT);}
void Comp_T_NEG(u16 op) {Comp_1Op_T(op,IR_NEG);}
void Comp_T_ADDspi(u16 op) {Comp_T_OpSpImm(op,IR_ADD);}
void Comp_T_SUBspi(u16 op) {Comp_T_OpSpImm(op,IR_SUB);}
void Comp_T_ADD(u16 op) {Comp_3Op_T(op,IR_ADD);}
void Comp_T_SUB(u16 op) {Comp_3Op_T(op,IR_SUB);}
void Comp_T_ADDimm(u16 op) {Comp_T_2opimm3(op,IR_ADD);}
void Comp_T_SUBimm(u16 op) {Comp_T_2opimm3(op,IR_SUB);}
void Comp_T_LSLimm(u16 op) {Comp_T_2opimm5(op,IR_LSL);}
void Comp_T_LSRimm(u16 op) {Comp_T_2opimm5(op,IR_LSR);}
void Comp_T_ASRimm(u16 op) {Comp_T_2opimm5(op,IR_ASR);}
void Comp_T_CMPimm(u16 op) {Comp_T_1opimm8NoOut(op,IR_CMP);}
void Comp_T_ADDlim(u16 op) {Comp_T_1opimm8(op,IR_ADD);}
void Comp_T_SUBlim(u16 op) {Comp_T_1opimm8(op,IR_SUB);}
void Comp_T_MOVimm(u16 op)
{
InstructionInfo &info = CurrentAnalysis();
int rn=(op>>8)&7;
int imm=op&0xff;
IR_Add(IR_MOV,info.flagsOut,rn,IRInput(imm,true));
}
void Comp_T_ADDpc(u16 op)
{
InstructionInfo &info = CurrentAnalysis();
int rn=(op>>8)&7;
int imm=op&0xff;
IR_Add(IR_MOV,info.flagsOut,rn,IRInput(imm*4+((compiler_pc+2)&~3),true));
}
void Comp_T_ADDsp(u16 op)
{
InstructionInfo &info = CurrentAnalysis();
int rn=(op>>8)&7;
int imm=op&0xff;
IR_Add(IR_ADD,info.flagsOut,rn,ARM_REG_SP,IRInput(imm*4,true));
}
}