Exemple #1
0
u32 MatchDiv32(u32 pc , Sh4RegType &reg1,Sh4RegType &reg2 , Sh4RegType &reg3)
{

	u32 v_pc=pc;
	u32 match=1;
	for (int i=0;i<32;i++)
	{
		u16 opcode=ReadMem16(v_pc);
		v_pc+=2;
		if ((opcode&MASK_N)==ROTCL_KEY)
		{
			if (reg1==NoReg)
				reg1=(Sh4RegType)GetN(opcode);
			else if (reg1!=(Sh4RegType)GetN(opcode))
				break;
			match++;
		}
		else
		{
			//printf("DIV MATCH BROKEN BY: %s\n",OpDesc[opcode]->diss);
			break;
		}
		
		opcode=ReadMem16(v_pc);
		v_pc+=2;
		if ((opcode&MASK_N_M)==DIV1_KEY)
		{
			if (reg2==NoReg)
				reg2=(Sh4RegType)GetM(opcode);
			else if (reg2!=(Sh4RegType)GetM(opcode))
				break;
			
			if (reg2==reg1)
				break;

			if (reg3==NoReg)
				reg3=(Sh4RegType)GetN(opcode);
			else if (reg3!=(Sh4RegType)GetN(opcode))
				break;
			
			if (reg3==reg1)
				break;

			match++;
		}
		else
			break;
	}
	
	return match;
}
u32 MatchDiv32(u32 pc , Sh4RegType &reg1,Sh4RegType &reg2 , Sh4RegType &reg3)
{
	if (settings.dynarec.Safe)
		return 0;

	u32 v_pc=pc;
	u32 match=1;
	for (int i=0;i<32;i++)
	{
		u16 opcode=ReadMem16(v_pc);
		v_pc+=2;
		if ((opcode&MASK_N)==ROTCL_KEY)
		{
			if (reg1==NoReg)
				reg1=(Sh4RegType)GetN(opcode);
			else if (reg1!=(Sh4RegType)GetN(opcode))
				break;
			match++;
		}
		else
			break;
		
		opcode=ReadMem16(v_pc);
		v_pc+=2;
		if ((opcode&MASK_N_M)==DIV1_KEY)
		{
			if (reg2==NoReg)
				reg2=(Sh4RegType)GetM(opcode);
			else if (reg2!=(Sh4RegType)GetM(opcode))
				break;
			
			if (reg2==reg1)
				break;

			if (reg3==NoReg)
				reg3=(Sh4RegType)GetN(opcode);
			else if (reg3!=(Sh4RegType)GetN(opcode))
				break;
			
			if (reg3==reg1)
				break;

			match++;
		}
		else
			break;
	}
	
	return match;
}
Exemple #3
0
void setup_syscall(u32 hook_addr, u32 syscall_addr) {
	WriteMem32(syscall_addr, hook_addr);
	WriteMem16(hook_addr, REIOS_OPCODE);

	debugf("reios: Patching syscall vector %08X, points to %08X\n", syscall_addr, hook_addr);
	debugf("reios: - address %08X: data %04X [%04X]\n", hook_addr, ReadMem16(hook_addr), REIOS_OPCODE);
}
void Sh4_int_Run()
{
    sh4_int_bCpuRun=true;

    s32 l=SH4_TIMESLICE;

#if !defined(TARGET_BOUNDED_EXECUTION)
    do
#else
    for (int i=0; i<10000; i++)
#endif
    {
        do
        {
            u32 op=ReadMem16(next_pc);
            next_pc+=2;

            OpPtr[op](op);
            l-=CPU_RATIO;
        } while(l>0);
        l+=SH4_TIMESLICE;
        UpdateSystem_INTC();
#if !defined(TARGET_BOUNDED_EXECUTION)
    }
    while(sh4_int_bCpuRun);

    sh4_int_bCpuRun=false;
#else
    }
