www.pudn.com > potemkin_sourceforPSP.rar > THUMBBranch.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 "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; 
		} 
	} 
}