[Poject64] Add Arm recompiler

This commit is contained in:
zilmar 2016-08-11 21:09:21 +10:00
parent 397a1dd469
commit 146ff34894
11 changed files with 4581 additions and 37 deletions

View File

@ -386,9 +386,9 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
};
ArmThumbOpcode * OpCode = (ArmThumbOpcode *)context.arm_pc;
if (OpCode->opcode == ArmLDR_Reg)
if (OpCode->Reg.opcode == ArmLDR_Reg)
{
if (!g_MMU->LW_NonMemory(MemAddress, ArmRegisters[OpCode->rt]))
if (!g_MMU->LW_NonMemory(MemAddress, ArmRegisters[OpCode->Reg.rt]))
{
if (g_Settings->LoadDword(Debugger_ShowUnhandledMemory))
{
@ -398,9 +398,9 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
context.arm_pc = context.arm_pc + 2;
return true;
}
if (OpCode->opcode == ArmSTR_Reg)
if (OpCode->Reg.opcode == ArmSTR_Reg)
{
if (!g_MMU->SW_NonMemory(MemAddress, *ArmRegisters[OpCode->rt]))
if (!g_MMU->SW_NonMemory(MemAddress, *ArmRegisters[OpCode->Reg.rt]))
{
if (g_Settings->LoadDword(Debugger_ShowUnhandledMemory))
{
@ -458,12 +458,12 @@ bool CMipsMemoryVM::FilterArmException(uint32_t MemAddress, mcontext_t & context
uint8_t * TypePos = (uint8_t *)context.arm_pc;
WriteTrace(TraceExceptionHandler, TraceError, "TypePos: %02X %02X %02X %02X %02X %02X %02X %02X %02X",TypePos[0],TypePos[1],TypePos[2],TypePos[3],TypePos[4],TypePos[5],TypePos[6],TypePos[7],TypePos[8]);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode.Hex: %X",OpCode->Hex);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode.opcode: %X",OpCode->opcode);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode.rm: %X",OpCode->rm);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode.rn: %X",OpCode->rn);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode.rt: %X",OpCode->rt);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode.opcode: %X",OpCode->Reg.opcode);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode.rm: %X",OpCode->Reg.rm);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode.rn: %X",OpCode->Reg.rn);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode.rt: %X",OpCode->Reg.rt);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32.Hex: %X",OpCode32->Hex);
WriteTrace(TraceExceptionHandler, TraceError, "OpCode32->uint16.opcode: %X",OpCode32->uint16.opcode);

View File

@ -9,6 +9,7 @@
* *
****************************************************************************/
#pragma once
#if defined(__arm__) || defined(_M_ARM)
#pragma warning(push)
#pragma warning(disable : 4201) // warning C4201: nonstandard extension used : nameless struct/union
@ -18,13 +19,77 @@ union ArmThumbOpcode
uint16_t Hex;
uint8_t Ascii[2];
struct
{
unsigned reserved : 3;
unsigned rm : 4;
unsigned opcode : 9;
} Branch;
struct
{
unsigned imm : 11;
unsigned opcode : 5;
} BranchImm;
struct
{
unsigned imm : 8;
unsigned cond : 4;
unsigned opcode : 4;
} BranchImmCond;
struct
{
unsigned rt : 3;
unsigned rn : 3;
unsigned rm : 3;
unsigned opcode : 7;
};
} Reg;
struct
{
unsigned imm8 : 8;
unsigned rdn : 3;
unsigned opcode : 5;
} Imm8;
struct
{
unsigned rd : 3;
unsigned rn : 3;
unsigned imm3 : 3;
unsigned opcode : 7;
} Imm3;
struct
{
unsigned rt : 3;
unsigned rn : 3;
unsigned imm5 : 5;
unsigned opcode : 5;
} Imm5;
struct
{
unsigned rn : 3;
unsigned rm : 3;
unsigned opcode : 10;
} Reg2;
struct
{
unsigned register_list : 8;
unsigned m : 1;
unsigned opcode : 7;
} Push;
struct
{
unsigned register_list : 8;
unsigned p : 1;
unsigned opcode : 7;
} Pop;
};
union Arm32Opcode
@ -43,6 +108,54 @@ union Arm32Opcode
unsigned rt : 4;
} uint16;
struct
{
unsigned Rn : 4;
unsigned s : 1;
unsigned opcode : 5;
unsigned i : 1;
unsigned opcode2 : 5;
unsigned imm8 : 8;
unsigned rd : 4;
unsigned imm3 : 3;
unsigned reserved : 1;
} RnRdImm12;
struct
{
unsigned rn : 4;
unsigned opcode : 12;
unsigned imm : 12;
unsigned rt : 4;
} imm12;
struct
{
unsigned imm4 : 4;
unsigned opcode2 : 6;
unsigned i : 1;
unsigned opcode : 5;
unsigned imm8 : 8;
unsigned rd : 4;
unsigned imm3 : 3;
unsigned reserved : 1;
} imm16;
struct
{
unsigned imm6 : 6;
unsigned cond : 4;
unsigned S : 1;
unsigned Opcode : 5;
unsigned imm11 : 11;
unsigned J2 : 1;
unsigned val12 : 1;
unsigned J1 : 1;
unsigned val14 : 2;
} Branch20;
struct
{
unsigned rm : 4;
@ -56,8 +169,17 @@ union Arm32Opcode
enum ArmThumbOpCodes
{
ArmSTR_ThumbImm = 0xC,
ArmSTR_Reg = 40,
ArmLDR_Reg = 44,
ArmLDR_ThumbImm = 0xD,
ArmLDR_Reg = 44,
ArmLDRH_Reg = 0xE19,
ArmLDRH_W = 0xF83,
ArmMOV_IMM16 = 0x1E,
ArmMOVW_IMM16 = 0x24,
ArmMOVT_IMM16 = 0x2C,
ArmPUSH = 0x5A,
ArmPOP = 0x5E,
};
#endif

View File

@ -0,0 +1,512 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include "stdafx.h"
#if defined(__arm__) || defined(_M_ARM)
#include <Project64-core/N64System/SystemGlobals.h>
#include <Project64-core/N64System/Recompiler/Arm/ArmOps.h>
#include <Project64-core/N64System/Recompiler/RecompilerCodeLog.h>
#include <Project64-core/N64System/Recompiler/Arm/ArmOpCode.h>
/**************************************************************************
* Logging Functions *
**************************************************************************/
void CArmOps::WriteArmComment(const char * Comment)
{
CPU_Message("");
CPU_Message(" // %s", Comment);
}
void CArmOps::WriteArmLabel(const char * Label)
{
CPU_Message("");
CPU_Message(" %s:", Label);
}
void CArmOps::AddArmRegToArmReg(ArmReg SourceReg1, ArmReg SourceReg2, ArmReg DestReg)
{
CPU_Message(" add\t%s,%s,%s", ArmRegName(DestReg), ArmRegName(SourceReg1), ArmRegName(SourceReg2));
ArmThumbOpcode op = {0};
op.Reg.rt = DestReg;
op.Reg.rn = SourceReg1;
op.Reg.rm = SourceReg2;
op.Reg.opcode = 0xC;
AddCode16(op.Hex);
}
void CArmOps::AndArmRegToArmReg(ArmReg SourceReg, ArmReg DestReg)
{
CPU_Message(" and\t%s, %s", ArmRegName(DestReg), ArmRegName(SourceReg));
ArmThumbOpcode op = {0};
op.Reg2.rn = DestReg;
op.Reg2.rm = SourceReg;
op.Reg2.opcode = 0x100;
AddCode16(op.Hex);
}
void CArmOps::BranchLabel8(ArmBranchCompare CompareType, const char * Label)
{
CPU_Message(" b%s\t%s", ArmBranchSuffix(CompareType),Label);
ArmThumbOpcode op = {0};
if (CompareType == ArmBranch_Always)
{
op.BranchImm.imm = 0;
op.BranchImm.opcode = 0x1C;
}
else
{
op.BranchImmCond.imm = 0;
op.BranchImmCond.opcode = 0xD;
op.BranchImmCond.cond = CompareType;
}
AddCode16(op.Hex);
}
void CArmOps::BranchLabel20(ArmBranchCompare CompareType, const char * Label)
{
CPU_Message(" b%s\t%s", ArmBranchSuffix(CompareType),Label);
Arm32Opcode op = {0};
op.Branch20.imm6 = 0;
op.Branch20.cond = CompareType == ArmBranch_Always ? 0 : CompareType;
op.Branch20.S = 0;
op.Branch20.Opcode = 0x1E;
op.Branch20.imm11 = 0;
op.Branch20.J2 = CompareType == ArmBranch_Always ? 1 : 0;
op.Branch20.val12 = CompareType == ArmBranch_Always ? 1 : 0;
op.Branch20.J1 = CompareType == ArmBranch_Always ? 1 : 0;
op.Branch20.val14 = 0x2;
AddCode32(op.Hex);
}
void CArmOps::CallFunction(void * Function, const char * FunctionName)
{
ArmReg reg = Arm_R4;
MoveConstToArmReg((uint32_t)Function,reg,FunctionName);
int32_t offset=(int32_t)Function-(int32_t)*g_RecompPos;
ArmThumbOpcode op = {0};
op.Branch.reserved = 0;
op.Branch.rm = reg;
op.Branch.opcode = 0x8F;
CPU_Message(" blx\t%s", ArmRegName(reg));
AddCode16(op.Hex);
}
void CArmOps::MoveConstToArmReg(uint16_t Const, ArmReg reg, const char * comment)
{
if (comment != NULL)
{
CPU_Message(" movw\t%s, #0x%X\t; %s", ArmRegName(reg), (uint32_t)Const, comment);
}
else
{
CPU_Message(" movw\t%s, #%d\t; 0x%X", ArmRegName(reg), (uint32_t)Const, (uint32_t)Const);
}
Arm32Opcode op = {0};
op.imm16.opcode = ArmMOV_IMM16;
op.imm16.i = ((Const >> 11) & 0x1);
op.imm16.opcode2 = ArmMOVW_IMM16;
op.imm16.imm4 = ((Const >> 12) & 0xF);
op.imm16.reserved = 0;
op.imm16.imm3 = ((Const >> 8) & 0x7);
op.imm16.rd = reg;
op.imm16.imm8 = (Const & 0xFF);
AddCode32(op.Hex);
}
void CArmOps::MoveConstToArmRegTop(uint16_t Const, ArmReg reg, const char * comment)
{
if (comment != NULL)
{
CPU_Message(" movt\t%s, #0x%X\t; %s", ArmRegName(reg), (uint32_t)Const, comment);
}
else
{
CPU_Message(" movt\t%s, #%d\t; 0x%X", ArmRegName(reg), (uint32_t)Const, (uint32_t)Const);
}
Arm32Opcode op = {0};
op.imm16.opcode = ArmMOV_IMM16;
op.imm16.i = ((Const >> 11) & 0x1);
op.imm16.opcode2 = ArmMOVT_IMM16;
op.imm16.imm4 = ((Const >> 12) & 0xF);
op.imm16.reserved = 0;
op.imm16.imm3 = ((Const >> 8) & 0x7);
op.imm16.rd = reg;
op.imm16.imm8 = (Const & 0xFF);
AddCode32(op.Hex);
}
void CArmOps::CompareArmRegToConst(ArmReg Reg, uint8_t value)
{
if (Reg > 0x7) { g_Notify->BreakPoint(__FILE__,__LINE__); return; }
CPU_Message(" cmp\t%s, #%d\t; 0x%X", ArmRegName(Reg), value, value);
ArmThumbOpcode op = {0};
op.Imm8.imm8 = value;
op.Imm8.rdn = Reg;
op.Imm8.opcode = 0x5;
AddCode16(op.Hex);
}
void CArmOps::CompareArmRegToArmReg(ArmReg Reg1, ArmReg Reg2)
{
CPU_Message(" cmp\t%s, %s", ArmRegName(Reg1), ArmRegName(Reg2));
ArmThumbOpcode op = {0};
op.Reg2.rn = Reg1;
op.Reg2.rm = Reg2;
op.Reg2.opcode = 0x10A;
AddCode16(op.Hex);
}
void CArmOps::LoadArmRegPointerToArmReg(ArmReg RegPointer, ArmReg Reg, uint8_t offset)
{
if (Reg > 0x7 || RegPointer > 0x7)
{
if ((offset & (~0xFFF)) != 0) { g_Notify->BreakPoint(__FILE__,__LINE__); return; }
g_Notify->BreakPoint(__FILE__,__LINE__);
}
else
{
if ((offset & (~0x1F)) != 0) { g_Notify->BreakPoint(__FILE__,__LINE__); return; }
CPU_Message(" ldr\t%s, [%s, #%d]", ArmRegName(Reg), ArmRegName(RegPointer), (uint32_t)offset);
ArmThumbOpcode op = {0};
op.Imm5.rt = Reg;
op.Imm5.rn = RegPointer;
op.Imm5.imm5 = offset;
op.Imm5.opcode = ArmLDR_ThumbImm;
AddCode16(op.Hex);
}
}
void CArmOps::MoveArmRegArmReg(ArmReg SourceReg, ArmReg DestReg)
{
g_Notify->BreakPoint(__FILE__,__LINE__);
}
void CArmOps::MoveConstToArmReg(uint32_t Const, ArmReg reg, const char * comment)
{
MoveConstToArmReg((uint16_t)(Const & 0xFFFF),reg,comment);
uint16_t TopValue = (uint16_t)((Const >> 16) & 0xFFFF);
if (TopValue != 0)
{
MoveConstToArmRegTop(TopValue,reg,comment != NULL ? "" : NULL);
}
}
void CArmOps::MoveConstToVariable(uint32_t Const, void * Variable, const char * VariableName)
{
MoveConstToArmReg(Const,Arm_R1);
MoveConstToArmReg((uint32_t)Variable,Arm_R2,VariableName);
StoreArmRegToArmRegPointer(Arm_R1,Arm_R2,0);
}
void CArmOps::MoveVariableToArmReg(void * Variable, const char * VariableName, ArmReg reg)
{
MoveConstToArmReg((uint32_t)Variable,reg,VariableName);
LoadArmRegPointerToArmReg(reg,reg,0);
}
void CArmOps::PushArmReg(uint16_t Registers)
{
if (Registers == 0)
{
return;
}
if ((Registers & ArmPushPop_R8) != 0) { g_Notify->BreakPoint(__FILE__,__LINE__); }
if ((Registers & ArmPushPop_R9) != 0) { g_Notify->BreakPoint(__FILE__,__LINE__); }
if ((Registers & ArmPushPop_R10) != 0) { g_Notify->BreakPoint(__FILE__,__LINE__); }
if ((Registers & ArmPushPop_R11) != 0) { g_Notify->BreakPoint(__FILE__,__LINE__); }
if ((Registers & ArmPushPop_R12) != 0) { g_Notify->BreakPoint(__FILE__,__LINE__); }
if ((Registers & ArmPushPop_R13) != 0) { g_Notify->BreakPoint(__FILE__,__LINE__); }
if ((Registers & ArmPushPop_R15) != 0) { g_Notify->BreakPoint(__FILE__,__LINE__); }
std::string pushed;
if ((Registers & ArmPushPop_R1) != 0) { pushed += pushed.length() > 0 ? ", r1" : "r1"; }
if ((Registers & ArmPushPop_R2) != 0) { pushed += pushed.length() > 0 ? ", r2" : "r2"; }
if ((Registers & ArmPushPop_R3) != 0) { pushed += pushed.length() > 0 ? ", r3" : "r3"; }
if ((Registers & ArmPushPop_R4) != 0) { pushed += pushed.length() > 0 ? ", r4" : "r4"; }
if ((Registers & ArmPushPop_R5) != 0) { pushed += pushed.length() > 0 ? ", r5" : "r5"; }
if ((Registers & ArmPushPop_R6) != 0) { pushed += pushed.length() > 0 ? ", r6" : "r6"; }
if ((Registers & ArmPushPop_R7) != 0) { pushed += pushed.length() > 0 ? ", r7" : "r7"; }
if ((Registers & ArmPushPop_LR) != 0) { pushed += pushed.length() > 0 ? ", lr" : "lr"; }
CPU_Message(" push\t%s", pushed.c_str());
bool lr = (Registers & ArmPushPop_LR) != 0;
Registers &= Registers & ~ArmPushPop_LR;
ArmThumbOpcode op = {0};
op.Push.register_list = (uint8_t)Registers;
op.Push.m = lr ? 1 : 0;
op.Push.opcode = ArmPUSH;
AddCode16(op.Hex);
}
void CArmOps::PopArmReg(uint16_t Registers)
{
if (Registers == 0)
{
return;
}
if ((Registers & ArmPushPop_R8) != 0) { g_Notify->BreakPoint(__FILE__,__LINE__); }
if ((Registers & ArmPushPop_R9) != 0) { g_Notify->BreakPoint(__FILE__,__LINE__); }
if ((Registers & ArmPushPop_R10) != 0) { g_Notify->BreakPoint(__FILE__,__LINE__); }
if ((Registers & ArmPushPop_R11) != 0) { g_Notify->BreakPoint(__FILE__,__LINE__); }
if ((Registers & ArmPushPop_R12) != 0) { g_Notify->BreakPoint(__FILE__,__LINE__); }
if ((Registers & ArmPushPop_R13) != 0) { g_Notify->BreakPoint(__FILE__,__LINE__); }
if ((Registers & ArmPushPop_R14) != 0) { g_Notify->BreakPoint(__FILE__,__LINE__); }
std::string pushed;
if ((Registers & ArmPushPop_R1) != 0) { pushed += pushed.length() > 0 ? ", r1" : "r1"; }
if ((Registers & ArmPushPop_R2) != 0) { pushed += pushed.length() > 0 ? ", r2" : "r2"; }
if ((Registers & ArmPushPop_R3) != 0) { pushed += pushed.length() > 0 ? ", r3" : "r3"; }
if ((Registers & ArmPushPop_R4) != 0) { pushed += pushed.length() > 0 ? ", r4" : "r4"; }
if ((Registers & ArmPushPop_R5) != 0) { pushed += pushed.length() > 0 ? ", r5" : "r5"; }
if ((Registers & ArmPushPop_R6) != 0) { pushed += pushed.length() > 0 ? ", r6" : "r6"; }
if ((Registers & ArmPushPop_R7) != 0) { pushed += pushed.length() > 0 ? ", r7" : "r7"; }
if ((Registers & ArmPushPop_PC) != 0) { pushed += pushed.length() > 0 ? ", pc" : "pc"; }
CPU_Message(" pop\t%s", pushed.c_str());
bool pc = (Registers & ArmPushPop_PC) != 0;
Registers &= Registers & ~ArmPushPop_PC;
ArmThumbOpcode op = {0};
op.Pop.register_list = (uint8_t)Registers;
op.Pop.p = pc ? 1 : 0;
op.Pop.opcode = ArmPOP;
AddCode16(op.Hex);
}
void CArmOps::StoreArmRegToArmRegPointer(ArmReg Reg, ArmReg RegPointer, uint8_t offset)
{
if (Reg > 0x7 || RegPointer > 0x7)
{
if ((offset & (~0xFFF)) != 0) { g_Notify->BreakPoint(__FILE__,__LINE__); return; }
CPU_Message(" str\t%s, [%s, #%d]", ArmRegName(Reg), ArmRegName(RegPointer), (uint32_t)offset);
Arm32Opcode op = {0};
op.imm12.rt = Reg;
op.imm12.rn = RegPointer;
op.imm12.imm = offset;
op.imm12.opcode = 0xF8C;
AddCode32(op.Hex);
}
else
{
if ((offset & (~0x1F)) != 0) { g_Notify->BreakPoint(__FILE__,__LINE__); return; }
CPU_Message(" str\t%s, [%s, #%d]", ArmRegName(Reg), ArmRegName(RegPointer), (uint32_t)offset);
ArmThumbOpcode op = {0};
op.Imm5.rt = Reg;
op.Imm5.rn = RegPointer;
op.Imm5.imm5 = offset;
op.Imm5.opcode = ArmSTR_ThumbImm;
AddCode16(op.Hex);
}
}
void CArmOps::SubConstFromArmReg(ArmReg Reg, uint32_t Const)
{
if (Reg <= 7 && (Const & (~0xFF)) == 0)
{
CPU_Message(" subs\t%s, #0x%X", ArmRegName(Reg), Const);
ArmThumbOpcode op = {0};
op.Imm8.imm8 = (uint8_t)Const;
op.Imm8.rdn = Reg;
op.Imm8.opcode = 0x7;
AddCode16(op.Hex);
}
else if ((Const & (~0x7FF)) == 0)
{
CPU_Message(" sub\t%s, #0x%X", ArmRegName(Reg), Const);
Arm32Opcode op = {0};
op.RnRdImm12.Rn = Reg;
op.RnRdImm12.s = 0;
op.RnRdImm12.opcode = 0x15;
op.RnRdImm12.i = (Const >> 11) & 1;
op.RnRdImm12.opcode2 = 0x1E;
op.RnRdImm12.imm8 = (Const & 0xFF);
op.RnRdImm12.rd = Reg;
op.RnRdImm12.imm3 = (Const >> 8) & 0x7;
op.RnRdImm12.reserved = 0;
AddCode32(op.Hex);
}
else
{
g_Notify->BreakPoint(__FILE__,__LINE__);
}
}
void CArmOps::SubConstFromVariable(uint32_t Const, void * Variable, const char * VariableName)
{
MoveConstToArmReg((uint32_t)Variable,Arm_R1,VariableName);
LoadArmRegPointerToArmReg(Arm_R1,Arm_R2,0);
SubConstFromArmReg(Arm_R2,Const);
StoreArmRegToArmRegPointer(Arm_R2,Arm_R1,0);
}
void CArmOps::TestVariable(uint32_t Const, void * Variable, const char * VariableName)
{
MoveVariableToArmReg(Variable,VariableName, Arm_R2);
MoveConstToArmReg(Const,Arm_R3);
AndArmRegToArmReg(Arm_R3,Arm_R2);
CompareArmRegToArmReg(Arm_R2,Arm_R3);
}
void CArmOps::SetJump8(uint8_t * Loc, uint8_t * JumpLoc)
{
if (Loc == NULL || JumpLoc == NULL)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
ArmThumbOpcode * op = (ArmThumbOpcode *)Loc;
if (op->BranchImm.opcode != 0x1C && op->BranchImmCond.opcode != 0xD)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
uint32_t pc = ((uint32_t)Loc) + 4;
uint32_t target = ((uint32_t)JumpLoc);
uint32_t immediate = (target - pc) >> 1;
if ((immediate & ~0x7F) != 0)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
CPU_Message("%s: pc: %X target: %X Loc: %X JumpLoc: %X immediate: %X", __FUNCTION__, pc, target, (uint32_t)Loc, (uint32_t)JumpLoc, immediate );
CPU_Message("%s: writing %d to %X", __FUNCTION__, immediate, Loc);
if (op->BranchImm.opcode == 0x1C)
{
op->BranchImm.imm = immediate;
}
else
{
op->BranchImmCond.imm = (uint8_t)immediate;
}
}
void CArmOps::SetJump20(uint32_t * Loc, uint32_t * JumpLoc)
{
if (Loc == NULL || JumpLoc == NULL)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
uint32_t pc = ((uint32_t)Loc) + 4;
uint32_t target = ((uint32_t)JumpLoc);
uint32_t immediate = (target - pc) >> 1;
uint32_t immediate_check = immediate & ~0xFFFFF;
if (immediate_check != 0 && immediate_check != ~0xFFFFF)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
Arm32Opcode op = {0};
op.Hex = *Loc;
if (op.Branch20.val12 == 0)
{
op.Branch20.imm11 = (immediate & 0x7FF);
op.Branch20.imm6 = (immediate >> 11) & 0x37;
op.Branch20.J1 = (immediate >> 17) & 0x1;
op.Branch20.J2 = (immediate >> 18) & 0x1;
op.Branch20.S = (immediate >> 19) & 0x1;
}
else
{
if (immediate < 0)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
else
{
op.Branch20.imm11 = (immediate & 0x7FF);
}
}
uint32_t OriginalValue = *Loc;
*Loc = op.Hex;
CPU_Message("%s: OriginalValue %X New Value %X JumpLoc: %X Loc: %X immediate: %X immediate_check = %X", __FUNCTION__, OriginalValue, *Loc, JumpLoc, Loc, immediate, immediate_check );
}
void * CArmOps::GetAddressOf(int value, ...)
{
void * Address;
va_list ap;
va_start(ap, value);
Address = va_arg(ap, void *);
va_end(ap);
return Address;
}
const char * CArmOps::ArmBranchSuffix(ArmBranchCompare CompareType)
{
switch (CompareType)
{
case ArmBranch_Equal: return "eq";
case ArmBranch_Notequal: return "ne";
case ArmBranch_GreaterThanOrEqual: return "ge";
case ArmBranch_LessThan: return "l";
case ArmBranch_GreaterThan: return "g";
case ArmBranch_LessThanOrEqual: return "le";
case ArmBranch_Always: return "";
default:
g_Notify->BreakPoint(__FILE__, __LINE__);
}
return "???";
}
const char * CArmOps::ArmRegName(ArmReg Reg)
{
switch (Reg)
{
case Arm_R0: return "R0";
case Arm_R1: return "R1";
case Arm_R2: return "R2";
case Arm_R3: return "R3";
case Arm_R4: return "R4";
case Arm_R5: return "R5";
case Arm_R6: return "R6";
case Arm_R7: return "R7";
case Arm_R8: return "R8";
case Arm_R9: return "R9";
case Arm_R10: return "R10";
case Arm_R11: return "R11";
case Arm_R12: return "R12";
case ArmRegSP: return "SP";
case ArmRegLR: return "LR";
case ArmRegPC: return "PC";
default:
g_Notify->BreakPoint(__FILE__, __LINE__);
}
return "???";
}
void CArmOps::AddCode8(uint8_t value)
{
(*((uint8_t *)(*g_RecompPos))=(uint8_t)(value));
*g_RecompPos += 1;
}
void CArmOps::AddCode16(uint16_t value)
{
(*((uint16_t *)(*g_RecompPos))=(uint16_t)(value));
*g_RecompPos += 2;
}
void CArmOps::AddCode32(uint32_t value)
{
(*((uint32_t *)(*g_RecompPos)) = (uint32_t)(value));
*g_RecompPos += 4;
}
#endif

View File

@ -0,0 +1,113 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once
#if defined(__arm__) || defined(_M_ARM)
class CArmOps
{
public:
enum ArmReg
{
Arm_R0 = 0,
Arm_R1 = 1,
Arm_R2 = 2,
Arm_R3 = 3,
Arm_R4 = 4,
Arm_R5 = 5,
Arm_R6 = 6,
Arm_R7 = 7,
Arm_R8 = 8,
Arm_R9 = 9,
Arm_R10 = 10,
Arm_R11 = 11,
Arm_R12 = 12,
Arm_R13 = 13,
ArmRegSP = 13,
Arm_R14 = 14,
ArmRegLR = 14,
Arm_R15 = 15,
ArmRegPC = 15,
};
enum ArmRegPushPop
{
ArmPushPop_R0 = 0x0001,
ArmPushPop_R1 = 0x0002,
ArmPushPop_R2 = 0x0004,
ArmPushPop_R3 = 0x0008,
ArmPushPop_R4 = 0x0010,
ArmPushPop_R5 = 0x0020,
ArmPushPop_R6 = 0x0040,
ArmPushPop_R7 = 0x0080,
ArmPushPop_R8 = 0x0100,
ArmPushPop_R9 = 0x0200,
ArmPushPop_R10 = 0x0400,
ArmPushPop_R11 = 0x0800,
ArmPushPop_R12 = 0x1000,
ArmPushPop_R13 = 0x2000,
ArmPushPop_SP = 0x2000,
ArmPushPop_R14 = 0x4000,
ArmPushPop_LR = 0x4000,
ArmPushPop_R15 = 0x8000,
ArmPushPop_PC = 0x8000,
};
enum ArmBranchCompare
{
ArmBranch_Equal = 0, //Code = 0000
ArmBranch_Notequal = 1, //Code = 0001
ArmBranch_GreaterThanOrEqual = 10, //Code = 1010
ArmBranch_LessThan = 11, //Code = 1011
ArmBranch_GreaterThan = 12, //Code = 1100
ArmBranch_LessThanOrEqual = 13, //Code = 1101
ArmBranch_Always = 14, //Code = 1110
};
protected:
//Logging Functions
static void WriteArmComment(const char * Comment);
static void WriteArmLabel(const char * Label);
static void AddArmRegToArmReg(ArmReg SourceReg1, ArmReg SourceReg2, ArmReg DestReg);
static void AndArmRegToArmReg(ArmReg SourceReg, ArmReg DestReg);
static void BranchLabel8(ArmBranchCompare CompareType, const char * Label);
static void BranchLabel20(ArmBranchCompare CompareType, const char * Label);
static void CallFunction(void * Function, const char * FunctionName);
static void CompareArmRegToConst(ArmReg Reg, uint8_t value);
static void CompareArmRegToArmReg(ArmReg Reg1, ArmReg Reg2);
static void LoadArmRegPointerToArmReg(ArmReg RegPointer, ArmReg Reg, uint8_t offset);
static void MoveArmRegArmReg(ArmReg SourceReg, ArmReg DestReg);
static void MoveConstToArmReg(uint16_t Const, ArmReg reg, const char * comment = NULL);
static void MoveConstToArmRegTop(uint16_t Const, ArmReg reg, const char * comment = NULL);
static void MoveConstToArmReg(uint32_t Const, ArmReg reg, const char * comment = NULL);
static void MoveConstToVariable(uint32_t Const, void * Variable, const char * VariableName);
static void MoveVariableToArmReg(void * Variable, const char * VariableName, ArmReg reg);
static void PushArmReg(uint16_t Registers);
static void PopArmReg(uint16_t Registers);
static void StoreArmRegToArmRegPointer(ArmReg Reg, ArmReg RegPointer, uint8_t offset);
static void SubConstFromArmReg(ArmReg Reg, uint32_t Const);
static void SubConstFromVariable(uint32_t Const, void * Variable, const char * VariableName);
static void TestVariable(uint32_t Const, void * Variable, const char * VariableName);
static void * GetAddressOf(int32_t value, ...);
static void SetJump8(uint8_t * Loc, uint8_t * JumpLoc);
static void SetJump20(uint32_t * Loc, uint32_t * JumpLoc);
static const char * ArmBranchSuffix(ArmBranchCompare CompareType);
static const char * ArmRegName(ArmReg Reg);
static void AddCode8(uint8_t value);
static void AddCode16(uint16_t value);
static void AddCode32(uint32_t value);
};
#define AddressOf(Addr) CArmOps::GetAddressOf(5,(Addr))
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,246 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once
#if defined(__arm__) || defined(_M_ARM)
#include <Project64-core/N64System/Mips/RegisterClass.h>
#include <Project64-core/N64System/Recompiler/RecompilerOps.h>
#include <Project64-core/N64System/Recompiler/Arm/ArmOps.h>
#include <Project64-core/Settings/DebugSettings.h>
class CArmRecompilerOps :
public CRecompilerOps,
protected CDebugSettings,
private CArmOps,
protected CSystemRegisters
{
public:
CArmRecompilerOps();
/************************** Branch functions ************************/
void Compile_BranchCompare(BRANCH_COMPARE CompareType);
void Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE BranchType, bool Link);
void Compile_BranchLikely(BRANCH_COMPARE CompareType, bool Link);
void BNE_Compare();
void BEQ_Compare();
void BGTZ_Compare();
void BLEZ_Compare();
void BLTZ_Compare();
void BGEZ_Compare();
void COP1_BCF_Compare();
void COP1_BCT_Compare();
/************************* OpCode functions *************************/
void J ();
void JAL ();
void ADDI ();
void ADDIU ();
void SLTI ();
void SLTIU ();
void ANDI ();
void ORI ();
void XORI ();
void LUI ();
void DADDIU ();
void LDL ();
void LDR ();
void LB ();
void LH ();
void LWL ();
void LW ();
void LBU ();
void LHU ();
void LWR ();
void LWU ();
void SB ();
void SH ();
void SWL ();
void SW ();
void SWR ();
void SDL ();
void SDR ();
void CACHE ();
void LL ();
void LWC1 ();
void LDC1 ();
void LD ();
void SC ();
void SWC1 ();
void SDC1 ();
void SD ();
/********************** R4300i OpCodes: Special **********************/
void SPECIAL_SLL ();
void SPECIAL_SRL ();
void SPECIAL_SRA ();
void SPECIAL_SLLV ();
void SPECIAL_SRLV ();
void SPECIAL_SRAV ();
void SPECIAL_JR ();
void SPECIAL_JALR ();
void SPECIAL_SYSCALL();
void SPECIAL_MFLO ();
void SPECIAL_MTLO ();
void SPECIAL_MFHI ();
void SPECIAL_MTHI ();
void SPECIAL_DSLLV ();
void SPECIAL_DSRLV ();
void SPECIAL_DSRAV ();
void SPECIAL_MULT ();
void SPECIAL_MULTU ();
void SPECIAL_DIV ();
void SPECIAL_DIVU ();
void SPECIAL_DMULT ();
void SPECIAL_DMULTU ();
void SPECIAL_DDIV ();
void SPECIAL_DDIVU ();
void SPECIAL_ADD ();
void SPECIAL_ADDU ();
void SPECIAL_SUB ();
void SPECIAL_SUBU ();
void SPECIAL_AND ();
void SPECIAL_OR ();
void SPECIAL_XOR ();
void SPECIAL_NOR ();
void SPECIAL_SLT ();
void SPECIAL_SLTU ();
void SPECIAL_DADD ();
void SPECIAL_DADDU ();
void SPECIAL_DSUB ();
void SPECIAL_DSUBU ();
void SPECIAL_DSLL ();
void SPECIAL_DSRL ();
void SPECIAL_DSRA ();
void SPECIAL_DSLL32 ();
void SPECIAL_DSRL32 ();
void SPECIAL_DSRA32 ();
/************************** COP0 functions **************************/
void COP0_MF ();
void COP0_MT ();
/************************** COP0 CO functions ***********************/
void COP0_CO_TLBR ();
void COP0_CO_TLBWI ();
void COP0_CO_TLBWR ();
void COP0_CO_TLBP ();
void COP0_CO_ERET ();
/************************** COP1 functions **************************/
void COP1_MF ();
void COP1_DMF ();
void COP1_CF ();
void COP1_MT ();
void COP1_DMT ();
void COP1_CT ();
/************************** COP1: S functions ************************/
void COP1_S_ADD ();
void COP1_S_SUB ();
void COP1_S_MUL ();
void COP1_S_DIV ();
void COP1_S_ABS ();
void COP1_S_NEG ();
void COP1_S_SQRT ();
void COP1_S_MOV ();
void COP1_S_ROUND_L ();
void COP1_S_TRUNC_L ();
void COP1_S_CEIL_L ();
void COP1_S_FLOOR_L ();
void COP1_S_ROUND_W ();
void COP1_S_TRUNC_W ();
void COP1_S_CEIL_W ();
void COP1_S_FLOOR_W ();
void COP1_S_CVT_D ();
void COP1_S_CVT_W ();
void COP1_S_CVT_L ();
void COP1_S_CMP ();
/************************** COP1: D functions ************************/
void COP1_D_ADD ();
void COP1_D_SUB ();
void COP1_D_MUL ();
void COP1_D_DIV ();
void COP1_D_ABS ();
void COP1_D_NEG ();
void COP1_D_SQRT ();
void COP1_D_MOV ();
void COP1_D_ROUND_L ();
void COP1_D_TRUNC_L ();
void COP1_D_CEIL_L ();
void COP1_D_FLOOR_L ();
void COP1_D_ROUND_W ();
void COP1_D_TRUNC_W ();
void COP1_D_CEIL_W ();
void COP1_D_FLOOR_W ();
void COP1_D_CVT_S ();
void COP1_D_CVT_W ();
void COP1_D_CVT_L ();
void COP1_D_CMP ();
/************************** COP1: W functions ************************/
void COP1_W_CVT_S ();
void COP1_W_CVT_D ();
/************************** COP1: L functions ************************/
void COP1_L_CVT_S ();
void COP1_L_CVT_D ();
/************************** Other functions **************************/
void UnknownOpcode ();
void EnterCodeBlock();
void ExitCodeBlock();
void CompileExitCode();
void CompileCop1Test();
void CompileInPermLoop(CRegInfo & RegSet, uint32_t ProgramCounter);
void SyncRegState(const CRegInfo & SyncTo);
CRegInfo & GetRegWorkingSet(void);
void SetRegWorkingSet(const CRegInfo & RegInfo);
bool InheritParentInfo();
void LinkJump(CJumpInfo & JumpInfo, uint32_t SectionID = -1, uint32_t FromSectionID = -1);
void JumpToSection( CCodeSection * Section);
void JumpToUnknown(CJumpInfo * JumpInfo);
void SetCurrentPC(uint32_t ProgramCounter);
uint32_t GetCurrentPC(void);
void SetCurrentSection(CCodeSection * section);
void SetNextStepType(STEP_TYPE StepType);
STEP_TYPE GetNextStepType( void );
const OPCODE & GetOpcode ( void ) const;
void PreCompileOpcode(void);
void PostCompileOpcode ( void );
void CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo &ExitRegSet, CExitInfo::EXIT_REASON reason);
void CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo &ExitRegSet, CExitInfo::EXIT_REASON reason, CArmOps::ArmBranchCompare CompareType);
static void UpdateSyncCPU(CRegInfo & RegSet, uint32_t Cycles);
void UpdateCounters(CRegInfo & RegSet, bool CheckTimer, bool ClearValues = false);
void CompileSystemCheck(uint32_t TargetPC, const CRegInfo & RegSet);
static bool IsKnown(int32_t Reg) { return false; }
static void ResetRegProtection()
{
//m_RegWorkingSet.ResetRegProtection();
}
inline void UnMap_GPR ( uint32_t Reg, bool WriteBackValue )
{
//m_RegWorkingSet.UnMap_GPR(Reg,WriteBackValue);
}
private:
void CompileInterpterCall (void * Function, const char * FunctionName);
void OverflowDelaySlot(bool TestTimer);
EXIT_LIST m_ExitInfo;
STEP_TYPE m_NextInstruction;
uint32_t m_CompilePC;
OPCODE m_Opcode;
CArmRegInfo m_RegWorkingSet;
CCodeSection * m_Section;
};
#endif