Exemple #5
0
// Reset core, call it after OnRead/OnWrite point to the right BIOS
void MinxCPU_Reset(int hardreset)
{
    MinxCPU.Status = MINX_STATUS_NORMAL;
    MinxCPU.PC.W.L = ReadMem16(hardreset ? 0 : 2);
    MinxCPU.E = 0x1F;
    MinxCPU.F = 0xC0;
    Set_U(0);
    MinxCPU_OnIRQHandle(MinxCPU.F, MinxCPU.Shift_U);
}
void Sh4_int_Step()
{
	if (sh4_int_bCpuRun)
	{
		printf("Sh4 Is running , can't step\n");
	}
	else
	{
		u32 op=ReadMem16(next_pc);
		next_pc+=2;
		ExecuteOpcode(op);
	}
}
void Sh4_int_Run()
{
	sh4_int_bCpuRun=true;

	s32 l=SH4_TIMESLICE;

	do
	{
		do
		{
			u32 op=ReadMem16(next_pc);
			next_pc+=2;

			OpPtr[op](op);
			l-=CPU_RATIO;
		} while(l>0);
		l+=SH4_TIMESLICE;
		UpdateSystem_INTC();

	} while(sh4_int_bCpuRun);

	sh4_int_bCpuRun=false;
}
Exemple #8
0
void print_blocks()
{
	FILE* f=0;

	if (print_stats)
	{
		f=fopen(GetPath("/blkmap.lst").c_str(),"w");
		print_stats=0;

		printf("writing blocks to %p\n",f);
	}

	for (size_t i=0;i<all_blocks.size();i++)
	{
		RuntimeBlockInfo* blk=all_blocks[i];

		if (f)
		{
			fprintf(f,"block: %08X\n",blk);
			fprintf(f,"addr: %08X\n",blk->addr);
			fprintf(f,"hash: %s\n",blk->hash());
			fprintf(f,"hash_rloc: %s\n",blk->hash(false,true));
			fprintf(f,"code: %08X\n",blk->code);
			fprintf(f,"runs: %d\n",blk->runs);
			fprintf(f,"BlockType: %d\n",blk->BlockType);
			fprintf(f,"NextBlock: %08X\n",blk->NextBlock);
			fprintf(f,"BranchBlock: %08X\n",blk->BranchBlock);
			fprintf(f,"pNextBlock: %08X\n",blk->pNextBlock);
			fprintf(f,"pBranchBlock: %08X\n",blk->pBranchBlock);
			fprintf(f,"guest_cycles: %d\n",blk->guest_cycles);
			fprintf(f,"guest_opcodes: %d\n",blk->guest_opcodes);
			fprintf(f,"host_opcodes: %d\n",blk->host_opcodes);
			fprintf(f,"il_opcodes: %d\n",blk->oplist.size());

			u32 hcode=0;
			s32 gcode=-1;
			u8* pucode=(u8*)blk->code;

			size_t j=0;
			
			fprintf(f,"{\n");
			for (;j<blk->oplist.size();j++)
			{
				shil_opcode* op=&all_blocks[i]->oplist[j];
				fprint_hex(f,"//h:",pucode,hcode,op->host_offs);

				if (gcode!=op->guest_offs)
				{
					gcode=op->guest_offs;
					u32 rpc=blk->addr+gcode;
					u16 op=ReadMem16(rpc);

					char temp[128];
					OpDesc[op]->Dissasemble(temp,rpc,op);

					fprintf(f,"//g:%s\n",temp);
				}

				string s=op->dissasm();
				fprintf(f,"//il:%d:%d:%s\n",op->guest_offs,op->host_offs,s.c_str());
			}
			
			fprint_hex(f,"//h:",pucode,hcode,blk->host_code_size);

			fprintf(f,"}\n");
		}

		all_blocks[i]->runs=0;
	}

	if (f) fclose(f);
}
Exemple #9
0
void dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles)
{
	blk=rbi;
	state.Setup(blk->addr,blk->fpu_cfg);
	ngen_GetFeatures(&state.ngen);
	
	blk->guest_opcodes=0;
	
	for(;;)
	{
		switch(state.NextOp)
		{
		case NDO_Delayslot:
			state.NextOp=state.DelayOp;
			state.cpu.is_delayslot=true;
			//there is no break here by design
		case NDO_NextOp:
			{
				if (blk->guest_cycles>=max_cycles && !state.cpu.is_delayslot)
				{
					dec_End(state.cpu.rpc,BET_StaticJump,false);
				}
				else
				{
					/*
					if (MatchDiv0S_0(state.cpu.rpc))
					{
						//can also be emitted as
						//sar   r2,31
						//subcs r1,1
						//in arm

						//r1=r1-sign bit
						//r2=sign mask
						Emit(shop_shl,mk_reg(reg_sr_T),mk_reg(reg_r2),mk_imm(31));
						Emit(shop_sar,mk_reg(reg_r2),mk_reg(reg_r2),mk_imm(31));
						Emit(shop_sub,mk_reg(reg_r1),mk_reg(reg_r1),mk_reg(reg_sr_T));
						blk->guest_cycles+=CPU_RATIO*4;
						state.cpu.rpc+=2*4;
						continue;
					}
					*/

					u32 op=ReadMem16(state.cpu.rpc);
					if (op==0 && state.cpu.is_delayslot)
					{
						printf("Delayslot 0 hack!\n");
					}
					else
					{
						blk->guest_opcodes++;
						if (op>=0xF000)
							blk->guest_cycles+=0;
						else
							blk->guest_cycles+=CPU_RATIO;

						verify(!(state.cpu.is_delayslot && OpDesc[op]->SetPC()));
						if (state.ngen.OnlyDynamicEnds || !OpDesc[op]->rec_oph)
						{
							if (state.ngen.InterpreterFallback || !dec_generic(op))
							{
								dec_fallback(op);
								if (OpDesc[op]->SetPC())
								{
									dec_DynamicSet(reg_nextpc);
									dec_End(0xFFFFFFFF,BET_DynamicJump,false);
								}
								if (OpDesc[op]->SetFPSCR() && !state.cpu.is_delayslot)
								{
									dec_End(state.cpu.rpc+2,BET_StaticJump,false);
								}
							}
							/*
							else if (state.info.has_readm || state.info.has_writem)
							{
								if (!state.cpu.is_delayslot)
								dec_End(state.cpu.rpc+2,BET_StaticJump,false);
							}
							*/
						}
						else
						{
							OpDesc[op]->rec_oph(op);
						}
					}
					state.cpu.rpc+=2;
				}
			}
			break;

		case NDO_Jump:
			die("Too old");
			state.NextOp=state.JumpOp;
			state.cpu.rpc=state.JumpAddr;
			break;

		case NDO_End:
			goto _end;
		}
	}

_end:
	blk->sh4_code_size=state.cpu.rpc-blk->addr;
	blk->NextBlock=state.NextAddr;
	blk->BranchBlock=state.JumpAddr;
	blk->BlockType=state.BlockType;
	
#if HOST_OS == OS_WINDOWS
	switch(rbi->addr)
	{
	case 0x8C09ED16:
	case 0x8C0BA50E:
	case 0x8C0BA506:
	case 0x8C0BA526:
	case 0x8C224800:
		printf("HASH: %08X reloc %s\n",blk->addr,blk->hash(false,true));
		break;
	}
#endif

	//cycle tricks
	if (settings.dynarec.idleskip)
	{
		//Experimental hash-id based idle skip
		if (strstr(idle_hash,blk->hash(false,true)))
		{
			//printf("IDLESKIP: %08X reloc match %s\n",blk->addr,blk->hash(false,true));
			blk->guest_cycles=max_cycles*100;
		}
		else
		{
			//Small-n-simple idle loop detector :p
			if (state.info.has_readm && !state.info.has_writem && !state.info.has_fpu && blk->guest_opcodes<6)
			{
				if (blk->BlockType==BET_Cond_0 || blk->BlockType==BET_Cond_1 && blk->BranchBlock<=blk->addr)
				{
					blk->guest_cycles*=3;
				}

				if (blk->BranchBlock==blk->addr)
				{
					blk->guest_cycles*=10;
				}
			}

			//if in syscalls area (ip.bin etc) skip fast :p
			if ((blk->addr&0x1FFF0000)==0x0C000000)
			{
				if (blk->addr&0x8000)
				{
					//ip.bin (boot loader/img etc)
					blk->guest_cycles*=15;
				}
				else
				{
					//syscalls
					blk->guest_cycles*=5;
				}
			}

			//blk->guest_cycles=5;
		}
	}
	else
	{
		blk->guest_cycles*=1.5;
	}

	//make sure we don't use wayy-too-many cycles
	blk->guest_cycles=min(blk->guest_cycles,max_cycles);
	//make sure we don't use wayy-too-few cycles
	blk->guest_cycles=max(1U,blk->guest_cycles);
	blk=0;
}
Exemple #10
0
u16 DYNACALL IReadMem16(u32 Address)
{
   return ReadMem16(Address);
}