Common: Clean up brace placements
This commit is contained in:
parent
77aef014a0
commit
ba4934b75e
|
@ -26,34 +26,43 @@
|
|||
namespace ArmGen
|
||||
{
|
||||
|
||||
inline u32 RotR(u32 a, int amount) {
|
||||
inline u32 RotR(u32 a, int amount)
|
||||
{
|
||||
if (!amount) return a;
|
||||
return (a >> amount) | (a << (32 - amount));
|
||||
}
|
||||
|
||||
inline u32 RotL(u32 a, int amount) {
|
||||
inline u32 RotL(u32 a, int amount)
|
||||
{
|
||||
if (!amount) return a;
|
||||
return (a << amount) | (a >> (32 - amount));
|
||||
}
|
||||
|
||||
bool TryMakeOperand2(u32 imm, Operand2 &op2) {
|
||||
bool TryMakeOperand2(u32 imm, Operand2 &op2)
|
||||
{
|
||||
// Just brute force it.
|
||||
for (int i = 0; i < 16; i++) {
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int mask = RotR(0xFF, i * 2);
|
||||
if ((imm & mask) == imm) {
|
||||
if ((imm & mask) == imm)
|
||||
{
|
||||
op2 = Operand2((u8)(RotL(imm, i * 2)), (u8)i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TryMakeOperand2_AllowInverse(u32 imm, Operand2 &op2, bool *inverse)
|
||||
{
|
||||
if (!TryMakeOperand2(imm, op2)) {
|
||||
if (!TryMakeOperand2(imm, op2))
|
||||
{
|
||||
*inverse = true;
|
||||
return TryMakeOperand2(~imm, op2);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
*inverse = false;
|
||||
return true;
|
||||
}
|
||||
|
@ -61,16 +70,20 @@ bool TryMakeOperand2_AllowInverse(u32 imm, Operand2 &op2, bool *inverse)
|
|||
|
||||
bool TryMakeOperand2_AllowNegation(s32 imm, Operand2 &op2, bool *negated)
|
||||
{
|
||||
if (!TryMakeOperand2(imm, op2)) {
|
||||
if (!TryMakeOperand2(imm, op2))
|
||||
{
|
||||
*negated = true;
|
||||
return TryMakeOperand2(-imm, op2);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
*negated = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Operand2 AssumeMakeOperand2(u32 imm) {
|
||||
Operand2 AssumeMakeOperand2(u32 imm)
|
||||
{
|
||||
Operand2 op2;
|
||||
bool result = TryMakeOperand2(imm, op2);
|
||||
(void) result;
|
||||
|
@ -93,8 +106,10 @@ bool ARMXEmitter::TrySetValue_TwoOp(ARMReg reg, u32 val)
|
|||
return false;
|
||||
|
||||
bool first = true;
|
||||
for (int i = 0; i < 16; i++, val >>=2) {
|
||||
if (val & 0x3) {
|
||||
for (int i = 0; i < 16; i++, val >>=2)
|
||||
{
|
||||
if (val & 0x3)
|
||||
{
|
||||
first ? MOV(reg, Operand2((u8)val, (u8)((16-i) & 0xF)))
|
||||
: ORR(reg, reg, Operand2((u8)val, (u8)((16-i) & 0xF)));
|
||||
first = false;
|
||||
|
@ -138,12 +153,15 @@ void ARMXEmitter::ADDI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch)
|
|||
{
|
||||
Operand2 op2;
|
||||
bool negated;
|
||||
if (TryMakeOperand2_AllowNegation(val, op2, &negated)) {
|
||||
if (TryMakeOperand2_AllowNegation(val, op2, &negated))
|
||||
{
|
||||
if (!negated)
|
||||
ADD(rd, rs, op2);
|
||||
else
|
||||
SUB(rd, rs, op2);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
MOVI2R(scratch, val);
|
||||
ADD(rd, rs, scratch);
|
||||
}
|
||||
|
@ -153,13 +171,19 @@ void ARMXEmitter::ANDI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch)
|
|||
{
|
||||
Operand2 op2;
|
||||
bool inverse;
|
||||
if (TryMakeOperand2_AllowInverse(val, op2, &inverse)) {
|
||||
if (!inverse) {
|
||||
if (TryMakeOperand2_AllowInverse(val, op2, &inverse))
|
||||
{
|
||||
if (!inverse)
|
||||
{
|
||||
AND(rd, rs, op2);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
BIC(rd, rs, op2);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
MOVI2R(scratch, val);
|
||||
AND(rd, rs, scratch);
|
||||
}
|
||||
|
@ -169,12 +193,15 @@ void ARMXEmitter::CMPI2R(ARMReg rs, u32 val, ARMReg scratch)
|
|||
{
|
||||
Operand2 op2;
|
||||
bool negated;
|
||||
if (TryMakeOperand2_AllowNegation(val, op2, &negated)) {
|
||||
if (TryMakeOperand2_AllowNegation(val, op2, &negated))
|
||||
{
|
||||
if (!negated)
|
||||
CMP(rs, op2);
|
||||
else
|
||||
CMN(rs, op2);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
MOVI2R(scratch, val);
|
||||
CMP(rs, scratch);
|
||||
}
|
||||
|
@ -183,9 +210,12 @@ void ARMXEmitter::CMPI2R(ARMReg rs, u32 val, ARMReg scratch)
|
|||
void ARMXEmitter::ORI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch)
|
||||
{
|
||||
Operand2 op2;
|
||||
if (TryMakeOperand2(val, op2)) {
|
||||
if (TryMakeOperand2(val, op2))
|
||||
{
|
||||
ORR(rd, rs, op2);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
MOVI2R(scratch, val);
|
||||
ORR(rd, rs, scratch);
|
||||
}
|
||||
|
@ -193,9 +223,11 @@ void ARMXEmitter::ORI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch)
|
|||
|
||||
void ARMXEmitter::FlushLitPool()
|
||||
{
|
||||
for (LiteralPool& pool : currentLitPool) {
|
||||
for (LiteralPool& pool : currentLitPool)
|
||||
{
|
||||
// Search for duplicates
|
||||
for (LiteralPool& old_pool : currentLitPool) {
|
||||
for (LiteralPool& old_pool : currentLitPool)
|
||||
{
|
||||
if (old_pool.val == pool.val)
|
||||
pool.loc = old_pool.loc;
|
||||
}
|
||||
|
@ -235,16 +267,21 @@ void ARMXEmitter::MOVI2R(ARMReg reg, u32 val, bool optimize)
|
|||
MOVW(reg, val & 0xFFFF);
|
||||
MOVT(reg, val, true);
|
||||
}
|
||||
else if (TryMakeOperand2_AllowInverse(val, op2, &inverse)) {
|
||||
else if (TryMakeOperand2_AllowInverse(val, op2, &inverse))
|
||||
{
|
||||
inverse ? MVN(reg, op2) : MOV(reg, op2);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cpu_info.bArmV7)
|
||||
{
|
||||
// Use MOVW+MOVT for ARMv7+
|
||||
MOVW(reg, val & 0xFFFF);
|
||||
if (val & 0xFFFF0000)
|
||||
MOVT(reg, val, true);
|
||||
} else if (!TrySetValue_TwoOp(reg,val)) {
|
||||
}
|
||||
else if (!TrySetValue_TwoOp(reg,val))
|
||||
{
|
||||
// Use literal pool for ARMv6.
|
||||
AddNewLit(val);
|
||||
LDR(reg, _PC); // To be backpatched later
|
||||
|
@ -252,10 +289,14 @@ void ARMXEmitter::MOVI2R(ARMReg reg, u32 val, bool optimize)
|
|||
}
|
||||
}
|
||||
|
||||
void ARMXEmitter::QuickCallFunction(ARMReg reg, void *func) {
|
||||
if (BLInRange(func)) {
|
||||
void ARMXEmitter::QuickCallFunction(ARMReg reg, void *func)
|
||||
{
|
||||
if (BLInRange(func))
|
||||
{
|
||||
BL(func);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
MOVI2R(reg, (u32)(func));
|
||||
BL(reg);
|
||||
}
|
||||
|
@ -327,7 +368,8 @@ void ARMXEmitter::SetCC(CCFlags cond)
|
|||
|
||||
void ARMXEmitter::NOP(int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++) {
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Write32(condition | 0x01A00000);
|
||||
}
|
||||
}
|
||||
|
@ -418,7 +460,8 @@ void ARMXEmitter::B(ARMReg src)
|
|||
Write32(condition | 0x12FFF10 | src);
|
||||
}
|
||||
|
||||
bool ARMXEmitter::BLInRange(const void *fnptr) {
|
||||
bool ARMXEmitter::BLInRange(const void *fnptr)
|
||||
{
|
||||
s32 distance = (s32)fnptr - (s32(code) + 8);
|
||||
if (distance <= -0x2000000 || distance > 0x2000000)
|
||||
return false;
|
||||
|
@ -602,7 +645,8 @@ void ARMXEmitter::MULS(ARMReg dest, ARMReg src, ARMReg op2)
|
|||
Write32(condition | (1 << 20) | (dest << 16) | (src << 8) | (9 << 4) | op2);
|
||||
}
|
||||
|
||||
void ARMXEmitter::Write4OpMultiply(u32 op, ARMReg destLo, ARMReg destHi, ARMReg rm, ARMReg rn) {
|
||||
void ARMXEmitter::Write4OpMultiply(u32 op, ARMReg destLo, ARMReg destHi, ARMReg rm, ARMReg rn)
|
||||
{
|
||||
Write32(condition | (op << 20) | (destHi << 16) | (destLo << 12) | (rm << 8) | (9 << 4) | rn);
|
||||
}
|
||||
|
||||
|
@ -1057,10 +1101,13 @@ void ARMXEmitter::VSTR(ARMReg Src, ARMReg Base, s16 offset)
|
|||
}
|
||||
}
|
||||
|
||||
void ARMXEmitter::VMRS(ARMReg Rt) {
|
||||
void ARMXEmitter::VMRS(ARMReg Rt)
|
||||
{
|
||||
Write32(condition | (0xEF << 20) | (1 << 16) | (Rt << 12) | 0xA10);
|
||||
}
|
||||
void ARMXEmitter::VMSR(ARMReg Rt) {
|
||||
|
||||
void ARMXEmitter::VMSR(ARMReg Rt)
|
||||
{
|
||||
Write32(condition | (0xEE << 20) | (1 << 16) | (Rt << 12) | 0xA10);
|
||||
}
|
||||
|
||||
|
@ -1191,26 +1238,33 @@ void ARMXEmitter::VCVT(ARMReg Dest, ARMReg Source, int flags)
|
|||
{
|
||||
Write32(condition | (0x1D << 23) | ((Dest & 0x10) << 18) | (0x7 << 19) \
|
||||
| ((Dest & 0xF) << 12) | (op << 7) | (0x2D << 6) | ((Source & 0x1) << 5) | (Source >> 1));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
Write32(condition | (0x1D << 23) | ((Dest & 0x1) << 22) | (0x7 << 19) | ((flags & TO_INT) << 18) | (op2 << 16) \
|
||||
| ((Dest & 0x1E) << 11) | (op << 7) | (0x2D << 6) | ((Source & 0x10) << 1) | (Source & 0xF));
|
||||
}
|
||||
}
|
||||
// F32<->F64
|
||||
else {
|
||||
else // F32<->F64
|
||||
{
|
||||
if (single_to_double)
|
||||
{
|
||||
Write32(condition | (0x1D << 23) | ((Dest & 0x10) << 18) | (0x3 << 20) | (0x7 << 16) \
|
||||
| ((Dest & 0xF) << 12) | (0x2B << 6) | ((Source & 0x1) << 5) | (Source >> 1));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
Write32(condition | (0x1D << 23) | ((Dest & 0x1) << 22) | (0x3 << 20) | (0x7 << 16) \
|
||||
| ((Dest & 0x1E) << 11) | (0x2F << 6) | ((Source & 0x10) << 1) | (Source & 0xF));
|
||||
}
|
||||
}
|
||||
} else if (single_reg) {
|
||||
} else if (single_reg)
|
||||
{
|
||||
Write32(condition | (0x1D << 23) | ((Dest & 0x1) << 22) | (0x7 << 19) | ((flags & TO_INT) << 18) | (op2 << 16) \
|
||||
| ((Dest & 0x1E) << 11) | (op << 7) | (0x29 << 6) | ((Source & 0x1) << 5) | (Source >> 1));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
Write32(condition | (0x1D << 23) | ((Dest & 0x10) << 18) | (0x7 << 19) | ((flags & TO_INT) << 18) | (op2 << 16) \
|
||||
| ((Dest & 0xF) << 12) | (1 << 8) | (op << 7) | (0x29 << 6) | ((Source & 0x10) << 1) | (Source & 0xF));
|
||||
}
|
||||
|
|
|
@ -25,23 +25,28 @@
|
|||
namespace Common
|
||||
{
|
||||
|
||||
inline void AtomicAdd(volatile u32& target, u32 value) {
|
||||
inline void AtomicAdd(volatile u32& target, u32 value)
|
||||
{
|
||||
__sync_add_and_fetch(&target, value);
|
||||
}
|
||||
|
||||
inline void AtomicAnd(volatile u32& target, u32 value) {
|
||||
inline void AtomicAnd(volatile u32& target, u32 value)
|
||||
{
|
||||
__sync_and_and_fetch(&target, value);
|
||||
}
|
||||
|
||||
inline void AtomicDecrement(volatile u32& target) {
|
||||
inline void AtomicDecrement(volatile u32& target)
|
||||
{
|
||||
__sync_add_and_fetch(&target, -1);
|
||||
}
|
||||
|
||||
inline void AtomicIncrement(volatile u32& target) {
|
||||
inline void AtomicIncrement(volatile u32& target)
|
||||
{
|
||||
__sync_add_and_fetch(&target, 1);
|
||||
}
|
||||
|
||||
inline void AtomicOr(volatile u32& target, u32 value) {
|
||||
inline void AtomicOr(volatile u32& target, u32 value)
|
||||
{
|
||||
__sync_or_and_fetch(&target, value);
|
||||
}
|
||||
|
||||
|
@ -63,27 +68,32 @@ _Atomic(T)* ToC11Atomic(volatile T* loc)
|
|||
#endif
|
||||
|
||||
template <typename T>
|
||||
inline T AtomicLoad(volatile T& src) {
|
||||
inline T AtomicLoad(volatile T& src)
|
||||
{
|
||||
return __atomic_load_n(&src, __ATOMIC_RELAXED);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T AtomicLoadAcquire(volatile T& src) {
|
||||
inline T AtomicLoadAcquire(volatile T& src)
|
||||
{
|
||||
return __atomic_load_n(&src, __ATOMIC_ACQUIRE);
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline void AtomicStore(volatile T& dest, U value) {
|
||||
inline void AtomicStore(volatile T& dest, U value)
|
||||
{
|
||||
__atomic_store_n(&dest, value, __ATOMIC_RELAXED);
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline void AtomicStoreRelease(volatile T& dest, U value) {
|
||||
inline void AtomicStoreRelease(volatile T& dest, U value)
|
||||
{
|
||||
__atomic_store_n(&dest, value, __ATOMIC_RELEASE);
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline T* AtomicExchangeAcquire(T* volatile& loc, U newval) {
|
||||
inline T* AtomicExchangeAcquire(T* volatile& loc, U newval)
|
||||
{
|
||||
return __atomic_exchange_n(&loc, newval, __ATOMIC_ACQ_REL);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,51 +32,61 @@
|
|||
namespace Common
|
||||
{
|
||||
|
||||
inline void AtomicAdd(volatile u32& target, u32 value) {
|
||||
inline void AtomicAdd(volatile u32& target, u32 value)
|
||||
{
|
||||
_InterlockedExchangeAdd((volatile LONG*)&target, (LONG)value);
|
||||
}
|
||||
|
||||
inline void AtomicAnd(volatile u32& target, u32 value) {
|
||||
inline void AtomicAnd(volatile u32& target, u32 value)
|
||||
{
|
||||
_InterlockedAnd((volatile LONG*)&target, (LONG)value);
|
||||
}
|
||||
|
||||
inline void AtomicIncrement(volatile u32& target) {
|
||||
inline void AtomicIncrement(volatile u32& target)
|
||||
{
|
||||
_InterlockedIncrement((volatile LONG*)&target);
|
||||
}
|
||||
|
||||
inline void AtomicDecrement(volatile u32& target) {
|
||||
inline void AtomicDecrement(volatile u32& target)
|
||||
{
|
||||
_InterlockedDecrement((volatile LONG*)&target);
|
||||
}
|
||||
|
||||
inline void AtomicOr(volatile u32& target, u32 value) {
|
||||
inline void AtomicOr(volatile u32& target, u32 value)
|
||||
{
|
||||
_InterlockedOr((volatile LONG*)&target, (LONG)value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T AtomicLoad(volatile T& src) {
|
||||
inline T AtomicLoad(volatile T& src)
|
||||
{
|
||||
return src; // 32-bit reads are always atomic.
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T AtomicLoadAcquire(volatile T& src) {
|
||||
inline T AtomicLoadAcquire(volatile T& src)
|
||||
{
|
||||
T result = src; // 32-bit reads are always atomic.
|
||||
_ReadBarrier(); // Compiler instruction only. x86 loads always have acquire semantics.
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline void AtomicStore(volatile T& dest, U value) {
|
||||
inline void AtomicStore(volatile T& dest, U value)
|
||||
{
|
||||
dest = (T) value; // 32-bit writes are always atomic.
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline void AtomicStoreRelease(volatile T& dest, U value) {
|
||||
inline void AtomicStoreRelease(volatile T& dest, U value)
|
||||
{
|
||||
_WriteBarrier(); // Compiler instruction only. x86 stores always have release semantics.
|
||||
dest = (T) value; // 32-bit writes are always atomic.
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline T* AtomicExchangeAcquire(T* volatile& loc, U newval) {
|
||||
inline T* AtomicExchangeAcquire(T* volatile& loc, U newval)
|
||||
{
|
||||
return (T*) _InterlockedExchangePointer_acq((void* volatile*) &loc, (void*) newval);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,11 +20,13 @@ struct TBreakPoint
|
|||
|
||||
struct TMemCheck
|
||||
{
|
||||
TMemCheck() {
|
||||
TMemCheck()
|
||||
{
|
||||
numHits = 0;
|
||||
StartAddress = EndAddress = 0;
|
||||
bRange = OnRead = OnWrite = Log = Break = false;
|
||||
}
|
||||
|
||||
u32 StartAddress;
|
||||
u32 EndAddress;
|
||||
|
||||
|
|
|
@ -74,25 +74,29 @@ _mm_shuffle_epi8(__m128i a, __m128i mask)
|
|||
// GCC 4.8 defines all the rotate functions now
|
||||
// Small issue with GCC's lrotl/lrotr intrinsics is they are still 32bit while we require 64bit
|
||||
#ifndef _rotl
|
||||
inline u32 _rotl(u32 x, int shift) {
|
||||
inline u32 _rotl(u32 x, int shift)
|
||||
{
|
||||
shift &= 31;
|
||||
if (!shift) return x;
|
||||
return (x << shift) | (x >> (32 - shift));
|
||||
}
|
||||
|
||||
inline u32 _rotr(u32 x, int shift) {
|
||||
inline u32 _rotr(u32 x, int shift)
|
||||
{
|
||||
shift &= 31;
|
||||
if (!shift) return x;
|
||||
return (x >> shift) | (x << (32 - shift));
|
||||
}
|
||||
#endif
|
||||
|
||||
inline u64 _rotl64(u64 x, unsigned int shift){
|
||||
inline u64 _rotl64(u64 x, unsigned int shift)
|
||||
{
|
||||
unsigned int n = shift % 64;
|
||||
return (x << n) | (x >> (64 - n));
|
||||
}
|
||||
|
||||
inline u64 _rotr64(u64 x, unsigned int shift){
|
||||
inline u64 _rotr64(u64 x, unsigned int shift)
|
||||
{
|
||||
unsigned int n = shift % 64;
|
||||
return (x >> n) | (x << (64 - n));
|
||||
}
|
||||
|
|
|
@ -92,7 +92,8 @@ static void InitSymbolPath( PSTR lpszSymbolPath, PCSTR lpszIniPath )
|
|||
}
|
||||
|
||||
// Uninitialize the loaded symbol files
|
||||
BOOL UninitSymInfo() {
|
||||
BOOL UninitSymInfo()
|
||||
{
|
||||
return SymCleanup( GetCurrentProcess() );
|
||||
}
|
||||
|
||||
|
|
|
@ -95,7 +95,8 @@ bool IsDirectory(const std::string &filename)
|
|||
int result = stat64(copy.c_str(), &file_info);
|
||||
#endif
|
||||
|
||||
if (result < 0) {
|
||||
if (result < 0)
|
||||
{
|
||||
WARN_LOG(COMMON, "IsDirectory: stat failed on %s: %s",
|
||||
filename.c_str(), GetLastErrorMsg());
|
||||
return false;
|
||||
|
@ -133,7 +134,8 @@ bool Delete(const std::string &filename)
|
|||
return false;
|
||||
}
|
||||
#else
|
||||
if (unlink(filename.c_str()) == -1) {
|
||||
if (unlink(filename.c_str()) == -1)
|
||||
{
|
||||
WARN_LOG(COMMON, "Delete: unlink failed on %s: %s",
|
||||
filename.c_str(), GetLastErrorMsg());
|
||||
return false;
|
||||
|
@ -413,7 +415,8 @@ u64 GetSize(const std::string &filename)
|
|||
u64 GetSize(const int fd)
|
||||
{
|
||||
struct stat64 buf;
|
||||
if (fstat64(fd, &buf) != 0) {
|
||||
if (fstat64(fd, &buf) != 0)
|
||||
{
|
||||
ERROR_LOG(COMMON, "GetSize: stat failed %i: %s",
|
||||
fd, GetLastErrorMsg());
|
||||
return 0;
|
||||
|
@ -426,17 +429,21 @@ u64 GetSize(FILE *f)
|
|||
{
|
||||
// can't use off_t here because it can be 32-bit
|
||||
u64 pos = ftello(f);
|
||||
if (fseeko(f, 0, SEEK_END) != 0) {
|
||||
if (fseeko(f, 0, SEEK_END) != 0)
|
||||
{
|
||||
ERROR_LOG(COMMON, "GetSize: seek failed %p: %s",
|
||||
f, GetLastErrorMsg());
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 size = ftello(f);
|
||||
if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0)) {
|
||||
if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0))
|
||||
{
|
||||
ERROR_LOG(COMMON, "GetSize: seek failed %p: %s",
|
||||
f, GetLastErrorMsg());
|
||||
return 0;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
@ -658,8 +665,8 @@ std::string GetCurrentDir()
|
|||
{
|
||||
char *dir;
|
||||
// Get the current working directory (getcwd uses malloc)
|
||||
if (!(dir = __getcwd(nullptr, 0))) {
|
||||
|
||||
if (!(dir = __getcwd(nullptr, 0)))
|
||||
{
|
||||
ERROR_LOG(COMMON, "GetCurrentDirectory failed: %s",
|
||||
GetLastErrorMsg());
|
||||
return nullptr;
|
||||
|
|
|
@ -36,13 +36,15 @@ public:
|
|||
delete [] storage;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
void clear()
|
||||
{
|
||||
head = 0;
|
||||
tail = 0;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
void push(T t) {
|
||||
void push(T t)
|
||||
{
|
||||
storage[tail] = t;
|
||||
tail++;
|
||||
if (tail == N)
|
||||
|
@ -50,14 +52,16 @@ public:
|
|||
count++;
|
||||
}
|
||||
|
||||
void pop() {
|
||||
void pop()
|
||||
{
|
||||
head++;
|
||||
if (head == N)
|
||||
head = 0;
|
||||
count--;
|
||||
}
|
||||
|
||||
T pop_front() {
|
||||
T pop_front()
|
||||
{
|
||||
const T &temp = storage[head];
|
||||
pop();
|
||||
return temp;
|
||||
|
@ -66,7 +70,8 @@ public:
|
|||
T &front() { return storage[head]; }
|
||||
const T &front() const { return storage[head]; }
|
||||
|
||||
size_t size() const {
|
||||
size_t size() const
|
||||
{
|
||||
return count;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -40,24 +40,31 @@ public:
|
|||
|
||||
bool Get(const std::string& key, std::string* value, const std::string& defaultValue = NULL_STRING);
|
||||
|
||||
void Set(const std::string& key, u32 newValue) {
|
||||
void Set(const std::string& key, u32 newValue)
|
||||
{
|
||||
Set(key, StringFromFormat("0x%08x", newValue));
|
||||
}
|
||||
void Set(const std::string& key, float newValue) {
|
||||
|
||||
void Set(const std::string& key, float newValue)
|
||||
{
|
||||
Set(key, StringFromFormat("%f", newValue));
|
||||
}
|
||||
|
||||
void Set(const std::string& key, const float newValue, const float defaultValue);
|
||||
void Set(const std::string& key, double newValue) {
|
||||
void Set(const std::string& key, double newValue)
|
||||
{
|
||||
Set(key, StringFromFormat("%f", newValue));
|
||||
}
|
||||
|
||||
void Set(const std::string& key, int newValue, int defaultValue);
|
||||
void Set(const std::string& key, int newValue) {
|
||||
void Set(const std::string& key, int newValue)
|
||||
{
|
||||
Set(key, StringFromInt(newValue));
|
||||
}
|
||||
|
||||
void Set(const std::string& key, bool newValue, bool defaultValue);
|
||||
void Set(const std::string& key, bool newValue) {
|
||||
void Set(const std::string& key, bool newValue)
|
||||
{
|
||||
Set(key, StringFromBool(newValue));
|
||||
}
|
||||
void Set(const std::string& key, const std::vector<std::string>& newValues);
|
||||
|
@ -69,7 +76,8 @@ public:
|
|||
bool Get(const std::string& key, double* value, double defaultValue = false);
|
||||
bool Get(const std::string& key, std::vector<std::string>* values);
|
||||
|
||||
bool operator < (const Section& other) const {
|
||||
bool operator < (const Section& other) const
|
||||
{
|
||||
return name < other.name;
|
||||
}
|
||||
|
||||
|
|
|
@ -152,7 +152,8 @@ u8* MemArena::Find4GBBase()
|
|||
#endif
|
||||
const u32 MemSize = 0x31000000;
|
||||
void* base = mmap(0, MemSize, PROT_NONE, flags, -1, 0);
|
||||
if (base == MAP_FAILED) {
|
||||
if (base == MAP_FAILED)
|
||||
{
|
||||
PanicAlert("Failed to map 1 GB of memory space: %s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
@ -170,7 +171,8 @@ u8* MemArena::Find4GBBase()
|
|||
continue; \
|
||||
|
||||
|
||||
static bool Memory_TryBase(u8 *base, const MemoryView *views, int num_views, u32 flags, MemArena *arena) {
|
||||
static bool Memory_TryBase(u8 *base, const MemoryView *views, int num_views, u32 flags, MemArena *arena)
|
||||
{
|
||||
// OK, we know where to find free space. Now grab it!
|
||||
// We just mimic the popular BAT setup.
|
||||
u32 position = 0;
|
||||
|
@ -189,9 +191,12 @@ static bool Memory_TryBase(u8 *base, const MemoryView *views, int num_views, u32
|
|||
for (i = 0; i < num_views; i++)
|
||||
{
|
||||
SKIP(flags, views[i].flags);
|
||||
if (views[i].flags & MV_MIRROR_PREVIOUS) {
|
||||
if (views[i].flags & MV_MIRROR_PREVIOUS)
|
||||
{
|
||||
position = last_position;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
*(views[i].out_ptr_low) = (u8*)arena->CreateView(position, views[i].size);
|
||||
if (!*views[i].out_ptr_low)
|
||||
goto bail;
|
||||
|
@ -200,10 +205,13 @@ static bool Memory_TryBase(u8 *base, const MemoryView *views, int num_views, u32
|
|||
*views[i].out_ptr = (u8*)arena->CreateView(
|
||||
position, views[i].size, base + views[i].virtual_address);
|
||||
#else
|
||||
if (views[i].flags & MV_MIRROR_PREVIOUS) {
|
||||
if (views[i].flags & MV_MIRROR_PREVIOUS)
|
||||
{
|
||||
// No need to create multiple identical views.
|
||||
*views[i].out_ptr = *views[i - 1].out_ptr;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
*views[i].out_ptr = (u8*)arena->CreateView(
|
||||
position, views[i].size, base + (views[i].virtual_address & 0x3FFFFFFF));
|
||||
if (!*views[i].out_ptr)
|
||||
|
|
|
@ -84,13 +84,15 @@ void SettingsHandler::Reset()
|
|||
|
||||
void SettingsHandler::AddSetting(const std::string& key, const std::string& value)
|
||||
{
|
||||
for (const char& c : key) {
|
||||
for (const char& c : key)
|
||||
{
|
||||
WriteByte(c);
|
||||
}
|
||||
|
||||
WriteByte('=');
|
||||
|
||||
for (const char& c : value) {
|
||||
for (const char& c : value)
|
||||
{
|
||||
WriteByte(c);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,22 +10,28 @@ using namespace Gen;
|
|||
|
||||
// Shared code between Win64 and Unix64
|
||||
|
||||
unsigned int XEmitter::ABI_GetAlignedFrameSize(unsigned int frameSize, bool noProlog) {
|
||||
unsigned int XEmitter::ABI_GetAlignedFrameSize(unsigned int frameSize, bool noProlog)
|
||||
{
|
||||
frameSize = noProlog ? 0x28 : 0;
|
||||
return frameSize;
|
||||
}
|
||||
|
||||
void XEmitter::ABI_AlignStack(unsigned int frameSize, bool noProlog) {
|
||||
unsigned int fillSize =
|
||||
ABI_GetAlignedFrameSize(frameSize, noProlog) - frameSize;
|
||||
if (fillSize != 0) {
|
||||
void XEmitter::ABI_AlignStack(unsigned int frameSize, bool noProlog)
|
||||
{
|
||||
unsigned int fillSize = ABI_GetAlignedFrameSize(frameSize, noProlog) - frameSize;
|
||||
|
||||
if (fillSize != 0)
|
||||
{
|
||||
SUB(64, R(RSP), Imm8(fillSize));
|
||||
}
|
||||
}
|
||||
|
||||
void XEmitter::ABI_RestoreStack(unsigned int frameSize, bool noProlog) {
|
||||
void XEmitter::ABI_RestoreStack(unsigned int frameSize, bool noProlog)
|
||||
{
|
||||
unsigned int alignedSize = ABI_GetAlignedFrameSize(frameSize, noProlog);
|
||||
if (alignedSize != 0) {
|
||||
|
||||
if (alignedSize != 0)
|
||||
{
|
||||
ADD(64, R(RSP), Imm8(alignedSize));
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +107,8 @@ void XEmitter::ABI_PopRegistersAndAdjustStack(u32 mask, bool noProlog)
|
|||
}
|
||||
|
||||
// Common functions
|
||||
void XEmitter::ABI_CallFunction(void *func) {
|
||||
void XEmitter::ABI_CallFunction(void *func)
|
||||
{
|
||||
ABI_AlignStack(0);
|
||||
u64 distance = u64(func) - (u64(code) + 5);
|
||||
if (distance >= 0x0000000080000000ULL &&
|
||||
|
@ -118,7 +125,8 @@ void XEmitter::ABI_CallFunction(void *func) {
|
|||
ABI_RestoreStack(0);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionC16(void *func, u16 param1) {
|
||||
void XEmitter::ABI_CallFunctionC16(void *func, u16 param1)
|
||||
{
|
||||
ABI_AlignStack(0);
|
||||
MOV(32, R(ABI_PARAM1), Imm32((u32)param1));
|
||||
u64 distance = u64(func) - (u64(code) + 5);
|
||||
|
@ -136,7 +144,8 @@ void XEmitter::ABI_CallFunctionC16(void *func, u16 param1) {
|
|||
ABI_RestoreStack(0);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionCC16(void *func, u32 param1, u16 param2) {
|
||||
void XEmitter::ABI_CallFunctionCC16(void *func, u32 param1, u16 param2)
|
||||
{
|
||||
ABI_AlignStack(0);
|
||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||
MOV(32, R(ABI_PARAM2), Imm32((u32)param2));
|
||||
|
@ -155,7 +164,8 @@ void XEmitter::ABI_CallFunctionCC16(void *func, u32 param1, u16 param2) {
|
|||
ABI_RestoreStack(0);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionC(void *func, u32 param1) {
|
||||
void XEmitter::ABI_CallFunctionC(void *func, u32 param1)
|
||||
{
|
||||
ABI_AlignStack(0);
|
||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||
u64 distance = u64(func) - (u64(code) + 5);
|
||||
|
@ -173,7 +183,8 @@ void XEmitter::ABI_CallFunctionC(void *func, u32 param1) {
|
|||
ABI_RestoreStack(0);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionCC(void *func, u32 param1, u32 param2) {
|
||||
void XEmitter::ABI_CallFunctionCC(void *func, u32 param1, u32 param2)
|
||||
{
|
||||
ABI_AlignStack(0);
|
||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
||||
|
@ -192,7 +203,8 @@ void XEmitter::ABI_CallFunctionCC(void *func, u32 param1, u32 param2) {
|
|||
ABI_RestoreStack(0);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionCP(void *func, u32 param1, void *param2) {
|
||||
void XEmitter::ABI_CallFunctionCP(void *func, u32 param1, void *param2)
|
||||
{
|
||||
ABI_AlignStack(0);
|
||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||
MOV(64, R(ABI_PARAM2), Imm64((u64)param2));
|
||||
|
@ -211,7 +223,8 @@ void XEmitter::ABI_CallFunctionCP(void *func, u32 param1, void *param2) {
|
|||
ABI_RestoreStack(0);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionCCC(void *func, u32 param1, u32 param2, u32 param3) {
|
||||
void XEmitter::ABI_CallFunctionCCC(void *func, u32 param1, u32 param2, u32 param3)
|
||||
{
|
||||
ABI_AlignStack(0);
|
||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
||||
|
@ -231,7 +244,8 @@ void XEmitter::ABI_CallFunctionCCC(void *func, u32 param1, u32 param2, u32 param
|
|||
ABI_RestoreStack(0);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionCCP(void *func, u32 param1, u32 param2, void *param3) {
|
||||
void XEmitter::ABI_CallFunctionCCP(void *func, u32 param1, u32 param2, void *param3)
|
||||
{
|
||||
ABI_AlignStack(0);
|
||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
||||
|
@ -251,7 +265,8 @@ void XEmitter::ABI_CallFunctionCCP(void *func, u32 param1, u32 param2, void *par
|
|||
ABI_RestoreStack(0);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionCCCP(void *func, u32 param1, u32 param2, u32 param3, void *param4) {
|
||||
void XEmitter::ABI_CallFunctionCCCP(void *func, u32 param1, u32 param2, u32 param3, void *param4)
|
||||
{
|
||||
ABI_AlignStack(0);
|
||||
MOV(32, R(ABI_PARAM1), Imm32(param1));
|
||||
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
||||
|
@ -272,7 +287,8 @@ void XEmitter::ABI_CallFunctionCCCP(void *func, u32 param1, u32 param2, u32 para
|
|||
ABI_RestoreStack(0);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionPC(void *func, void *param1, u32 param2) {
|
||||
void XEmitter::ABI_CallFunctionPC(void *func, void *param1, u32 param2)
|
||||
{
|
||||
ABI_AlignStack(0);
|
||||
MOV(64, R(ABI_PARAM1), Imm64((u64)param1));
|
||||
MOV(32, R(ABI_PARAM2), Imm32(param2));
|
||||
|
@ -291,7 +307,8 @@ void XEmitter::ABI_CallFunctionPC(void *func, void *param1, u32 param2) {
|
|||
ABI_RestoreStack(0);
|
||||
}
|
||||
|
||||
void XEmitter::ABI_CallFunctionPPC(void *func, void *param1, void *param2, u32 param3) {
|
||||
void XEmitter::ABI_CallFunctionPPC(void *func, void *param1, void *param2, u32 param3)
|
||||
{
|
||||
ABI_AlignStack(0);
|
||||
MOV(64, R(ABI_PARAM1), Imm64((u64)param1));
|
||||
MOV(64, R(ABI_PARAM2), Imm64((u64)param2));
|
||||
|
@ -312,7 +329,8 @@ void XEmitter::ABI_CallFunctionPPC(void *func, void *param1, void *param2, u32 p
|
|||
}
|
||||
|
||||
// Pass a register as a parameter.
|
||||
void XEmitter::ABI_CallFunctionR(void *func, X64Reg reg1) {
|
||||
void XEmitter::ABI_CallFunctionR(void *func, X64Reg reg1)
|
||||
{
|
||||
ABI_AlignStack(0);
|
||||
if (reg1 != ABI_PARAM1)
|
||||
MOV(32, R(ABI_PARAM1), R(reg1));
|
||||
|
@ -332,7 +350,8 @@ void XEmitter::ABI_CallFunctionR(void *func, X64Reg reg1) {
|
|||
}
|
||||
|
||||
// Pass two registers as parameters.
|
||||
void XEmitter::ABI_CallFunctionRR(void *func, X64Reg reg1, X64Reg reg2, bool noProlog) {
|
||||
void XEmitter::ABI_CallFunctionRR(void *func, X64Reg reg1, X64Reg reg2, bool noProlog)
|
||||
{
|
||||
ABI_AlignStack(0, noProlog);
|
||||
if (reg2 != ABI_PARAM1)
|
||||
{
|
||||
|
@ -407,7 +426,8 @@ void XEmitter::ABI_CallFunctionA(void *func, const Gen::OpArg &arg1)
|
|||
#ifdef _WIN32
|
||||
// Win64 Specific Code
|
||||
|
||||
void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack() {
|
||||
void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack()
|
||||
{
|
||||
//we only want to do this once
|
||||
PUSH(RBP);
|
||||
MOV(64, R(RBP), R(RSP));
|
||||
|
@ -422,7 +442,8 @@ void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack() {
|
|||
//TODO: Also preserve XMM0-3?
|
||||
}
|
||||
|
||||
void XEmitter::ABI_PopAllCalleeSavedRegsAndAdjustStack() {
|
||||
void XEmitter::ABI_PopAllCalleeSavedRegsAndAdjustStack()
|
||||
{
|
||||
ADD(64, R(RSP), Imm8(0x28));
|
||||
POP(R15);
|
||||
POP(R14);
|
||||
|
@ -437,7 +458,8 @@ void XEmitter::ABI_PopAllCalleeSavedRegsAndAdjustStack() {
|
|||
#else
|
||||
// Unix64 Specific Code
|
||||
|
||||
void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack() {
|
||||
void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack()
|
||||
{
|
||||
PUSH(RBP);
|
||||
MOV(64, R(RBP), R(RSP));
|
||||
PUSH(RBX);
|
||||
|
@ -448,7 +470,8 @@ void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack() {
|
|||
SUB(64, R(RSP), Imm8(8));
|
||||
}
|
||||
|
||||
void XEmitter::ABI_PopAllCalleeSavedRegsAndAdjustStack() {
|
||||
void XEmitter::ABI_PopAllCalleeSavedRegsAndAdjustStack()
|
||||
{
|
||||
ADD(64, R(RSP), Imm8(8));
|
||||
POP(R15);
|
||||
POP(R14);
|
||||
|
|
|
@ -143,7 +143,8 @@ void OpArg::WriteRex(XEmitter *emit, int opBits, int bits, int customOp) const
|
|||
// SIL, DIL, BPL, or SPL.
|
||||
if (op != 0x40 ||
|
||||
(scale == SCALE_NONE && bits == 8 && (offsetOrBaseReg & 0x10c) == 4) ||
|
||||
(opBits == 8 && (customOp & 0x10c) == 4)) {
|
||||
(opBits == 8 && (customOp & 0x10c) == 4))
|
||||
{
|
||||
emit->Write8(op);
|
||||
// Check the operation doesn't access AH, BH, CH, or DH.
|
||||
_dbg_assert_(DYNA_REC, (offsetOrBaseReg & 0x100) == 0);
|
||||
|
@ -773,7 +774,8 @@ void XEmitter::BSR(int bits, X64Reg dest, OpArg src) {WriteBitSearchType(bits,de
|
|||
void XEmitter::MOVSX(int dbits, int sbits, X64Reg dest, OpArg src)
|
||||
{
|
||||
if (src.IsImm()) _assert_msg_(DYNA_REC, 0, "MOVSX - Imm argument");
|
||||
if (dbits == sbits) {
|
||||
if (dbits == sbits)
|
||||
{
|
||||
MOV(dbits, R(dest), src);
|
||||
return;
|
||||
}
|
||||
|
@ -804,7 +806,8 @@ void XEmitter::MOVSX(int dbits, int sbits, X64Reg dest, OpArg src)
|
|||
void XEmitter::MOVZX(int dbits, int sbits, X64Reg dest, OpArg src)
|
||||
{
|
||||
if (src.IsImm()) _assert_msg_(DYNA_REC, 0, "MOVZX - Imm argument");
|
||||
if (dbits == sbits) {
|
||||
if (dbits == sbits)
|
||||
{
|
||||
MOV(dbits, R(dest), src);
|
||||
return;
|
||||
}
|
||||
|
@ -1181,14 +1184,18 @@ void XEmitter::XCHG(int bits, const OpArg &a1, const OpArg &a2) {WriteNormalOp(t
|
|||
|
||||
void XEmitter::IMUL(int bits, X64Reg regOp, OpArg a1, OpArg a2)
|
||||
{
|
||||
if (bits == 8) {
|
||||
if (bits == 8)
|
||||
{
|
||||
_assert_msg_(DYNA_REC, 0, "IMUL - illegal bit size!");
|
||||
return;
|
||||
}
|
||||
if (a1.IsImm()) {
|
||||
|
||||
if (a1.IsImm())
|
||||
{
|
||||
_assert_msg_(DYNA_REC, 0, "IMUL - second arg cannot be imm!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!a2.IsImm())
|
||||
{
|
||||
_assert_msg_(DYNA_REC, 0, "IMUL - third arg must be imm!");
|
||||
|
@ -1201,20 +1208,27 @@ void XEmitter::IMUL(int bits, X64Reg regOp, OpArg a1, OpArg a2)
|
|||
|
||||
if (a2.GetImmBits() == 8 ||
|
||||
(a2.GetImmBits() == 16 && (s8)a2.offset == (s16)a2.offset) ||
|
||||
(a2.GetImmBits() == 32 && (s8)a2.offset == (s32)a2.offset)) {
|
||||
(a2.GetImmBits() == 32 && (s8)a2.offset == (s32)a2.offset))
|
||||
{
|
||||
Write8(0x6B);
|
||||
a1.WriteRest(this, 1, regOp);
|
||||
Write8((u8)a2.offset);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
Write8(0x69);
|
||||
if (a2.GetImmBits() == 16 && bits == 16) {
|
||||
if (a2.GetImmBits() == 16 && bits == 16)
|
||||
{
|
||||
a1.WriteRest(this, 2, regOp);
|
||||
Write16((u16)a2.offset);
|
||||
} else if (a2.GetImmBits() == 32 &&
|
||||
(bits == 32 || bits == 64)) {
|
||||
}
|
||||
else if (a2.GetImmBits() == 32 && (bits == 32 || bits == 64))
|
||||
{
|
||||
a1.WriteRest(this, 4, regOp);
|
||||
Write32((u32)a2.offset);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
_assert_msg_(DYNA_REC, 0, "IMUL - unhandled case!");
|
||||
}
|
||||
}
|
||||
|
@ -1222,10 +1236,12 @@ void XEmitter::IMUL(int bits, X64Reg regOp, OpArg a1, OpArg a2)
|
|||
|
||||
void XEmitter::IMUL(int bits, X64Reg regOp, OpArg a)
|
||||
{
|
||||
if (bits == 8) {
|
||||
if (bits == 8)
|
||||
{
|
||||
_assert_msg_(DYNA_REC, 0, "IMUL - illegal bit size!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (a.IsImm())
|
||||
{
|
||||
IMUL(bits, regOp, R(regOp), a) ;
|
||||
|
@ -1283,7 +1299,8 @@ void XEmitter::WriteAVXOp(int size, u16 sseOp, bool packed, X64Reg regOp1, X64Re
|
|||
void XEmitter::MOVD_xmm(X64Reg dest, const OpArg &arg) {WriteSSEOp(64, 0x6E, true, dest, arg, 0);}
|
||||
void XEmitter::MOVD_xmm(const OpArg &arg, X64Reg src) {WriteSSEOp(64, 0x7E, true, src, arg, 0);}
|
||||
|
||||
void XEmitter::MOVQ_xmm(X64Reg dest, OpArg arg) {
|
||||
void XEmitter::MOVQ_xmm(X64Reg dest, OpArg arg)
|
||||
{
|
||||
// Alternate encoding
|
||||
// This does not display correctly in MSVC's debugger, it thinks it's a MOVD
|
||||
arg.operandReg = dest;
|
||||
|
@ -1294,7 +1311,8 @@ void XEmitter::MOVQ_xmm(X64Reg dest, OpArg arg) {
|
|||
arg.WriteRest(this, 0);
|
||||
}
|
||||
|
||||
void XEmitter::MOVQ_xmm(OpArg arg, X64Reg src) {
|
||||
void XEmitter::MOVQ_xmm(OpArg arg, X64Reg src)
|
||||
{
|
||||
if (src > 7 || arg.IsSimpleReg())
|
||||
{
|
||||
// Alternate encoding
|
||||
|
@ -1305,7 +1323,9 @@ void XEmitter::MOVQ_xmm(OpArg arg, X64Reg src) {
|
|||
Write8(0x0f);
|
||||
Write8(0x7E);
|
||||
arg.WriteRest(this, 0);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
arg.operandReg = src;
|
||||
arg.WriteRex(this, 0, 0);
|
||||
Write8(0x66);
|
||||
|
@ -1466,42 +1486,50 @@ void XEmitter::PUNPCKLWD(X64Reg dest, const OpArg &arg) {WriteSSEOp(64, 0x61, tr
|
|||
void XEmitter::PUNPCKLDQ(X64Reg dest, const OpArg &arg) {WriteSSEOp(64, 0x62, true, dest, arg);}
|
||||
//void PUNPCKLQDQ(X64Reg dest, OpArg arg) {WriteSSEOp(64, 0x60, true, dest, arg);}
|
||||
|
||||
void XEmitter::PSRLW(X64Reg reg, int shift) {
|
||||
void XEmitter::PSRLW(X64Reg reg, int shift)
|
||||
{
|
||||
WriteSSEOp(64, 0x71, true, (X64Reg)2, R(reg));
|
||||
Write8(shift);
|
||||
}
|
||||
|
||||
void XEmitter::PSRLD(X64Reg reg, int shift) {
|
||||
void XEmitter::PSRLD(X64Reg reg, int shift)
|
||||
{
|
||||
WriteSSEOp(64, 0x72, true, (X64Reg)2, R(reg));
|
||||
Write8(shift);
|
||||
}
|
||||
|
||||
void XEmitter::PSRLQ(X64Reg reg, int shift) {
|
||||
void XEmitter::PSRLQ(X64Reg reg, int shift)
|
||||
{
|
||||
WriteSSEOp(64, 0x73, true, (X64Reg)2, R(reg));
|
||||
Write8(shift);
|
||||
}
|
||||
|
||||
void XEmitter::PSRLQ(X64Reg reg, OpArg arg) {
|
||||
void XEmitter::PSRLQ(X64Reg reg, OpArg arg)
|
||||
{
|
||||
WriteSSEOp(64, 0xd3, true, reg, arg);
|
||||
}
|
||||
|
||||
void XEmitter::PSLLW(X64Reg reg, int shift) {
|
||||
void XEmitter::PSLLW(X64Reg reg, int shift)
|
||||
{
|
||||
WriteSSEOp(64, 0x71, true, (X64Reg)6, R(reg));
|
||||
Write8(shift);
|
||||
}
|
||||
|
||||
void XEmitter::PSLLD(X64Reg reg, int shift) {
|
||||
void XEmitter::PSLLD(X64Reg reg, int shift)
|
||||
{
|
||||
WriteSSEOp(64, 0x72, true, (X64Reg)6, R(reg));
|
||||
Write8(shift);
|
||||
}
|
||||
|
||||
void XEmitter::PSLLQ(X64Reg reg, int shift) {
|
||||
void XEmitter::PSLLQ(X64Reg reg, int shift)
|
||||
{
|
||||
WriteSSEOp(64, 0x73, true, (X64Reg)6, R(reg));
|
||||
Write8(shift);
|
||||
}
|
||||
|
||||
// WARNING not REX compatible
|
||||
void XEmitter::PSRAW(X64Reg reg, int shift) {
|
||||
void XEmitter::PSRAW(X64Reg reg, int shift)
|
||||
{
|
||||
if (reg > 7)
|
||||
PanicAlert("The PSRAW-emitter does not support regs above 7");
|
||||
Write8(0x66);
|
||||
|
@ -1512,7 +1540,8 @@ void XEmitter::PSRAW(X64Reg reg, int shift) {
|
|||
}
|
||||
|
||||
// WARNING not REX compatible
|
||||
void XEmitter::PSRAD(X64Reg reg, int shift) {
|
||||
void XEmitter::PSRAD(X64Reg reg, int shift)
|
||||
{
|
||||
if (reg > 7)
|
||||
PanicAlert("The PSRAD-emitter does not support regs above 7");
|
||||
Write8(0x66);
|
||||
|
@ -1632,11 +1661,14 @@ void XEmitter::FWAIT()
|
|||
void XEmitter::WriteFloatLoadStore(int bits, FloatOp op, OpArg arg)
|
||||
{
|
||||
int mf = 0;
|
||||
switch (bits) {
|
||||
|
||||
switch (bits)
|
||||
{
|
||||
case 32: mf = 0; break;
|
||||
case 64: mf = 2; break;
|
||||
default: _assert_msg_(DYNA_REC, 0, "WriteFloatLoadStore: bits is not 32 or 64");
|
||||
}
|
||||
|
||||
Write8(0xd9 | (mf << 1));
|
||||
// x87 instructions use the reg field of the ModR/M byte as opcode:
|
||||
arg.WriteRest(this, 0, (X64Reg) op);
|
||||
|
@ -1727,20 +1759,23 @@ void XEmitter::CallCdeclFunction6(void* fnptr, u32 arg0, u32 arg1, u32 arg2, u32
|
|||
}
|
||||
|
||||
// See header
|
||||
void XEmitter::___CallCdeclImport3(void* impptr, u32 arg0, u32 arg1, u32 arg2) {
|
||||
void XEmitter::___CallCdeclImport3(void* impptr, u32 arg0, u32 arg1, u32 arg2)
|
||||
{
|
||||
MOV(32, R(RCX), Imm32(arg0));
|
||||
MOV(32, R(RDX), Imm32(arg1));
|
||||
MOV(32, R(R8), Imm32(arg2));
|
||||
CALLptr(M(impptr));
|
||||
}
|
||||
void XEmitter::___CallCdeclImport4(void* impptr, u32 arg0, u32 arg1, u32 arg2, u32 arg3) {
|
||||
void XEmitter::___CallCdeclImport4(void* impptr, u32 arg0, u32 arg1, u32 arg2, u32 arg3)
|
||||
{
|
||||
MOV(32, R(RCX), Imm32(arg0));
|
||||
MOV(32, R(RDX), Imm32(arg1));
|
||||
MOV(32, R(R8), Imm32(arg2));
|
||||
MOV(32, R(R9), Imm32(arg3));
|
||||
CALLptr(M(impptr));
|
||||
}
|
||||
void XEmitter::___CallCdeclImport5(void* impptr, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4) {
|
||||
void XEmitter::___CallCdeclImport5(void* impptr, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
|
||||
{
|
||||
MOV(32, R(RCX), Imm32(arg0));
|
||||
MOV(32, R(RDX), Imm32(arg1));
|
||||
MOV(32, R(R8), Imm32(arg2));
|
||||
|
@ -1748,7 +1783,8 @@ void XEmitter::___CallCdeclImport5(void* impptr, u32 arg0, u32 arg1, u32 arg2, u
|
|||
MOV(32, MDisp(RSP, 0x20), Imm32(arg4));
|
||||
CALLptr(M(impptr));
|
||||
}
|
||||
void XEmitter::___CallCdeclImport6(void* impptr, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4, u32 arg5) {
|
||||
void XEmitter::___CallCdeclImport6(void* impptr, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
|
||||
{
|
||||
MOV(32, R(RCX), Imm32(arg0));
|
||||
MOV(32, R(RDX), Imm32(arg1));
|
||||
MOV(32, R(R8), Imm32(arg2));
|
||||
|
|
|
@ -134,7 +134,8 @@ struct OpArg
|
|||
void WriteNormalOp(XEmitter *emit, bool toRM, NormalOp op, const OpArg &operand, int bits) const;
|
||||
bool IsImm() const {return scale == SCALE_IMM8 || scale == SCALE_IMM16 || scale == SCALE_IMM32 || scale == SCALE_IMM64;}
|
||||
bool IsSimpleReg() const {return scale == SCALE_NONE;}
|
||||
bool IsSimpleReg(X64Reg reg) const {
|
||||
bool IsSimpleReg(X64Reg reg) const
|
||||
{
|
||||
if (!IsSimpleReg())
|
||||
return false;
|
||||
return GetSimpleReg() == reg;
|
||||
|
@ -175,21 +176,30 @@ private:
|
|||
inline OpArg M(const void *ptr) {return OpArg((u64)ptr, (int)SCALE_RIP);}
|
||||
inline OpArg R(X64Reg value) {return OpArg(0, SCALE_NONE, value);}
|
||||
inline OpArg MatR(X64Reg value) {return OpArg(0, SCALE_ATREG, value);}
|
||||
inline OpArg MDisp(X64Reg value, int offset) {
|
||||
|
||||
inline OpArg MDisp(X64Reg value, int offset)
|
||||
{
|
||||
return OpArg((u32)offset, SCALE_ATREG, value);
|
||||
}
|
||||
inline OpArg MComplex(X64Reg base, X64Reg scaled, int scale, int offset) {
|
||||
|
||||
inline OpArg MComplex(X64Reg base, X64Reg scaled, int scale, int offset)
|
||||
{
|
||||
return OpArg(offset, scale, base, scaled);
|
||||
}
|
||||
inline OpArg MScaled(X64Reg scaled, int scale, int offset) {
|
||||
|
||||
inline OpArg MScaled(X64Reg scaled, int scale, int offset)
|
||||
{
|
||||
if (scale == SCALE_1)
|
||||
return OpArg(offset, SCALE_ATREG, scaled);
|
||||
else
|
||||
return OpArg(offset, scale | 0x20, RAX, scaled);
|
||||
}
|
||||
inline OpArg MRegSum(X64Reg base, X64Reg offset) {
|
||||
|
||||
inline OpArg MRegSum(X64Reg base, X64Reg offset)
|
||||
{
|
||||
return MComplex(base, offset, 1, 0);
|
||||
}
|
||||
|
||||
inline OpArg Imm8 (u8 imm) {return OpArg(imm, SCALE_IMM8);}
|
||||
inline OpArg Imm16(u16 imm) {return OpArg(imm, SCALE_IMM16);} //rarely used
|
||||
inline OpArg Imm32(u32 imm) {return OpArg(imm, SCALE_IMM32);}
|
||||
|
@ -199,14 +209,18 @@ inline OpArg ImmPtr(const void* imm) {return Imm64((u64)imm);}
|
|||
#else
|
||||
inline OpArg ImmPtr(const void* imm) {return Imm32((u32)imm);}
|
||||
#endif
|
||||
inline u32 PtrOffset(void* ptr, void* base) {
|
||||
|
||||
inline u32 PtrOffset(void* ptr, void* base)
|
||||
{
|
||||
#ifdef _ARCH_64
|
||||
s64 distance = (s64)ptr-(s64)base;
|
||||
if (distance >= 0x80000000LL ||
|
||||
distance < -0x80000000LL) {
|
||||
distance < -0x80000000LL)
|
||||
{
|
||||
_assert_msg_(DYNA_REC, 0, "pointer offset out of range");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (u32)distance;
|
||||
#else
|
||||
return (u32)ptr-(u32)base;
|
||||
|
|
Loading…
Reference in New Issue