View File

@ -0,0 +1,52 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include "stdafx.h"
#if defined(__arm__) || defined(_M_ARM)
#include <Project64-core/N64System/Recompiler/Arm/ArmRegInfo.h>
CArmRegInfo::CArmRegInfo()
{
}
CArmRegInfo::CArmRegInfo(const CArmRegInfo& rhs)
{
*this = rhs;
}
CArmRegInfo::~CArmRegInfo()
{
}
CArmRegInfo& CArmRegInfo::operator=(const CArmRegInfo& right)
{
CRegBase::operator=(right);
#ifdef _DEBUG
if (*this != right)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
#endif
return *this;
}
void CArmRegInfo::BeforeCallDirect(void)
{
}
void CArmRegInfo::AfterCallDirect(void)
{
}
void CArmRegInfo::WriteBackRegisters()
{
}
#endif

View File

@ -9,7 +9,6 @@
* *
****************************************************************************/
#pragma once
#if defined(__arm__) || defined(_M_ARM)
#include <Project64-core/N64System/Recompiler/RegBase.h>
@ -17,7 +16,20 @@ class CArmRegInfo :
public CRegBase
{
public:
bool operator==(const CArmRegInfo& right) const;
};
CArmRegInfo();
CArmRegInfo(const CArmRegInfo&);
~CArmRegInfo();
CArmRegInfo& operator=(const CArmRegInfo&);
bool operator==(const CArmRegInfo& right) const;
bool operator!=(const CArmRegInfo& right) const;
void BeforeCallDirect(void);
void AfterCallDirect(void);
void WriteBackRegisters();
private:
};
#endif

