www.pudn.com > potemkin_sourceforPSP.rar > THUMBBranch.cpp, change:2005-09-10,size:2689b
#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 "THUMBBranch.h"
//////////////////////////////////////////////////////////////////////////
// THUMB
//////////////////////////////////////////////////////////////////////////
extern bool internalBackBranches;
namespace THUMBInstructions
{
//Software int
void Comp_T_SWI(u16 op)
{
IR_Add(IR_LEAVE,0,0,IRImm(compiler_pc + 2),IRL_SWITHUMB,IRImm((u32)(op&0xFF)));
if (!IR_IsInBranch())
Compiler_ExitCompile();
}
//branch
void Comp_T_Bcond(u16 op)
{
IR_StartBranch((op>>8)&0xf);
u32 addr = compiler_pc + ((s32)(s8)(op&0xff))*2+4;
if (internalBackBranches && addr>=Compiler_GetStart() && addr=Compiler_GetStart() && addr>3)&0xF);
IR_Add(IR_LEAVE,0,0,rn,IRL_BRDEPENDS);
Compiler_ExitCompile();
}
void Comp_T_BLX(u16 op)
{
int rn = ((op>>3)&0xF);
IR_Add(IR_MOV,0,ARM_REG_LR,IRImm((compiler_pc+2)|1));
IR_Add(IR_LEAVE,0,0,rn,IRL_BRDEPENDS);
Compiler_ExitCompile();
}
void Comp_T_BLbig(u16 op)
{
int H = (op>>11)&3;
switch(H) {
case 2: //10
//this may look inefficient but this is behaviour according to
//ARM manual, and constant propagation will kill it anyway :)
IR_Add(IR_MOV,0,ARM_REG_LR,IRImm(compiler_pc+4+(SEX11(op)<<12)));
break;
case 3: //11
IR_Add(IR_ADD,0,ARM_REG_PC,ARM_REG_LR,IRImm((u32)((op&0x7ff)<<1)));
IR_Add(IR_MOV,0,ARM_REG_LR,IRImm((compiler_pc+2) | 1));
IR_Add(IR_LEAVE,0,0,ARM_REG_PC,IRL_BRTHUMB);
Compiler_ExitCompile();
break;
case 1: //01
IR_Add(IR_ADD,0,ARM_REG_PC,ARM_REG_LR,IRImm((u32)((op&0x7ff)<<1)));
IR_Add(IR_AND,0,ARM_REG_PC,ARM_REG_PC,IRImm((u32)0xFFFFFFFC));
IR_Add(IR_MOV,0,ARM_REG_LR,IRImm((compiler_pc+2) | 1));
IR_Add(IR_LEAVE,0,0,ARM_REG_PC,IRL_BRARM);
Compiler_ExitCompile();
break;
default:
_dbg_assert_msg_(CPU,0,"Illegal form of BLbig");
break;
}
}
}