Skip to content

Commit

Permalink
Merge 215761d into caf5894
Browse files Browse the repository at this point in the history
  • Loading branch information
Nekotekina committed Jun 13, 2016
2 parents caf5894 + 215761d commit 8c327d4
Show file tree
Hide file tree
Showing 34 changed files with 6,907 additions and 466 deletions.
4 changes: 0 additions & 4 deletions .travis.yml
Expand Up @@ -20,10 +20,6 @@ env:
# Test mode is for testing if it's working with Coverity. Change to true if testing, to avoid reaching the quota.
- coverity_scan_script_test_mode=false

branches:
except:
- ppu_recompiler

matrix:
exclude:
- os: osx
Expand Down
266 changes: 253 additions & 13 deletions Utilities/Thread.cpp
Expand Up @@ -114,11 +114,15 @@ enum x64_op_t : u32
X64OP_STOS,
X64OP_XCHG,
X64OP_CMPXCHG,
X64OP_LOAD_AND_STORE, // lock and [mem], reg
X64OP_LOAD_OR_STORE, // lock or [mem], reg (TODO)
X64OP_LOAD_XOR_STORE, // lock xor [mem], reg (TODO)
X64OP_INC, // lock inc [mem] (TODO)
X64OP_DEC, // lock dec [mem] (TODO)
X64OP_AND, // lock and [mem], ...
X64OP_OR, // lock or [mem], ...
X64OP_XOR, // lock xor [mem], ...
X64OP_INC, // lock inc [mem]
X64OP_DEC, // lock dec [mem]
X64OP_ADD, // lock add [mem], ...
X64OP_ADC, // lock adc [mem], ...
X64OP_SUB, // lock sub [mem], ...
X64OP_SBB, // lock sbb [mem], ...
};