View File

@ -13,6 +13,7 @@
#include <Project64-core/N64System/Recompiler/CodeBlock.h>
#include <Project64-core/N64System/Recompiler/RecompilerCodeLog.h>
#include <Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h>
#include <Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.h>
#include <Project64-core/N64System/SystemGlobals.h>
#include <Project64-core/N64System/Mips/TranslateVaddr.h>
#include <Project64-core/N64System/N64Class.h>
@ -20,6 +21,11 @@
bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
#if defined(ANDROID) && (defined(__arm__) || defined(_M_ARM))
/* bug-fix to implement __clear_cache (missing in Android; http://code.google.com/p/android/issues/detail?id=1803) */
extern "C" void __clear_cache_android(uint8_t* begin, uint8_t *end);
#endif
CCodeBlock::CCodeBlock(uint32_t VAddrEnter, uint8_t * CompiledLocation) :
m_VAddrEnter(VAddrEnter),
m_VAddrFirst(VAddrEnter),
@ -29,12 +35,22 @@ m_EnterSection(NULL),
m_RecompilerOps(NULL),
m_Test(1)
{
#if defined(__arm__) || defined(_M_ARM)
// make sure function starts at odd address so that the system knows it is thumb mode
if (((uint32_t)m_CompiledLocation % 2) == 0)
{
m_CompiledLocation+=1;
}
#endif
#if defined(__i386__) || defined(_M_IX86)
m_RecompilerOps = new CX86RecompilerOps;
#elif defined(__arm__) || defined(_M_ARM)
m_RecompilerOps = new CArmRecompilerOps;
#endif
if (m_RecompilerOps == NULL)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
CCodeSection * baseSection = new CCodeSection(this, VAddrEnter, 0, false);
if (baseSection == NULL)
@ -749,6 +765,9 @@ bool CCodeBlock::Compile()
g_TransVaddr->TranslateVaddr(VAddrFirst(), PAddr);
MD5(g_MMU->Rdram() + PAddr, (VAddrLast() - VAddrFirst()) + 4).get_digest(m_Hash);
#if defined(ANDROID) && (defined(__arm__) || defined(_M_ARM))
__clear_cache_android((uint8_t *)((uint32_t)m_CompiledLocation & ~1), (uint8_t *)(*g_RecompPos));
#endif
return true;
}

