Merge branch 'master' into d3d12
This commit is contained in:
@@ -187,7 +187,7 @@ uint64_t ReadCapstoneReg(X64Context* context, x86_reg reg) {
|
||||
#define X86_EFLAGS_SF 0x00000080 // Sign Flag
|
||||
#define X86_EFLAGS_OF 0x00000800 // Overflow Flag
|
||||
bool TestCapstoneEflags(uint32_t eflags, uint32_t insn) {
|
||||
// http://www.felixcloutier.com/x86/Jcc.html
|
||||
// https://www.felixcloutier.com/x86/Jcc.html
|
||||
switch (insn) {
|
||||
case X86_INS_JAE:
|
||||
// CF=0 && ZF=0
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace cpu {
|
||||
namespace backend {
|
||||
namespace x64 {
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ssa62fwe.aspx
|
||||
// https://msdn.microsoft.com/en-us/library/ssa62fwe.aspx
|
||||
typedef enum _UNWIND_OP_CODES {
|
||||
UWOP_PUSH_NONVOL = 0, /* info == register number */
|
||||
UWOP_ALLOC_LARGE, /* no info, alloc size in next 2 slots */
|
||||
@@ -242,7 +242,7 @@ void Win32X64CodeCache::InitializeUnwindEntry(uint8_t* unwind_entry_address,
|
||||
UNWIND_CODE* unwind_code = nullptr;
|
||||
|
||||
if (!stack_size) {
|
||||
// http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
|
||||
// https://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
|
||||
unwind_info->Version = 1;
|
||||
unwind_info->Flags = 0;
|
||||
unwind_info->SizeOfProlog = 0;
|
||||
@@ -252,7 +252,7 @@ void Win32X64CodeCache::InitializeUnwindEntry(uint8_t* unwind_entry_address,
|
||||
} else if (stack_size <= 128) {
|
||||
uint8_t prolog_size = 4;
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
|
||||
// https://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
|
||||
unwind_info->Version = 1;
|
||||
unwind_info->Flags = 0;
|
||||
unwind_info->SizeOfProlog = prolog_size;
|
||||
@@ -260,7 +260,7 @@ void Win32X64CodeCache::InitializeUnwindEntry(uint8_t* unwind_entry_address,
|
||||
unwind_info->FrameRegister = 0;
|
||||
unwind_info->FrameOffset = 0;
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ck9asaa9.aspx
|
||||
// https://msdn.microsoft.com/en-us/library/ck9asaa9.aspx
|
||||
unwind_code = &unwind_info->UnwindCode[unwind_info->CountOfCodes++];
|
||||
unwind_code->CodeOffset =
|
||||
14; // end of instruction + 1 == offset of next instruction
|
||||
@@ -270,7 +270,7 @@ void Win32X64CodeCache::InitializeUnwindEntry(uint8_t* unwind_entry_address,
|
||||
// TODO(benvanik): take as parameters?
|
||||
uint8_t prolog_size = 7;
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
|
||||
// https://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
|
||||
unwind_info->Version = 1;
|
||||
unwind_info->Flags = 0;
|
||||
unwind_info->SizeOfProlog = prolog_size;
|
||||
@@ -278,7 +278,7 @@ void Win32X64CodeCache::InitializeUnwindEntry(uint8_t* unwind_entry_address,
|
||||
unwind_info->FrameRegister = 0;
|
||||
unwind_info->FrameOffset = 0;
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ck9asaa9.aspx
|
||||
// https://msdn.microsoft.com/en-us/library/ck9asaa9.aspx
|
||||
unwind_code = &unwind_info->UnwindCode[unwind_info->CountOfCodes++];
|
||||
unwind_code->CodeOffset =
|
||||
7; // end of instruction + 1 == offset of next instruction
|
||||
|
||||
@@ -82,7 +82,7 @@ X64Emitter::X64Emitter(X64Backend* backend, XbyakAllocator* allocator)
|
||||
if (!cpu_.has(Xbyak::util::Cpu::tAVX)) {
|
||||
xe::FatalError(
|
||||
"Your CPU is too old to support Xenia. See the FAQ for system "
|
||||
"requirements at http://xenia.jp");
|
||||
"requirements at https://xenia.jp");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -160,7 +160,7 @@ bool X64Emitter::Emit(HIRBuilder* builder, size_t* out_stack_size) {
|
||||
// Function prolog.
|
||||
// Must be 16b aligned.
|
||||
// Windows is very strict about the form of this and the epilog:
|
||||
// http://msdn.microsoft.com/en-us/library/tawsa7cb.aspx
|
||||
// https://msdn.microsoft.com/en-us/library/tawsa7cb.aspx
|
||||
// IMPORTANT: any changes to the prolog must be kept in sync with
|
||||
// X64CodeCache, which dynamically generates exception information.
|
||||
// Adding or changing anything here must be matched!
|
||||
@@ -738,7 +738,7 @@ Xbyak::Address X64Emitter::GetXmmConstPtr(XmmConst id) {
|
||||
}
|
||||
|
||||
void X64Emitter::LoadConstantXmm(Xbyak::Xmm dest, const vec128_t& v) {
|
||||
// http://www.agner.org/optimize/optimizing_assembly.pdf
|
||||
// https://www.agner.org/optimize/optimizing_assembly.pdf
|
||||
// 13.4 Generating constants
|
||||
if (!v.low && !v.high) {
|
||||
// 0000...
|
||||
|
||||
@@ -3367,7 +3367,8 @@ EMITTER_ASSOCIATIVE_COMPARE_XX(ULE, setbe, setae);
|
||||
EMITTER_ASSOCIATIVE_COMPARE_XX(UGT, seta, setb);
|
||||
EMITTER_ASSOCIATIVE_COMPARE_XX(UGE, setae, setbe);
|
||||
|
||||
// http://x86.renejeschke.de/html/file_module_x86_id_288.html
|
||||
// https://web.archive.org/web/20171129015931/https://x86.renejeschke.de/html/file_module_x86_id_288.html
|
||||
// Original link: https://x86.renejeschke.de/html/file_module_x86_id_288.html
|
||||
#define EMITTER_ASSOCIATIVE_COMPARE_FLT_XX(op, instr) \
|
||||
struct COMPARE_##op##_F32 \
|
||||
: Sequence<COMPARE_##op##_F32, \
|
||||
@@ -3793,7 +3794,7 @@ struct VECTOR_ADD
|
||||
// If result is smaller than either of the inputs, we've
|
||||
// overflowed (only need to check one input)
|
||||
// if (src1 > res) then overflowed
|
||||
// http://locklessinc.com/articles/sat_arithmetic/
|
||||
// https://locklessinc.com/articles/sat_arithmetic/
|
||||
e.vpxor(e.xmm2, src1, e.GetXmmConstPtr(XMMSignMaskI32));
|
||||
e.vpxor(e.xmm0, e.xmm1, e.GetXmmConstPtr(XMMSignMaskI32));
|
||||
e.vpcmpgtd(e.xmm0, e.xmm2, e.xmm0);
|
||||
@@ -3804,7 +3805,7 @@ struct VECTOR_ADD
|
||||
// Overflow results if two inputs are the same sign and the
|
||||
// result isn't the same sign. if ((s32b)(~(src1 ^ src2) &
|
||||
// (src1 ^ res)) < 0) then overflowed
|
||||
// http://locklessinc.com/articles/sat_arithmetic/
|
||||
// https://locklessinc.com/articles/sat_arithmetic/
|
||||
e.vpxor(e.xmm2, src1, src2);
|
||||
e.vpxor(e.xmm3, src1, e.xmm1);
|
||||
e.vpandn(e.xmm2, e.xmm2, e.xmm3);
|
||||
@@ -3950,7 +3951,7 @@ struct VECTOR_SUB
|
||||
// If result is greater than either of the inputs, we've
|
||||
// underflowed (only need to check one input)
|
||||
// if (res > src1) then underflowed
|
||||
// http://locklessinc.com/articles/sat_arithmetic/
|
||||
// https://locklessinc.com/articles/sat_arithmetic/
|
||||
e.vpxor(e.xmm2, src1, e.GetXmmConstPtr(XMMSignMaskI32));
|
||||
e.vpxor(e.xmm0, e.xmm1, e.GetXmmConstPtr(XMMSignMaskI32));
|
||||
e.vpcmpgtd(e.xmm0, e.xmm0, e.xmm2);
|
||||
@@ -3962,7 +3963,7 @@ struct VECTOR_SUB
|
||||
// opposite. If signs are opposite and result sign isn't the
|
||||
// same as src1's sign, we've overflowed. if ((s32b)((src1 ^
|
||||
// src2) & (src1 ^ res)) < 0) then overflowed
|
||||
// http://locklessinc.com/articles/sat_arithmetic/
|
||||
// https://locklessinc.com/articles/sat_arithmetic/
|
||||
e.vpxor(e.xmm2, src1, src2);
|
||||
e.vpxor(e.xmm3, src1, e.xmm1);
|
||||
e.vpand(e.xmm2, e.xmm2, e.xmm3);
|
||||
@@ -5062,7 +5063,7 @@ EMITTER_OPCODE_TABLE(OPCODE_RECIP, RECIP_F32, RECIP_F64, RECIP_V128);
|
||||
// OPCODE_POW2
|
||||
// ============================================================================
|
||||
// TODO(benvanik): use approx here:
|
||||
// http://jrfonseca.blogspot.com/2008/09/fast-sse2-pow-tables-or-polynomials.html
|
||||
// https://jrfonseca.blogspot.com/2008/09/fast-sse2-pow-tables-or-polynomials.html
|
||||
struct POW2_F32 : Sequence<POW2_F32, I<OPCODE_POW2, F32Op, F32Op>> {
|
||||
static __m128 EmulatePow2(void*, __m128 src) {
|
||||
float src_value;
|
||||
@@ -5112,7 +5113,7 @@ EMITTER_OPCODE_TABLE(OPCODE_POW2, POW2_F32, POW2_F64, POW2_V128);
|
||||
// OPCODE_LOG2
|
||||
// ============================================================================
|
||||
// TODO(benvanik): use approx here:
|
||||
// http://jrfonseca.blogspot.com/2008/09/fast-sse2-pow-tables-or-polynomials.html
|
||||
// https://jrfonseca.blogspot.com/2008/09/fast-sse2-pow-tables-or-polynomials.html
|
||||
// TODO(benvanik): this emulated fn destroys all xmm registers! don't do it!
|
||||
struct LOG2_F32 : Sequence<LOG2_F32, I<OPCODE_LOG2, F32Op, F32Op>> {
|
||||
static __m128 EmulateLog2(void*, __m128 src) {
|
||||
@@ -5166,7 +5167,7 @@ struct DOT_PRODUCT_3_V128
|
||||
: Sequence<DOT_PRODUCT_3_V128,
|
||||
I<OPCODE_DOT_PRODUCT_3, F32Op, V128Op, V128Op>> {
|
||||
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
||||
// http://msdn.microsoft.com/en-us/library/bb514054(v=vs.90).aspx
|
||||
// https://msdn.microsoft.com/en-us/library/bb514054(v=vs.90).aspx
|
||||
EmitCommutativeBinaryXmmOp(e, i,
|
||||
[](X64Emitter& e, Xmm dest, Xmm src1, Xmm src2) {
|
||||
// TODO(benvanik): apparently this is very slow
|
||||
@@ -5184,7 +5185,7 @@ struct DOT_PRODUCT_4_V128
|
||||
: Sequence<DOT_PRODUCT_4_V128,
|
||||
I<OPCODE_DOT_PRODUCT_4, F32Op, V128Op, V128Op>> {
|
||||
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
||||
// http://msdn.microsoft.com/en-us/library/bb514054(v=vs.90).aspx
|
||||
// https://msdn.microsoft.com/en-us/library/bb514054(v=vs.90).aspx
|
||||
EmitCommutativeBinaryXmmOp(e, i,
|
||||
[](X64Emitter& e, Xmm dest, Xmm src1, Xmm src2) {
|
||||
// TODO(benvanik): apparently this is very slow
|
||||
@@ -7003,7 +7004,7 @@ struct PACK : Sequence<PACK, I<OPCODE_PACK, V128Op, V128Op, V128Op>> {
|
||||
}
|
||||
static void EmitFLOAT16_2(X64Emitter& e, const EmitArgType& i) {
|
||||
assert_true(i.src2.value->IsConstantZero());
|
||||
// http://blogs.msdn.com/b/chuckw/archive/2012/09/11/directxmath-f16c-and-fma.aspx
|
||||
// https://blogs.msdn.com/b/chuckw/archive/2012/09/11/directxmath-f16c-and-fma.aspx
|
||||
// dest = [(src1.x | src1.y), 0, 0, 0]
|
||||
|
||||
Xmm src;
|
||||
@@ -7398,10 +7399,10 @@ struct UNPACK : Sequence<UNPACK, I<OPCODE_UNPACK, V128Op, V128Op>> {
|
||||
// 1 bit sign, 5 bit exponent, 10 bit mantissa
|
||||
// D3D10 half float format
|
||||
// TODO(benvanik):
|
||||
// http://blogs.msdn.com/b/chuckw/archive/2012/09/11/directxmath-f16c-and-fma.aspx
|
||||
// https://blogs.msdn.com/b/chuckw/archive/2012/09/11/directxmath-f16c-and-fma.aspx
|
||||
// Use _mm_cvtph_ps -- requires very modern processors (SSE5+)
|
||||
// Unpacking half floats:
|
||||
// http://fgiesen.wordpress.com/2012/03/28/half-to-float-done-quic/
|
||||
// https://fgiesen.wordpress.com/2012/03/28/half-to-float-done-quic/
|
||||
// Packing half floats: https://gist.github.com/rygorous/2156668
|
||||
// Load source, move from tight pack of X16Y16.... to X16...Y16...
|
||||
// Also zero out the high end.
|
||||
|
||||
@@ -489,7 +489,7 @@ int CompareValueUse(const Value::Use* a, const Value::Use* b) {
|
||||
} // namespace
|
||||
void RegisterAllocationPass::SortUsageList(Value* value) {
|
||||
// Modified in-place linked list sort from:
|
||||
// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.c
|
||||
// https://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.c
|
||||
if (!value->use_head) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -505,7 +505,7 @@ bool TryDecodeMov(const uint8_t* p, DecodedMov* mov) {
|
||||
}
|
||||
if (p[i] == 0x0F && p[i + 1] == 0x38 && p[i + 2] == 0xF1) {
|
||||
// MOVBE m32, r32 (store)
|
||||
// http://www.tptp.cc/mirrors/siyobik.info/instruction/MOVBE.html
|
||||
// https://web.archive.org/web/20170629091435/https://www.tptp.cc/mirrors/siyobik.info/instruction/MOVBE.html
|
||||
// 44 0f 38 f1 a4 02 00 movbe DWORD PTR [rdx+rax*1+0x0],r12d
|
||||
// 42 0f 38 f1 8c 22 00 movbe DWORD PTR [rdx+r12*1+0x0],ecx
|
||||
// 0f 38 f1 8c 02 00 00 movbe DWORD PTR [rdx + rax * 1 + 0x0], ecx
|
||||
@@ -514,7 +514,7 @@ bool TryDecodeMov(const uint8_t* p, DecodedMov* mov) {
|
||||
i += 3;
|
||||
} else if (p[i] == 0x0F && p[i + 1] == 0x38 && p[i + 2] == 0xF0) {
|
||||
// MOVBE r32, m32 (load)
|
||||
// http://www.tptp.cc/mirrors/siyobik.info/instruction/MOVBE.html
|
||||
// https://web.archive.org/web/20170629091435/https://www.tptp.cc/mirrors/siyobik.info/instruction/MOVBE.html
|
||||
// 44 0f 38 f0 a4 02 00 movbe r12d,DWORD PTR [rdx+rax*1+0x0]
|
||||
// 42 0f 38 f0 8c 22 00 movbe ecx,DWORD PTR [rdx+r12*1+0x0]
|
||||
// 46 0f 38 f0 a4 22 00 movbe r12d,DWORD PTR [rdx+r12*1+0x0]
|
||||
@@ -525,7 +525,7 @@ bool TryDecodeMov(const uint8_t* p, DecodedMov* mov) {
|
||||
i += 3;
|
||||
} else if (p[i] == 0x89) {
|
||||
// MOV m32, r32 (store)
|
||||
// http://www.tptp.cc/mirrors/siyobik.info/instruction/MOV.html
|
||||
// https://web.archive.org/web/20170629072136/https://www.tptp.cc/mirrors/siyobik.info/instruction/MOV.html
|
||||
// 44 89 24 02 mov DWORD PTR[rdx + rax * 1], r12d
|
||||
// 42 89 0c 22 mov DWORD PTR[rdx + r12 * 1], ecx
|
||||
// 89 0c 02 mov DWORD PTR[rdx + rax * 1], ecx
|
||||
@@ -534,7 +534,7 @@ bool TryDecodeMov(const uint8_t* p, DecodedMov* mov) {
|
||||
++i;
|
||||
} else if (p[i] == 0x8B) {
|
||||
// MOV r32, m32 (load)
|
||||
// http://www.tptp.cc/mirrors/siyobik.info/instruction/MOV.html
|
||||
// https://web.archive.org/web/20170629072136/https://www.tptp.cc/mirrors/siyobik.info/instruction/MOV.html
|
||||
// 44 8b 24 02 mov r12d, DWORD PTR[rdx + rax * 1]
|
||||
// 42 8b 0c 22 mov ecx, DWORD PTR[rdx + r12 * 1]
|
||||
// 46 8b 24 22 mov r12d, DWORD PTR[rdx + r12 * 1]
|
||||
@@ -544,7 +544,7 @@ bool TryDecodeMov(const uint8_t* p, DecodedMov* mov) {
|
||||
++i;
|
||||
} else if (p[i] == 0xC7) {
|
||||
// MOV m32, simm32
|
||||
// http://www.asmpedia.org/index.php?title=MOV
|
||||
// https://web.archive.org/web/20161017042413/https://www.asmpedia.org/index.php?title=MOV
|
||||
// C7 04 02 02 00 00 00 mov dword ptr [rdx+rax],2
|
||||
mov->is_load = false;
|
||||
mov->byte_swap = false;
|
||||
|
||||
@@ -31,7 +31,7 @@ Value* CalculateEA_0(PPCHIRBuilder& f, uint32_t ra, uint32_t rb);
|
||||
// Most of this file comes from:
|
||||
// http://biallas.net/doc/vmx128/vmx128.txt
|
||||
// https://github.com/kakaroto/ps3ida/blob/master/plugins/PPCAltivec/src/main.cpp
|
||||
// http://sannybuilder.com/forums/viewtopic.php?id=190
|
||||
// https://sannybuilder.com/forums/viewtopic.php?id=190
|
||||
|
||||
#define OP(x) ((((uint32_t)(x)) & 0x3f) << 26)
|
||||
#define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0))
|
||||
@@ -2068,7 +2068,7 @@ int InstrEmit_vpkd3d128(PPCHIRBuilder& f, const InstrData& i) {
|
||||
assert_unhandled_case(type);
|
||||
return 1;
|
||||
}
|
||||
// http://hlssmod.net/he_code/public/pixelwriter.h
|
||||
// https://hlssmod.net/he_code/public/pixelwriter.h
|
||||
// control = prev:0123 | new:4567
|
||||
uint32_t control = kIdentityPermuteMask; // original
|
||||
switch (pack) {
|
||||
@@ -2141,7 +2141,8 @@ int InstrEmit_vpkd3d128(PPCHIRBuilder& f, const InstrData& i) {
|
||||
|
||||
int InstrEmit_vupkd3d128(PPCHIRBuilder& f, const InstrData& i) {
|
||||
// Can't find many docs on this. Best reference is
|
||||
// http://worldcraft.googlecode.com/svn/trunk/src/qylib/math/xmmatrix.inl,
|
||||
// https://code.google.com/archive/p/worldcraft/source/default/source?page=4
|
||||
// (qylib/math/xmmatrix.inl)
|
||||
// which shows how it's used in some cases. Since it's all intrinsics,
|
||||
// finding it in code is pretty easy.
|
||||
const uint32_t vd = i.VX128_3.VD128l | (i.VX128_3.VD128h << 5);
|
||||
|
||||
@@ -26,7 +26,7 @@ using xe::cpu::hir::RoundMode;
|
||||
using xe::cpu::hir::Value;
|
||||
|
||||
// Good source of information:
|
||||
// http://mamedev.org/source/src/emu/cpu/powerpc/ppc_ops.c
|
||||
// https://github.com/mamedev/historic-mame/blob/master/src/emu/cpu/powerpc/ppc_ops.c
|
||||
// The correctness of that code is not reflected here yet -_-
|
||||
|
||||
// Enable rounding numbers to single precision as required.
|
||||
|
||||
Reference in New Issue
Block a user