void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, size_t& out_size, size_t& out_length)
Expand Down Expand Up @@ -329,7 +333,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz
{
if (!oso)
{
out_op = X64OP_LOAD_AND_STORE;
out_op = X64OP_AND;
out_reg = rex & 8 ? get_modRM_reg(code, rex) : get_modRM_reg_lh(code);
out_size = 1;
out_length += get_modRM_size(code);
Expand All @@ -341,14 +345,71 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz
{
if (true)
{
out_op = X64OP_LOAD_AND_STORE;
out_op = X64OP_AND;
out_reg = get_modRM_reg(code, rex);
out_size = get_op_size(rex, oso);
out_length += get_modRM_size(code);
return;
}
break;
}
case 0x80:
{
switch (auto mod_code = get_modRM_reg(code, 0))
{
//case 0: out_op = X64OP_ADD; break; // TODO: strange info in instruction manual
case 1: out_op = X64OP_OR; break;
case 2: out_op = X64OP_ADC; break;
case 3: out_op = X64OP_SBB; break;
case 4: out_op = X64OP_AND; break;
case 5: out_op = X64OP_SUB; break;
case 6: out_op = X64OP_XOR; break;
default: out_op = X64OP_NONE; return;
}

out_reg = X64_IMM8;
out_size = 1;
out_length += get_modRM_size(code) + 1;
return;
}
case 0x81:
{
switch (auto mod_code = get_modRM_reg(code, 0))
{
case 0: out_op = X64OP_ADD; break;
case 1: out_op = X64OP_OR; break;
case 2: out_op = X64OP_ADC; break;
case 3: out_op = X64OP_SBB; break;
case 4: out_op = X64OP_AND; break;
case 5: out_op = X64OP_SUB; break;
case 6: out_op = X64OP_XOR; break;
default: out_op = X64OP_NONE; return;
}

out_reg = oso ? X64_IMM16 : X64_IMM32;
out_size = get_op_size(rex, oso);
out_length += get_modRM_size(code) + (oso ? 2 : 4);
return;
}
case 0x83:
{
switch (auto mod_code = get_modRM_reg(code, 0))
{
case 0: out_op = X64OP_ADD; break;
case 1: out_op = X64OP_OR; break;
case 2: out_op = X64OP_ADC; break;
case 3: out_op = X64OP_SBB; break;
case 4: out_op = X64OP_AND; break;
case 5: out_op = X64OP_SUB; break;
case 6: out_op = X64OP_XOR; break;
default: out_op = X64OP_NONE; return;
}

out_reg = X64_IMM8;
out_size = get_op_size(rex, oso);
out_length += get_modRM_size(code) + 1;
return;
}
case 0x86:
{
if (!oso) // XCHG r8/m8, r8
Expand Down Expand Up @@ -459,7 +520,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz
}
case 0xc6:
{
if (!lock && !oso && get_modRM_reg(code, 0) == X64R_RAX) // MOV r8/m8, imm8
if (!lock && !oso && get_modRM_reg(code, 0) == 0) // MOV r8/m8, imm8
{
out_op = X64OP_STORE;
out_reg = X64_IMM8;
Expand All @@ -471,7 +532,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz
}
case 0xc7:
{
if (!lock && get_modRM_reg(code, 0) == X64R_RAX) // MOV r/m, imm16/imm32 (16, 32, 64)
if (!lock && get_modRM_reg(code, 0) == 0) // MOV r/m, imm16/imm32 (16, 32, 64)
{
out_op = X64OP_STORE;
out_reg = oso ? X64_IMM16 : X64_IMM32;
Expand Down Expand Up @@ -599,6 +660,9 @@ bool get_x64_reg_value(x64_context* context, x64_reg_t reg, size_t d_size, size_
switch (d_size)
{
case 1: out_value = (u8)imm_value; return true;
case 2: out_value = (u16)imm_value; return true; // sign-extended
case 4: out_value = (u32)imm_value; return true; // sign-extended
case 8: out_value = (u64)imm_value; return true; // sign-extended
}
}
else if (reg == X64_IMM16)
Expand Down Expand Up @@ -649,7 +713,7 @@ bool put_x64_reg_value(x64_context* context, x64_reg_t reg, size_t d_size, u64 v
return false;
}

bool set_x64_cmp_flags(x64_context* context, size_t d_size, u64 x, u64 y)
bool set_x64_cmp_flags(x64_context* context, size_t d_size, u64 x, u64 y, bool carry = true)
{
switch (d_size)
{
Expand All @@ -664,11 +728,11 @@ bool set_x64_cmp_flags(x64_context* context, size_t d_size, u64 x, u64 y)
const u64 diff = x - y;
const u64 summ = x + y;

if (((x & y) | ((x ^ y) & ~summ)) & sign)
if (carry && ((x & y) | ((x ^ y) & ~summ)) & sign)
{
EFLAGS(context) |= 0x1; // set CF
}
else
else if (carry)
{
EFLAGS(context) &= ~0x1; // clear CF
}
Expand Down Expand Up @@ -1060,7 +1124,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
}
break;
}
case X64OP_LOAD_AND_STORE:
case X64OP_AND:
{
u64 value;
if (!get_x64_reg_value(context, reg, d_size, i_size, value))
Expand All @@ -1083,6 +1147,182 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
}
break;
}
case X64OP_OR:
{
u64 value;
if (!get_x64_reg_value(context, reg, d_size, i_size, value))
{
return false;
}

switch (d_size)
{
case 1: value = *(atomic_t<u8>*)vm::base_priv(addr) |= (u8)value; break;
case 2: value = *(atomic_t<u16>*)vm::base_priv(addr) |= (u16)value; break;
case 4: value = *(atomic_t<u32>*)vm::base_priv(addr) |= (u32)value; break;
case 8: value = *(atomic_t<u64>*)vm::base_priv(addr) |= (u64)value; break;
default: return false;
}

if (!set_x64_cmp_flags(context, d_size, value, 0))
{
return false;
}
break;
}
case X64OP_XOR:
{
u64 value;
if (!get_x64_reg_value(context, reg, d_size, i_size, value))
{
return false;
}

switch (d_size)
{
case 1: value = *(atomic_t<u8>*)vm::base_priv(addr) ^= (u8)value; break;
case 2: value = *(atomic_t<u16>*)vm::base_priv(addr) ^= (u16)value; break;
case 4: value = *(atomic_t<u32>*)vm::base_priv(addr) ^= (u32)value; break;
case 8: value = *(atomic_t<u64>*)vm::base_priv(addr) ^= (u64)value; break;
default: return false;
}

if (!set_x64_cmp_flags(context, d_size, value, 0))
{
return false;
}
break;
}
case X64OP_INC:
{
u64 value;

switch (d_size)
{
case 1: value = ++*(atomic_t<u8>*)vm::base_priv(addr); break;
case 2: value = ++*(atomic_t<u16>*)vm::base_priv(addr); break;
case 4: value = ++*(atomic_t<u32>*)vm::base_priv(addr); break;
case 8: value = ++*(atomic_t<u64>*)vm::base_priv(addr); break;
default: return false;
}

if (!set_x64_cmp_flags(context, d_size, value, 1, false)) // ???
{
return false;
}
break;
}
case X64OP_DEC:
{
u64 value;

switch (d_size)
{
case 1: value = --*(atomic_t<u8>*)vm::base_priv(addr); break;
case 2: value = --*(atomic_t<u16>*)vm::base_priv(addr); break;
case 4: value = --*(atomic_t<u32>*)vm::base_priv(addr); break;
case 8: value = --*(atomic_t<u64>*)vm::base_priv(addr); break;
default: return false;
}

if (!set_x64_cmp_flags(context, d_size, value, -1, false)) // ???
{
return false;
}
break;
}
case X64OP_ADD:
{
u64 value, new_value;
if (!get_x64_reg_value(context, reg, d_size, i_size, value))
{
return false;
}

switch (d_size)
{
case 1: new_value = *(atomic_t<u8>*)vm::base_priv(addr) += (u8)value; break;
case 2: new_value = *(atomic_t<u16>*)vm::base_priv(addr) += (u16)value; break;
case 4: new_value = *(atomic_t<u32>*)vm::base_priv(addr) += (u32)value; break;
case 8: new_value = *(atomic_t<u64>*)vm::base_priv(addr) += (u64)value; break;
default: return false;
}

if (!set_x64_cmp_flags(context, d_size, new_value, value)) // ???
{
return false;
}
break;
}
case X64OP_ADC:
{
u64 value, new_value;
if (!get_x64_reg_value(context, reg, d_size, i_size, value))
{
return false;
}

switch (d_size)
{
case 1: new_value = *(atomic_t<u8>*)vm::base_priv(addr) += (u8)(value + (EFLAGS(context) & 1)); break;
case 2: new_value = *(atomic_t<u16>*)vm::base_priv(addr) += (u16)(value + (EFLAGS(context) & 1)); break;
case 4: new_value = *(atomic_t<u32>*)vm::base_priv(addr) += (u32)(value + (EFLAGS(context) & 1)); break;
case 8: new_value = *(atomic_t<u64>*)vm::base_priv(addr) += (u64)(value + (EFLAGS(context) & 1)); break;
default: return false;
}

if (!set_x64_cmp_flags(context, d_size, new_value, value + (EFLAGS(context) & 1))) // ???
{
return false;
}
break;
}
case X64OP_SUB:
{
u64 value, new_value;
if (!get_x64_reg_value(context, reg, d_size, i_size, value))
{
return false;
}

switch (d_size)
{
case 1: new_value = *(atomic_t<u8>*)vm::base_priv(addr) -= (u8)value; break;
case 2: new_value = *(atomic_t<u16>*)vm::base_priv(addr) -= (u16)value; break;
case 4: new_value = *(atomic_t<u32>*)vm::base_priv(addr) -= (u32)value; break;
case 8: new_value = *(atomic_t<u64>*)vm::base_priv(addr) -= (u64)value; break;
default: return false;
}

if (!set_x64_cmp_flags(context, d_size, new_value, 0 - value)) // ???
{
return false;
}
break;
}
case X64OP_SBB:
{
u64 value, new_value;
if (!get_x64_reg_value(context, reg, d_size, i_size, value))
{
return false;
}

switch (d_size)
{
case 1: new_value = *(atomic_t<u8>*)vm::base_priv(addr) -= (u8)(value + (EFLAGS(context) & 1)); break;
case 2: new_value = *(atomic_t<u16>*)vm::base_priv(addr) -= (u16)(value + (EFLAGS(context) & 1)); break;
case 4: new_value = *(atomic_t<u32>*)vm::base_priv(addr) -= (u32)(value + (EFLAGS(context) & 1)); break;
case 8: new_value = *(atomic_t<u64>*)vm::base_priv(addr) -= (u64)(value + (EFLAGS(context) & 1)); break;
default: return false;
}

if (!set_x64_cmp_flags(context, d_size, new_value, 0 - (value + (EFLAGS(context) & 1)))) // ???
{
return false;
}
break;
}
default:
{
LOG_ERROR(MEMORY, "Invalid or unsupported operation (op=%d, reg=%d, d_size=%lld, a_size=0x%llx, i_size=%lld)", op, reg, d_size, a_size, i_size);
Expand Down
4 changes: 2 additions & 2 deletions Vulkan/CMakeLists.txt
@@ -1,10 +1,10 @@
if(APPLE OR WIN32 AND NOT MSVC)
if(APPLE)
else()
add_subdirectory( glslang )
set(BUILD_TESTS OFF CACHE BOOL "Build tests" FORCE)
set(BUILD_DEMOS OFF CACHE BOOL "Build demos" FORCE)
# TravisCI break build with layers and vkjson
set(BUILD_LAYERS OFF CACHE BOOL "Build demos" FORCE)
set(BUILD_VKJSON OFF CACHE BOOL "Build demos" FORCE)
add_subdirectory( Vulkan-LoaderAndValidationLayers )
add_subdirectory( glslang )
endif()
7 changes: 2 additions & 5 deletions appveyor.yml
Expand Up @@ -8,10 +8,6 @@ clone_folder: c:\rpcs3
clone_depth: 3
test: off

branches:
except:
- ppu_recompiler

before_build:
# until git for win 2.5 release with commit checkout
- git submodule update --init 3rdparty/ffmpeg 3rdparty/pugixml asmjit 3rdparty/GSL 3rdparty/libpng Vulkan/glslang Vulkan/Vulkan-LoaderAndValidationLayers Utilities/yaml-cpp
Expand All @@ -25,7 +21,8 @@ build_script:

install:
- ps: Start-FileDownload 'https://402331b94f8e4b87ae2ef4677347f7956cf3861f.googledrive.com/host/0B6v_qtb9hkicfmt0NG0wTTRtUmF4X3VTQk5Oc2JidEVKVnUteDA1dXdrYlNsVW9kREpsSHc/wxWidgets.7z'
- ps: Start-FileDownload 'https://402331b94f8e4b87ae2ef4677347f7956cf3861f.googledrive.com/host/0B6v_qtb9hkicfmt0NG0wTTRtUmF4X3VTQk5Oc2JidEVKVnUteDA1dXdrYlNsVW9kREpsSHc/llvmlibs.7z'
# - ps: Start-FileDownload 'https://402331b94f8e4b87ae2ef4677347f7956cf3861f.googledrive.com/host/0B6v_qtb9hkicfmt0NG0wTTRtUmF4X3VTQk5Oc2JidEVKVnUteDA1dXdrYlNsVW9kREpsSHc/llvmlibs.7z'
- ps: Start-FileDownload 'https://drive.google.com/uc?export=download&id=0B-98fOyaZKJ5YWVnb29JZXFQWkU' -FileName llvmlibs.7z
- ps: Start-FileDownload 'https://402331b94f8e4b87ae2ef4677347f7956cf3861f.googledrive.com/host/0B6v_qtb9hkicfmt0NG0wTTRtUmF4X3VTQk5Oc2JidEVKVnUteDA1dXdrYlNsVW9kREpsSHc/zlib.7z'
- set WXWIN=C:\rpcs3\wxWidgets
- set OPENALDIR=C:\rpcs3\3rdparty\OpenAL
Expand Down
2 changes: 1 addition & 1 deletion llvm
Submodule llvm updated 14004 files

0 comments on commit 8c327d4

Please sign in to comment.