View File

@ -66,6 +66,9 @@
<ClCompile Include="N64System\N64DiskClass.cpp" />
<ClCompile Include="N64System\N64RomClass.cpp" />
<ClCompile Include="N64System\ProfilingClass.cpp" />
<ClCompile Include="N64System\Recompiler\Arm\ArmOps.cpp" />
<ClCompile Include="N64System\Recompiler\Arm\ArmRecompilerOps.cpp" />
<ClCompile Include="N64System\Recompiler\Arm\ArmRegInfo.cpp" />
<ClCompile Include="N64System\Recompiler\CodeBlock.cpp" />
<ClCompile Include="N64System\Recompiler\CodeSection.cpp" />
<ClCompile Include="N64System\Recompiler\FunctionInfo.cpp" />
@ -129,7 +132,6 @@
<ClInclude Include="Logging.h" />
<ClInclude Include="Multilanguage.h" />
<ClInclude Include="Multilanguage\LanguageClass.h" />
<ClInclude Include="N64System\Arm\ArmOpCode.h" />
<ClInclude Include="N64System\CheatClass.h" />
<ClInclude Include="N64System\FramePerSecondClass.h" />
<ClInclude Include="N64System\Interpreter\InterpreterCPU.h" />
@ -159,6 +161,9 @@
<ClInclude Include="N64System\N64RomClass.h" />
<ClInclude Include="N64System\N64Types.h" />
<ClInclude Include="N64System\ProfilingClass.h" />
<ClInclude Include="N64System\Recompiler\Arm\ArmOpCode.h" />
<ClInclude Include="N64System\Recompiler\Arm\ArmOps.h" />
<ClInclude Include="N64System\Recompiler\Arm\ArmRecompilerOps.h" />
<ClInclude Include="N64System\Recompiler\Arm\ArmRegInfo.h" />
<ClInclude Include="N64System\Recompiler\CodeBlock.h" />
<ClInclude Include="N64System\Recompiler\CodeSection.h" />

View File

@ -76,26 +76,17 @@
<Filter Include="Header Files\Rom List">
<UniqueIdentifier>{1030356f-55d6-4fef-9ee2-64c45b9c8ff2}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\N64 System\Arm">
<UniqueIdentifier>{8c526293-ee42-44b0-938f-f3c1cc18a986}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\N64 System\Recompiler\x86">
<UniqueIdentifier>{84d10022-4b24-4ba2-bfef-f85d16dfdc09}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\N64 System\Recompiler\x86">
<UniqueIdentifier>{b6d9fd3a-e8e5-42a2-8bcc-8fa430dd8aaa}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\N64 System\Recompiler\x64-86">
<UniqueIdentifier>{4a163a31-b1fb-4e50-b229-45d508dfc4a2}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\N64 System\Recompiler\Arm">
<UniqueIdentifier>{30c93ff6-032f-4702-9437-67b799f088af}</UniqueIdentifier>
<UniqueIdentifier>{cf6a56ff-5e83-49c8-af46-2d0eb9ff5abe}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\N64 System\Recompiler\Arm">
<UniqueIdentifier>{7ad7bbe7-44ed-4604-95c1-9af746e49e8e}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\N64 System\Recompiler\x64-86">
<UniqueIdentifier>{271c80e0-b4fa-4510-ae8b-1f0f2c88ab39}</UniqueIdentifier>
<UniqueIdentifier>{98453fda-8903-4074-8c4c-831c3f2bd63d}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
@ -306,9 +297,6 @@
<ClCompile Include="Multilanguage\LanguageClass.cpp">
<Filter>Source Files\Multilanguage</Filter>
</ClCompile>
<ClCompile Include="MemoryExceptionFilter.cpp">
<Filter>Source Files\N64 System</Filter>
</ClCompile>
<ClCompile Include="N64System\Mips\Disk.cpp">
<Filter>Source Files\N64 System\Mips</Filter>
</ClCompile>
@ -336,9 +324,21 @@
<ClCompile Include="N64System\Recompiler\x86\x86RegInfo.cpp">
<Filter>Source Files\N64 System\Recompiler\x86</Filter>
</ClCompile>
<ClCompile Include="MemoryExceptionFilter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="N64System\Recompiler\RegBase.cpp">
<Filter>Source Files\N64 System\Recompiler</Filter>
</ClCompile>
<ClCompile Include="N64System\Recompiler\Arm\ArmOps.cpp">
<Filter>Source Files\N64 System\Recompiler\Arm</Filter>
</ClCompile>
<ClCompile Include="N64System\Recompiler\Arm\ArmRecompilerOps.cpp">
<Filter>Source Files\N64 System\Recompiler\Arm</Filter>
</ClCompile>
<ClCompile Include="N64System\Recompiler\Arm\ArmRegInfo.cpp">
<Filter>Source Files\N64 System\Recompiler\Arm</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
@ -626,9 +626,6 @@
<ClInclude Include="RomList\RomList.h">
<Filter>Header Files\Rom List</Filter>
</ClInclude>
<ClInclude Include="N64System\Arm\ArmOpCode.h">
<Filter>Source Files\N64 System\Arm</Filter>
</ClInclude>
<ClInclude Include="N64System\Recompiler\RecompilerCodeLog.h">
<Filter>Header Files\N64 System\Recompiler</Filter>
</ClInclude>
@ -641,14 +638,17 @@
<ClInclude Include="N64System\Recompiler\x86\x86RegInfo.h">
<Filter>Header Files\N64 System\Recompiler\x86</Filter>
</ClInclude>
<ClInclude Include="N64System\Recompiler\RegBase.h">
<Filter>Header Files\N64 System\Recompiler</Filter>
<ClInclude Include="N64System\Recompiler\Arm\ArmOpCode.h">
<Filter>Header Files\N64 System\Recompiler\Arm</Filter>
</ClInclude>
<ClInclude Include="N64System\Recompiler\Arm\ArmOps.h">
<Filter>Header Files\N64 System\Recompiler\Arm</Filter>
</ClInclude>
<ClInclude Include="N64System\Recompiler\Arm\ArmRecompilerOps.h">
<Filter>Header Files\N64 System\Recompiler\Arm</Filter>
</ClInclude>
<ClInclude Include="N64System\Recompiler\Arm\ArmRegInfo.h">
<Filter>Header Files\N64 System\Recompiler\Arm</Filter>
</ClInclude>
<ClInclude Include="N64System\Recompiler\x64-86\x64RegInfo.h">
<Filter>Header Files\N64 System\Recompiler\x64-86</Filter>
</ClInclude>
</ItemGroup>
</Project>