OSDN Git Service

Make Reactor build stand-alone.
authorNicolas Capens <capn@google.com>
Mon, 6 Aug 2018 18:20:45 +0000 (14:20 -0400)
committerNicolas Capens <nicolascapens@google.com>
Fri, 12 Oct 2018 18:19:15 +0000 (18:19 +0000)
This is accomplished by duplicating files from the Common directory
that Reactor (both with LLVM and Subzero back-end) depended on. They
will be minimized in the next change.

Bug b/115344057
Bug swiftshader:16

Change-Id: I2dc087e91b761cc4402ed8594022551e9246b855
Reviewed-on: https://swiftshader-review.googlesource.com/c/20108
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
34 files changed:
.travis.yml
CMakeLists.txt
SwiftShader.sln
src/Android.mk
src/Common/Version.h
src/Reactor/BUILD.gn
src/Reactor/CPUID.cpp [new file with mode: 0644]
src/Reactor/CPUID.hpp [new file with mode: 0644]
src/Reactor/Debug.cpp [new file with mode: 0644]
src/Reactor/Debug.hpp [new file with mode: 0644]
src/Reactor/DebugAndroid.cpp [new file with mode: 0644]
src/Reactor/DebugAndroid.hpp [new file with mode: 0644]
src/Reactor/LLVMReactor.cpp
src/Reactor/LLVMRoutine.cpp
src/Reactor/LLVMRoutineManager.cpp
src/Reactor/Memory.cpp [new file with mode: 0644]
src/Reactor/Memory.hpp [new file with mode: 0644]
src/Reactor/MutexLock.hpp [new file with mode: 0644]
src/Reactor/Reactor.vcxproj
src/Reactor/Reactor.vcxproj.filters
src/Reactor/ReactorUnitTests.cpp [moved from src/Reactor/Main.cpp with 97% similarity]
src/Reactor/ReactorUnitTests.vcxproj [moved from src/Reactor/SubzeroTest.vcxproj with 71% similarity]
src/Reactor/ReactorUnitTests.vcxproj.filters [new file with mode: 0644]
src/Reactor/Routine.cpp
src/Reactor/Subzero.vcxproj
src/Reactor/Subzero.vcxproj.filters
src/Reactor/SubzeroReactor.cpp
src/Reactor/SubzeroTest.vcxproj.filters [deleted file]
src/Reactor/Thread.cpp [new file with mode: 0644]
src/Reactor/Thread.hpp [new file with mode: 0644]
src/Reactor/Types.hpp [new file with mode: 0644]
tests/unittests/GLESUnitTests.vcxproj [moved from tests/unittests/unittests.vcxproj with 97% similarity]
tests/unittests/GLESUnitTests.vcxproj.filters [moved from tests/unittests/unittests.vcxproj.filters with 100% similarity]
tests/unittests/GLESUnitTests.vcxproj.user [moved from tests/unittests/unittests.vcxproj.user with 100% similarity]

index 25a651f..6848734 100644 (file)
@@ -13,8 +13,9 @@ compiler:
   - gcc
 
 env:
-  - REACTOR_BACKEND=LLVM
   - REACTOR_BACKEND=Subzero
+  - REACTOR_BACKEND=LLVM SWIFTSHADER_LLVM_VERSION=3
+  - REACTOR_BACKEND=LLVM SWIFTSHADER_LLVM_VERSION=7
 
 script:
   - $CXX --version
@@ -22,6 +23,7 @@ script:
   - cmake -DREACTOR_BACKEND=$REACTOR_BACKEND ..
   - make
   - ./unittests
+  - ./ReactorUnitTests
 
 notifications:
   email:
@@ -39,4 +41,4 @@ deploy:
   skip_cleanup: true
   acl: public-read
   upload-dir: OpenGL_ES/Latest
-  local-dir: $TRAVIS_BUILD_DIR/out
\ No newline at end of file
+  local-dir: $TRAVIS_BUILD_DIR/out
index 2c2684e..8f1e1c2 100644 (file)
@@ -1724,14 +1724,17 @@ if(${REACTOR_BACKEND} STREQUAL "Subzero")
         ${SOURCE_DIR}/Reactor/Optimizer.cpp
         ${SOURCE_DIR}/Reactor/Nucleus.hpp
         ${SOURCE_DIR}/Reactor/Routine.hpp
+        ${SOURCE_DIR}/Reactor/Debug.cpp
+        ${SOURCE_DIR}/Reactor/Debug.hpp
+        ${SOURCE_DIR}/Reactor/Memory.cpp
+        ${SOURCE_DIR}/Reactor/Memory.hpp
     )
 
     set(SUBZERO_INCLUDE_DIR
-        ${SOURCE_DIR}/
         ${SUBZERO_DIR}/
         ${SUBZERO_LLVM_DIR}/include/
         ${SUBZERO_DIR}/pnacl-llvm/include/
-     )
+    )
 
     if(WIN32)
         list(APPEND SUBZERO_INCLUDE_DIR ${SUBZERO_LLVM_DIR}/build/Windows/include/)
@@ -1817,6 +1820,12 @@ set(REACTOR_LLVM_LIST
     ${SOURCE_DIR}/Reactor/LLVMRoutine.hpp
     ${SOURCE_DIR}/Reactor/LLVMRoutineManager.cpp
     ${SOURCE_DIR}/Reactor/LLVMRoutineManager.hpp
+    ${SOURCE_DIR}/Reactor/CPUID.cpp
+    ${SOURCE_DIR}/Reactor/CPUID.hpp
+    ${SOURCE_DIR}/Reactor/Debug.cpp
+    ${SOURCE_DIR}/Reactor/Debug.hpp
+    ${SOURCE_DIR}/Reactor/Memory.cpp
+    ${SOURCE_DIR}/Reactor/Memory.hpp
 )
 
 file(GLOB_RECURSE EGL_LIST
@@ -2113,26 +2122,27 @@ if(BUILD_SAMPLES)
     endif()
 endif()
 
-if(BUILD_TESTS AND ${REACTOR_BACKEND} STREQUAL "Subzero")
-    set(SUBZERO_TEST_LIST
-        ${SOURCE_DIR}/Reactor/Main.cpp
+if(BUILD_TESTS)
+    set(REACTOR_UNIT_TESTS_LIST
+        ${SOURCE_DIR}/Reactor/ReactorUnitTests.cpp
         ${CMAKE_SOURCE_DIR}/third_party/googletest/googletest/src/gtest-all.cc
     )
 
-    set(SUBZERO_TEST_INCLUDE_DIR
+    set(REACTOR_UNIT_TESTS_INCLUDE_DIR
         ${CMAKE_SOURCE_DIR}/third_party/googletest/googletest/include
         ${CMAKE_SOURCE_DIR}/third_party/googletest/googletest/
     )
 
-    add_executable(SubzeroTest ${SUBZERO_TEST_LIST})
-    set_target_properties(SubzeroTest PROPERTIES
-        INCLUDE_DIRECTORIES "${SUBZERO_TEST_INCLUDE_DIR}"
+    add_executable(ReactorUnitTests ${REACTOR_UNIT_TESTS_LIST})
+    set_target_properties(ReactorUnitTests PROPERTIES
+        INCLUDE_DIRECTORIES "${REACTOR_UNIT_TESTS_INCLUDE_DIR}"
         FOLDER "Tests"
     )
-    if(WIN32)
-        target_link_libraries(SubzeroTest ReactorSubzero)
+
+    if(NOT WIN32 AND ${REACTOR_BACKEND} STREQUAL "Subzero")
+        target_link_libraries(ReactorUnitTests ${Reactor} pthread dl)
     else()
-        target_link_libraries(SubzeroTest ReactorSubzero pthread dl)
+        target_link_libraries(ReactorUnitTests ${Reactor})
     endif()
 endif()
 
index 4e436f4..5a11a15 100644 (file)
@@ -253,11 +253,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "D3D8", "src\D3D8\D3D8.vcxpr
 EndProject\r
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Subzero", "src\Reactor\Subzero.vcxproj", "{0EB31AEC-B020-46AB-BA05-730F6D01C29B}"\r
 EndProject\r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SubzeroTest", "src\Reactor\SubzeroTest.vcxproj", "{4EC107AB-89E8-4A0B-8366-B3E81085AE07}"\r
-EndProject\r
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SubzeroLLVMDependencies", "src\Reactor\SubzeroLLVMDependencies.vcxproj", "{E3BBD7DA-45C1-43EF-9C87-3F411031BDE4}"\r
 EndProject\r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unittests", "tests\unittests\unittests.vcxproj", "{CF8EBC89-8762-49DC-9440-6C82B3499913}"\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GLESUnitTests", "tests\unittests\GLESUnitTests.vcxproj", "{CF8EBC89-8762-49DC-9440-6C82B3499913}"\r
 EndProject\r
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VertexRoutineFuzzer", "tests\fuzzers\VertexRoutineFuzzer.vcxproj", "{FBDCFF88-0CE1-43C3-B694-8F45946FAFE3}"\r
        ProjectSection(ProjectDependencies) = postProject\r
@@ -267,6 +265,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VertexRoutineFuzzer", "test
 EndProject\r
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Vulkan", "src\Vulkan\vulkan.vcxproj", "{E1C34B66-C942-4B9A-B8C3-9A12625650D3}"\r
 EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReactorUnitTests", "src\Reactor\ReactorUnitTests.vcxproj", "{4EC107AB-89E8-4A0B-8366-B3E81085AE07}"\r
+EndProject\r
 Global\r
        GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
                Debug|Win32 = Debug|Win32\r
@@ -754,18 +754,6 @@ Global
                {0EB31AEC-B020-46AB-BA05-730F6D01C29B}.Release|Win32.Build.0 = Release|Win32\r
                {0EB31AEC-B020-46AB-BA05-730F6D01C29B}.Release|x64.ActiveCfg = Release|x64\r
                {0EB31AEC-B020-46AB-BA05-730F6D01C29B}.Release|x64.Build.0 = Release|x64\r
-               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Debug|Win32.ActiveCfg = Debug|Win32\r
-               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Debug|Win32.Build.0 = Debug|Win32\r
-               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Debug|x64.ActiveCfg = Debug|x64\r
-               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Debug|x64.Build.0 = Debug|x64\r
-               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Profile|Win32.ActiveCfg = Release|Win32\r
-               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Profile|Win32.Build.0 = Release|Win32\r
-               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Profile|x64.ActiveCfg = Release|x64\r
-               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Profile|x64.Build.0 = Release|x64\r
-               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Release|Win32.ActiveCfg = Release|Win32\r
-               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Release|Win32.Build.0 = Release|Win32\r
-               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Release|x64.ActiveCfg = Release|x64\r
-               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Release|x64.Build.0 = Release|x64\r
                {E3BBD7DA-45C1-43EF-9C87-3F411031BDE4}.Debug|Win32.ActiveCfg = Debug|Win32\r
                {E3BBD7DA-45C1-43EF-9C87-3F411031BDE4}.Debug|Win32.Build.0 = Debug|Win32\r
                {E3BBD7DA-45C1-43EF-9C87-3F411031BDE4}.Debug|x64.ActiveCfg = Debug|x64\r
@@ -814,6 +802,18 @@ Global
                {E1C34B66-C942-4B9A-B8C3-9A12625650D3}.Release|Win32.Build.0 = Release|Win32\r
                {E1C34B66-C942-4B9A-B8C3-9A12625650D3}.Release|x64.ActiveCfg = Release|x64\r
                {E1C34B66-C942-4B9A-B8C3-9A12625650D3}.Release|x64.Build.0 = Release|x64\r
+               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Debug|Win32.Build.0 = Debug|Win32\r
+               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Debug|x64.ActiveCfg = Debug|x64\r
+               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Debug|x64.Build.0 = Debug|x64\r
+               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Profile|Win32.ActiveCfg = Release|Win32\r
+               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Profile|Win32.Build.0 = Release|Win32\r
+               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Profile|x64.ActiveCfg = Release|x64\r
+               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Profile|x64.Build.0 = Release|x64\r
+               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Release|Win32.ActiveCfg = Release|Win32\r
+               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Release|Win32.Build.0 = Release|Win32\r
+               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Release|x64.ActiveCfg = Release|x64\r
+               {4EC107AB-89E8-4A0B-8366-B3E81085AE07}.Release|x64.Build.0 = Release|x64\r
        EndGlobalSection\r
        GlobalSection(SolutionProperties) = preSolution\r
                HideSolutionNode = FALSE\r
@@ -855,9 +855,9 @@ Global
                {04FC5430-3F1B-42A2-A18A-D8BB7E5B2733} = {ED25C308-5BDB-43A7-BED6-C2C059FC2D7D}\r
                {09ABE661-9BC0-4152-A820-1FB0522CAC01} = {B7E24D8E-6BE9-4DEF-A8B9-6A6E60CA60E9}\r
                {9088FC9E-9843-4E0D-85D0-1B657AFC480A} = {B7E24D8E-6BE9-4DEF-A8B9-6A6E60CA60E9}\r
-               {4EC107AB-89E8-4A0B-8366-B3E81085AE07} = {ED25C308-5BDB-43A7-BED6-C2C059FC2D7D}\r
                {CF8EBC89-8762-49DC-9440-6C82B3499913} = {ED25C308-5BDB-43A7-BED6-C2C059FC2D7D}\r
                {FBDCFF88-0CE1-43C3-B694-8F45946FAFE3} = {ED25C308-5BDB-43A7-BED6-C2C059FC2D7D}\r
+               {4EC107AB-89E8-4A0B-8366-B3E81085AE07} = {ED25C308-5BDB-43A7-BED6-C2C059FC2D7D}\r
        EndGlobalSection\r
        GlobalSection(ExtensibilityGlobals) = postSolution\r
                SolutionGuid = {4DF423D2-8425-48A7-9CEC-835C4C3CA957}\r
index b25ef91..d418b35 100644 (file)
@@ -60,17 +60,22 @@ COMMON_SRC_FILES += \
        Main/FrameBufferAndroid.cpp \
        Main/SwiftConfig.cpp
 
+COMMON_SRC_FILES += \
+       Reactor/Routine.cpp \
+       Reactor/Debug.cpp \
+       Reactor/DebugAndroid.cpp \
+       Reactor/Memory.cpp
+
 ifdef SWIFTSHADER_USE_SUBZERO
 COMMON_SRC_FILES += \
        Reactor/SubzeroReactor.cpp \
-       Reactor/Routine.cpp \
        Reactor/Optimizer.cpp
 else
 COMMON_SRC_FILES += \
        Reactor/LLVMReactor.cpp \
-       Reactor/Routine.cpp \
        Reactor/LLVMRoutine.cpp \
-       Reactor/LLVMRoutineManager.cpp
+       Reactor/LLVMRoutineManager.cpp \
+       Reactor/CPUID.cpp
 endif
 
 COMMON_SRC_FILES += \
index 72bd15d..bf1701e 100644 (file)
@@ -15,7 +15,7 @@
 #define MAJOR_VERSION 4
 #define MINOR_VERSION 1
 #define BUILD_VERSION 0
-#define BUILD_REVISION 2
+#define BUILD_REVISION 3
 
 #define STRINGIFY(x) #x
 #define MACRO_STRINGIFY(x) STRINGIFY(x)
index 1084f27..c63e359 100644 (file)
@@ -267,6 +267,8 @@ swiftshader_source_set("swiftshader_reactor") {
 
   sources = [
     "Routine.cpp",
+    "Debug.cpp",
+    "Memory.cpp",
   ]
 
   if (use_swiftshader_with_subzero) {
@@ -283,7 +285,6 @@ swiftshader_source_set("swiftshader_reactor") {
     ]
 
     include_dirs = [
-      "..",
     ]
   } else {
     deps += [ "../../third_party/LLVM:swiftshader_llvm" ]
@@ -292,13 +293,12 @@ swiftshader_source_set("swiftshader_reactor") {
       "LLVMReactor.cpp",
       "LLVMRoutine.cpp",
       "LLVMRoutineManager.cpp",
+      "CPUID.cpp",
     ]
 
     configs = [ ":swiftshader_reactor_private_config" ]
 
     include_dirs = [
-      "..",
-      "../Common",
       "../../third_party/LLVM/include/",
     ]
   }
diff --git a/src/Reactor/CPUID.cpp b/src/Reactor/CPUID.cpp
new file mode 100644 (file)
index 0000000..58ef009
--- /dev/null
@@ -0,0 +1,227 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "CPUID.hpp"
+
+#if defined(_WIN32)
+       #ifndef WIN32_LEAN_AND_MEAN
+               #define WIN32_LEAN_AND_MEAN
+       #endif
+       #include <windows.h>
+       #include <intrin.h>
+       #include <float.h>
+#else
+       #include <unistd.h>
+       #include <sched.h>
+       #include <sys/types.h>
+#endif
+
+namespace rr
+{
+       bool CPUID::MMX = detectMMX();
+       bool CPUID::CMOV = detectCMOV();
+       bool CPUID::SSE = detectSSE();
+       bool CPUID::SSE2 = detectSSE2();
+       bool CPUID::SSE3 = detectSSE3();
+       bool CPUID::SSSE3 = detectSSSE3();
+       bool CPUID::SSE4_1 = detectSSE4_1();
+
+       bool CPUID::enableMMX = true;
+       bool CPUID::enableCMOV = true;
+       bool CPUID::enableSSE = true;
+       bool CPUID::enableSSE2 = true;
+       bool CPUID::enableSSE3 = true;
+       bool CPUID::enableSSSE3 = true;
+       bool CPUID::enableSSE4_1 = true;
+
+       void CPUID::setEnableMMX(bool enable)
+       {
+               enableMMX = enable;
+
+               if(!enableMMX)
+               {
+                       enableSSE = false;
+                       enableSSE2 = false;
+                       enableSSE3 = false;
+                       enableSSSE3 = false;
+                       enableSSE4_1 = false;
+               }
+       }
+
+       void CPUID::setEnableCMOV(bool enable)
+       {
+               enableCMOV = enable;
+
+               if(!CMOV)
+               {
+                       enableSSE = false;
+                       enableSSE2 = false;
+                       enableSSE3 = false;
+                       enableSSSE3 = false;
+                       enableSSE4_1 = false;
+               }
+       }
+
+       void CPUID::setEnableSSE(bool enable)
+       {
+               enableSSE = enable;
+
+               if(enableSSE)
+               {
+                       enableMMX = true;
+                       enableCMOV = true;
+               }
+               else
+               {
+                       enableSSE2 = false;
+                       enableSSE3 = false;
+                       enableSSSE3 = false;
+                       enableSSE4_1 = false;
+               }
+       }
+
+       void CPUID::setEnableSSE2(bool enable)
+       {
+               enableSSE2 = enable;
+
+               if(enableSSE2)
+               {
+                       enableMMX = true;
+                       enableCMOV = true;
+                       enableSSE = true;
+               }
+               else
+               {
+                       enableSSE3 = false;
+                       enableSSSE3 = false;
+                       enableSSE4_1 = false;
+               }
+       }
+
+       void CPUID::setEnableSSE3(bool enable)
+       {
+               enableSSE3 = enable;
+
+               if(enableSSE3)
+               {
+                       enableMMX = true;
+                       enableCMOV = true;
+                       enableSSE = true;
+                       enableSSE2 = true;
+               }
+               else
+               {
+                       enableSSSE3 = false;
+                       enableSSE4_1 = false;
+               }
+       }
+
+       void CPUID::setEnableSSSE3(bool enable)
+       {
+               enableSSSE3 = enable;
+
+               if(enableSSSE3)
+               {
+                       enableMMX = true;
+                       enableCMOV = true;
+                       enableSSE = true;
+                       enableSSE2 = true;
+                       enableSSE3 = true;
+               }
+               else
+               {
+                       enableSSE4_1 = false;
+               }
+       }
+
+       void CPUID::setEnableSSE4_1(bool enable)
+       {
+               enableSSE4_1 = enable;
+
+               if(enableSSE4_1)
+               {
+                       enableMMX = true;
+                       enableCMOV = true;
+                       enableSSE = true;
+                       enableSSE2 = true;
+                       enableSSE3 = true;
+                       enableSSSE3 = true;
+               }
+       }
+
+       static void cpuid(int registers[4], int info)
+       {
+               #if defined(__i386__) || defined(__x86_64__)
+                       #if defined(_WIN32)
+                               __cpuid(registers, info);
+                       #else
+                               __asm volatile("cpuid": "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]): "a" (info));
+                       #endif
+               #else
+                       registers[0] = 0;
+                       registers[1] = 0;
+                       registers[2] = 0;
+                       registers[3] = 0;
+               #endif
+       }
+
+       bool CPUID::detectMMX()
+       {
+               int registers[4];
+               cpuid(registers, 1);
+               return MMX = (registers[3] & 0x00800000) != 0;
+       }
+
+       bool CPUID::detectCMOV()
+       {
+               int registers[4];
+               cpuid(registers, 1);
+               return CMOV = (registers[3] & 0x00008000) != 0;
+       }
+
+       bool CPUID::detectSSE()
+       {
+               int registers[4];
+               cpuid(registers, 1);
+               return SSE = (registers[3] & 0x02000000) != 0;
+       }
+
+       bool CPUID::detectSSE2()
+       {
+               int registers[4];
+               cpuid(registers, 1);
+               return SSE2 = (registers[3] & 0x04000000) != 0;
+       }
+
+       bool CPUID::detectSSE3()
+       {
+               int registers[4];
+               cpuid(registers, 1);
+               return SSE3 = (registers[2] & 0x00000001) != 0;
+       }
+
+       bool CPUID::detectSSSE3()
+       {
+               int registers[4];
+               cpuid(registers, 1);
+               return SSSE3 = (registers[2] & 0x00000200) != 0;
+       }
+
+       bool CPUID::detectSSE4_1()
+       {
+               int registers[4];
+               cpuid(registers, 1);
+               return SSE4_1 = (registers[2] & 0x00080000) != 0;
+       }
+}
diff --git a/src/Reactor/CPUID.hpp b/src/Reactor/CPUID.hpp
new file mode 100644 (file)
index 0000000..108d4a7
--- /dev/null
@@ -0,0 +1,118 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef rr_CPUID_hpp
+#define rr_CPUID_hpp
+
+namespace rr
+{
+       #if !defined(__i386__) && defined(_M_IX86)
+               #define __i386__ 1
+       #endif
+
+       #if !defined(__x86_64__) && (defined(_M_AMD64) || defined (_M_X64))
+               #define __x86_64__ 1
+       #endif
+
+       class CPUID
+       {
+       public:
+               static bool supportsMMX();
+               static bool supportsCMOV();
+               static bool supportsMMX2();   // MMX instructions added by SSE: pshufw, pmulhuw, pmovmskb, pavgw/b, pextrw, pinsrw, pmaxsw/ub, etc.
+               static bool supportsSSE();
+               static bool supportsSSE2();
+               static bool supportsSSE3();
+               static bool supportsSSSE3();
+               static bool supportsSSE4_1();
+
+               static void setEnableMMX(bool enable);
+               static void setEnableCMOV(bool enable);
+               static void setEnableSSE(bool enable);
+               static void setEnableSSE2(bool enable);
+               static void setEnableSSE3(bool enable);
+               static void setEnableSSSE3(bool enable);
+               static void setEnableSSE4_1(bool enable);
+
+       private:
+               static bool MMX;
+               static bool CMOV;
+               static bool SSE;
+               static bool SSE2;
+               static bool SSE3;
+               static bool SSSE3;
+               static bool SSE4_1;
+
+               static bool enableMMX;
+               static bool enableCMOV;
+               static bool enableSSE;
+               static bool enableSSE2;
+               static bool enableSSE3;
+               static bool enableSSSE3;
+               static bool enableSSE4_1;
+
+               static bool detectMMX();
+               static bool detectCMOV();
+               static bool detectSSE();
+               static bool detectSSE2();
+               static bool detectSSE3();
+               static bool detectSSSE3();
+               static bool detectSSE4_1();
+       };
+}
+
+namespace rr
+{
+       inline bool CPUID::supportsMMX()
+       {
+               return MMX && enableMMX;
+       }
+
+       inline bool CPUID::supportsCMOV()
+       {
+               return CMOV && enableCMOV;
+       }
+
+       inline bool CPUID::supportsMMX2()
+       {
+               return supportsSSE();   // Coincides with 64-bit integer vector instructions supported by SSE
+       }
+
+       inline bool CPUID::supportsSSE()
+       {
+               return SSE && enableSSE;
+       }
+
+       inline bool CPUID::supportsSSE2()
+       {
+               return SSE2 && enableSSE2;
+       }
+
+       inline bool CPUID::supportsSSE3()
+       {
+               return SSE3 && enableSSE3;
+       }
+
+       inline bool CPUID::supportsSSSE3()
+       {
+               return SSSE3 && enableSSSE3;
+       }
+
+       inline bool CPUID::supportsSSE4_1()
+       {
+               return SSE4_1 && enableSSE4_1;
+       }
+}
+
+#endif   // rr_CPUID_hpp
diff --git a/src/Reactor/Debug.cpp b/src/Reactor/Debug.cpp
new file mode 100644 (file)
index 0000000..adfcabd
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "Debug.hpp"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+namespace rr
+{
+void trace(const char *format, ...)
+{
+       if(false)
+       {
+               FILE *file = fopen("debug.txt", "a");
+
+               if(file)
+               {
+                       va_list vararg;
+                       va_start(vararg, format);
+                       vfprintf(file, format, vararg);
+                       va_end(vararg);
+
+                       fclose(file);
+               }
+       }
+}
+}
\ No newline at end of file
diff --git a/src/Reactor/Debug.hpp b/src/Reactor/Debug.hpp
new file mode 100644 (file)
index 0000000..720b38a
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef Debug_hpp
+#define Debug_hpp
+
+#ifdef __ANDROID__
+#include "DebugAndroid.hpp"
+#else
+
+#include <assert.h>
+#include <stdio.h>
+
+#undef min
+#undef max
+
+namespace rr
+{
+void trace(const char *format, ...);
+
+#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
+       #define TRACE(format, ...) trace("[0x%0.8X]%s(" format ")\n", this, __FUNCTION__, ##__VA_ARGS__)
+#else
+       #define TRACE(...) ((void)0)
+#endif
+
+#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
+       #define UNIMPLEMENTED() {trace("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); ASSERT(false);}
+#else
+       #define UNIMPLEMENTED() ((void)0)
+#endif
+
+#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
+       #define ASSERT(expression) {if(!(expression)) trace("\t! Assert failed in %s(%d): " #expression "\n", __FUNCTION__, __LINE__); assert(expression);}
+#else
+       #define ASSERT assert
+#endif
+}
+
+#endif   // __ANDROID__
+#endif   // Debug_hpp
diff --git a/src/Reactor/DebugAndroid.cpp b/src/Reactor/DebugAndroid.cpp
new file mode 100644 (file)
index 0000000..c511fc3
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "DebugAndroid.hpp"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <cutils/properties.h>
+
+void AndroidEnterDebugger()
+{
+       ALOGE(__FUNCTION__);
+#ifndef NDEBUG
+       static volatile int * const makefault = nullptr;
+       char value[PROPERTY_VALUE_MAX];
+       property_get("debug.db.uid", value, "-1");
+       int debug_uid = atoi(value);
+       if((debug_uid >= 0) && (geteuid() < static_cast<uid_t>(debug_uid)))
+       {
+               ALOGE("Waiting for debugger: gdbserver :${PORT} --attach %u. Look for thread %u", getpid(), gettid());
+               volatile int waiting = 1;
+               while (waiting) {
+                       sleep(1);
+               }
+       }
+       else
+       {
+               ALOGE("No debugger");
+       }
+#endif
+}
+
+void trace(const char *format, ...)
+{
+#ifndef NDEBUG
+       va_list vararg;
+       va_start(vararg, format);
+       android_vprintLog(ANDROID_LOG_VERBOSE, NULL, LOG_TAG, format, vararg);
+       va_end(vararg);
+#endif
+}
diff --git a/src/Reactor/DebugAndroid.hpp b/src/Reactor/DebugAndroid.hpp
new file mode 100644 (file)
index 0000000..eced194
--- /dev/null
@@ -0,0 +1,99 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef DebugAndroid_hpp
+#define DebugAndroid_hpp
+
+#if ANDROID_PLATFORM_SDK_VERSION < 27
+#include <cutils/log.h>
+#elif ANDROID_PLATFORM_SDK_VERSION >= 27
+#include <log/log.h>
+#else
+#error "ANDROID_PLATFORM_SDK_VERSION is not defined"
+#endif
+
+#include <cassert>
+
+// On Android Virtual Devices we heavily depend on logging, even in
+// production builds. We do this because AVDs are components of larger
+// systems, and may be configured in ways that are difficult to
+// reproduce locally. For example some system run tests against
+// third-party code that we cannot access.  Aborting (cf. assert) on
+// unimplemented functionality creates two problems. First, it produces
+// a service failure where none is needed. Second, it puts the
+// customer on the critical path for notifying us of a problem.
+// The alternative, skipping unimplemented functionality silently, is
+// arguably worse: neither the service provider nor the customer will
+// learn that unimplemented functionality may have compromised the test
+// results.
+// Logging invocations of unimplemented functionality is useful to both
+// service provider and the customer. The service provider can learn
+// that the functionality is needed. The customer learns that the test
+// results may be compromised.
+
+/**
+ * Enter the debugger with a memory fault iff debuggerd is set to capture this
+ * process. Otherwise return.
+ */
+void AndroidEnterDebugger();
+
+#define ASSERT(E) do { \
+               if (!(E)) { \
+                       ALOGE("badness: assertion_failed %s in %s at %s:%d", #E,        \
+                                 __FUNCTION__, __FILE__, __LINE__);                                    \
+                       AndroidEnterDebugger();                                                                         \
+               }                                                                                                                               \
+       } while(0)
+
+#undef assert
+#define assert(E) ASSERT(E)
+
+#define ERR(format, ...)                                                                                               \
+       do {                                                                                                                            \
+               ALOGE("badness: err %s %s:%d (" format ")", __FUNCTION__, __FILE__, \
+                         __LINE__, ##__VA_ARGS__);                                                                     \
+               AndroidEnterDebugger();                                                                                 \
+       } while(0)
+
+#define FIXME(format, ...)                                                                                             \
+       do {                                                                                                                            \
+               ALOGE("badness: fixme %s %s:%d (" format ")", __FUNCTION__, __FILE__, \
+                         __LINE__, ##__VA_ARGS__);                                                                     \
+               AndroidEnterDebugger();                                                                                 \
+       } while(0)
+
+// TODO: Handle __VA_ARGS__ (can be empty)
+#define UNIMPLEMENTED(...) do {                                                \
+               ALOGE("badness: unimplemented: %s %s:%d",       \
+                         __FUNCTION__, __FILE__, __LINE__);    \
+               AndroidEnterDebugger();                                         \
+       } while(0)
+
+#define UNREACHABLE(value) do {                                         \
+               ALOGE("badness: unreachable case reached: %s %s:%d. %s: %d", \
+                         __FUNCTION__, __FILE__, __LINE__, #value, value);                     \
+               AndroidEnterDebugger();                                         \
+       } while(0)
+
+#ifndef NDEBUG
+       #define TRACE(format, ...)                                                                 \
+               ALOGV("%s %s:%d (" format ")", __FUNCTION__, __FILE__, \
+                         __LINE__, ##__VA_ARGS__)
+#else
+       #define TRACE(...) ((void)0)
+#endif
+
+void trace(const char *format, ...);
+
+#endif   // DebugAndroid_hpp
index b702ec9..0f3b3da 100644 (file)
 
 #include "Reactor.hpp"
 
+#include "x86.hpp"
+#include "CPUID.hpp"
+#include "Thread.hpp"
+#include "Memory.hpp"
+#include "MutexLock.hpp"
+
+#undef min
+#undef max
+
 #if SWIFTSHADER_LLVM_VERSION < 7
        #include "llvm/Analysis/LoopPass.h"
        #include "llvm/Constants.h"
        #include <unordered_map>
 #endif
 
-#include "x86.hpp"
-#include "Common/CPUID.hpp"
-#include "Common/Thread.hpp"
-#include "Common/Memory.hpp"
-#include "Common/MutexLock.hpp"
-
 #include <numeric>
 #include <fstream>
 
@@ -120,7 +123,7 @@ namespace
        llvm::Module *module = nullptr;
        llvm::Function *function = nullptr;
 
-       sw::MutexLock codegenMutex;
+       rr::MutexLock codegenMutex;
 
 #if SWIFTSHADER_LLVM_VERSION >= 7
        llvm::Value *lowerPAVG(llvm::Value *x, llvm::Value *y)
@@ -443,8 +446,6 @@ namespace
 
 namespace rr
 {
-       using namespace sw;
-
 #if SWIFTSHADER_LLVM_VERSION < 7
        class LLVMReactorJIT
        {
index 8dbfe07..6b37fa6 100644 (file)
 
 #include "LLVMRoutine.hpp"
 
-#include "Common/Memory.hpp"
-#include "Common/Thread.hpp"
-#include "Common/Types.hpp"
+#include "Memory.hpp"
+#include "Thread.hpp"
+#include "Types.hpp"
 
 namespace rr
 {
 #if SWIFTSHADER_LLVM_VERSION < 7
        LLVMRoutine::LLVMRoutine(int bufferSize) : bufferSize(bufferSize)
        {
-               void *memory = sw::allocateExecutable(bufferSize);
+               void *memory = allocateExecutable(bufferSize);
 
                buffer = memory;
                entry = memory;
@@ -32,7 +32,7 @@ namespace rr
 
        LLVMRoutine::~LLVMRoutine()
        {
-               sw::deallocateExecutable(buffer, bufferSize);
+               deallocateExecutable(buffer, bufferSize);
        }
 
        const void *LLVMRoutine::getEntry()
index 8af37f3..276bdd9 100644 (file)
@@ -18,9 +18,9 @@
 
 #include "LLVMRoutine.hpp"
 #include "llvm/Function.h"
-#include "Common/Memory.hpp"
-#include "Common/Thread.hpp"
-#include "Common/Debug.hpp"
+#include "Memory.hpp"
+#include "Thread.hpp"
+#include "Debug.hpp"
 
 namespace rr
 {
@@ -63,11 +63,11 @@ namespace rr
                }
                else   // Estimate was too low
                {
-                       sw::atomicIncrement(&averageInstructionSize);
+                       atomicIncrement(&averageInstructionSize);
                }
 
                // Round up to the next page size
-               size_t pageSize = sw::memoryPageSize();
+               size_t pageSize = memoryPageSize();
                actualSize = (actualSize + pageSize - 1) & ~(pageSize - 1);
 
                delete routine;
@@ -130,7 +130,7 @@ namespace rr
 
        void LLVMRoutineManager::setMemoryExecutable()
        {
-               sw::markExecutable(routine->buffer, routine->bufferSize);
+               markExecutable(routine->buffer, routine->bufferSize);
        }
 
        void LLVMRoutineManager::setPoisonMemory(bool poison)
diff --git a/src/Reactor/Memory.cpp b/src/Reactor/Memory.cpp
new file mode 100644 (file)
index 0000000..c7c3d6d
--- /dev/null
@@ -0,0 +1,262 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "Memory.hpp"
+
+#include "Types.hpp"
+#include "Debug.hpp"
+
+#if defined(_WIN32)
+       #ifndef WIN32_LEAN_AND_MEAN
+               #define WIN32_LEAN_AND_MEAN
+       #endif
+       #include <windows.h>
+       #include <intrin.h>
+#else
+       #include <errno.h>
+       #include <sys/mman.h>
+       #include <stdlib.h>
+       #include <unistd.h>
+#endif
+
+#include <memory.h>
+
+#undef allocate
+#undef deallocate
+
+#if (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined (_M_X64)) && !defined(__x86__)
+#define __x86__
+#endif
+
+namespace rr
+{
+namespace
+{
+struct Allocation
+{
+//     size_t bytes;
+       unsigned char *block;
+};
+
+void *allocateRaw(size_t bytes, size_t alignment)
+{
+       ASSERT((alignment & (alignment - 1)) == 0);   // Power of 2 alignment.
+
+       #if defined(LINUX_ENABLE_NAMED_MMAP)
+               void *allocation;
+               int result = posix_memalign(&allocation, alignment, bytes);
+               if(result != 0)
+               {
+                       errno = result;
+                       allocation = nullptr;
+               }
+               return allocation;
+       #else
+               unsigned char *block = new unsigned char[bytes + sizeof(Allocation) + alignment];
+               unsigned char *aligned = nullptr;
+
+               if(block)
+               {
+                       aligned = (unsigned char*)((uintptr_t)(block + sizeof(Allocation) + alignment - 1) & -(intptr_t)alignment);
+                       Allocation *allocation = (Allocation*)(aligned - sizeof(Allocation));
+
+               //      allocation->bytes = bytes;
+                       allocation->block = block;
+               }
+
+               return aligned;
+       #endif
+}
+
+#if defined(LINUX_ENABLE_NAMED_MMAP)
+// Create a file descriptor for anonymous memory with the given
+// name. Returns -1 on failure.
+// TODO: remove once libc wrapper exists.
+int memfd_create(const char* name, unsigned int flags)
+{
+       #if __aarch64__
+       #define __NR_memfd_create 279
+       #elif __arm__
+       #define __NR_memfd_create 279
+       #elif __powerpc64__
+       #define __NR_memfd_create 360
+       #elif __i386__
+       #define __NR_memfd_create 356
+       #elif __x86_64__
+       #define __NR_memfd_create 319
+       #endif /* __NR_memfd_create__ */
+       #ifdef __NR_memfd_create
+               // In the event of no system call this returns -1 with errno set
+               // as ENOSYS.
+               return syscall(__NR_memfd_create, name, flags);
+       #else
+               return -1;
+       #endif
+}
+
+// Returns a file descriptor for use with an anonymous mmap, if
+// memfd_create fails, -1 is returned. Note, the mappings should be
+// MAP_PRIVATE so that underlying pages aren't shared.
+int anonymousFd()
+{
+       static int fd = memfd_create("SwiftShader JIT", 0);
+       return fd;
+}
+
+// Ensure there is enough space in the "anonymous" fd for length.
+void ensureAnonFileSize(int anonFd, size_t length)
+{
+       static size_t fileSize = 0;
+       if(length > fileSize)
+       {
+               ftruncate(anonFd, length);
+               fileSize = length;
+       }
+}
+#endif  // defined(LINUX_ENABLE_NAMED_MMAP)
+
+}  // anonymous namespace
+
+size_t memoryPageSize()
+{
+       static int pageSize = 0;
+
+       if(pageSize == 0)
+       {
+               #if defined(_WIN32)
+                       SYSTEM_INFO systemInfo;
+                       GetSystemInfo(&systemInfo);
+                       pageSize = systemInfo.dwPageSize;
+               #else
+                       pageSize = sysconf(_SC_PAGESIZE);
+               #endif
+       }
+
+       return pageSize;
+}
+
+void *allocate(size_t bytes, size_t alignment)
+{
+       void *memory = allocateRaw(bytes, alignment);
+
+       if(memory)
+       {
+               memset(memory, 0, bytes);
+       }
+
+       return memory;
+}
+
+void deallocate(void *memory)
+{
+       #if defined(LINUX_ENABLE_NAMED_MMAP)
+               free(memory);
+       #else
+               if(memory)
+               {
+                       unsigned char *aligned = (unsigned char*)memory;
+                       Allocation *allocation = (Allocation*)(aligned - sizeof(Allocation));
+
+                       delete[] allocation->block;
+               }
+       #endif
+}
+
+void *allocateExecutable(size_t bytes)
+{
+       size_t pageSize = memoryPageSize();
+       size_t length = (bytes + pageSize - 1) & ~(pageSize - 1);
+       void *mapping;
+
+       #if defined(LINUX_ENABLE_NAMED_MMAP)
+               // Try to name the memory region for the executable code,
+               // to aid profilers.
+               int anonFd = anonymousFd();
+               if(anonFd == -1)
+               {
+                       mapping = mmap(nullptr, length, PROT_READ | PROT_WRITE,
+                                      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+               }
+               else
+               {
+                       ensureAnonFileSize(anonFd, length);
+                       mapping = mmap(nullptr, length, PROT_READ | PROT_WRITE,
+                                      MAP_PRIVATE, anonFd, 0);
+               }
+
+               if(mapping == MAP_FAILED)
+               {
+                       mapping = nullptr;
+               }
+       #else
+               mapping = allocate(length, pageSize);
+       #endif
+
+       return mapping;
+}
+
+void markExecutable(void *memory, size_t bytes)
+{
+       #if defined(_WIN32)
+               unsigned long oldProtection;
+               VirtualProtect(memory, bytes, PAGE_EXECUTE_READ, &oldProtection);
+       #else
+               mprotect(memory, bytes, PROT_READ | PROT_EXEC);
+       #endif
+}
+
+void deallocateExecutable(void *memory, size_t bytes)
+{
+       #if defined(_WIN32)
+               unsigned long oldProtection;
+               VirtualProtect(memory, bytes, PAGE_READWRITE, &oldProtection);
+               deallocate(memory);
+       #elif defined(LINUX_ENABLE_NAMED_MMAP)
+               size_t pageSize = memoryPageSize();
+               size_t length = (bytes + pageSize - 1) & ~(pageSize - 1);
+               munmap(memory, length);
+       #else
+               mprotect(memory, bytes, PROT_READ | PROT_WRITE);
+               deallocate(memory);
+       #endif
+}
+
+void clear(uint16_t *memory, uint16_t element, size_t count)
+{
+       #if defined(_MSC_VER) && defined(__x86__) && !defined(MEMORY_SANITIZER)
+               __stosw(memory, element, count);
+       #elif defined(__GNUC__) && defined(__x86__) && !defined(MEMORY_SANITIZER)
+               __asm__("rep stosw" : : "D"(memory), "a"(element), "c"(count));
+       #else
+               for(size_t i = 0; i < count; i++)
+               {
+                       memory[i] = element;
+               }
+       #endif
+}
+
+void clear(uint32_t *memory, uint32_t element, size_t count)
+{
+       #if defined(_MSC_VER) && defined(__x86__) && !defined(MEMORY_SANITIZER)
+               __stosd((unsigned long*)memory, element, count);
+       #elif defined(__GNUC__) && defined(__x86__) && !defined(MEMORY_SANITIZER)
+               __asm__("rep stosl" : : "D"(memory), "a"(element), "c"(count));
+       #else
+               for(size_t i = 0; i < count; i++)
+               {
+                       memory[i] = element;
+               }
+       #endif
+}
+}
diff --git a/src/Reactor/Memory.hpp b/src/Reactor/Memory.hpp
new file mode 100644 (file)
index 0000000..3517f3c
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef rr_Memory_hpp
+#define rr_Memory_hpp
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace rr
+{
+size_t memoryPageSize();
+
+void *allocate(size_t bytes, size_t alignment = 16);
+void deallocate(void *memory);
+
+void *allocateExecutable(size_t bytes);   // Allocates memory that can be made executable using markExecutable()
+void markExecutable(void *memory, size_t bytes);
+void deallocateExecutable(void *memory, size_t bytes);
+
+void clear(uint16_t *memory, uint16_t element, size_t count);
+void clear(uint32_t *memory, uint32_t element, size_t count);
+}
+
+#endif   // rr_Memory_hpp
diff --git a/src/Reactor/MutexLock.hpp b/src/Reactor/MutexLock.hpp
new file mode 100644 (file)
index 0000000..c2d00eb
--- /dev/null
@@ -0,0 +1,177 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef rr_MutexLock_hpp
+#define rr_MutexLock_hpp
+
+#include "Thread.hpp"
+
+#if defined(__linux__)
+// Use a pthread mutex on Linux. Since many processes may use SwiftShader
+// at the same time it's best to just have the scheduler overhead.
+#include <pthread.h>
+
+namespace rr
+{
+       class MutexLock
+       {
+       public:
+               MutexLock()
+               {
+                       pthread_mutex_init(&mutex, NULL);
+               }
+
+               ~MutexLock()
+               {
+                       pthread_mutex_destroy(&mutex);
+               }
+
+               bool attemptLock()
+               {
+                       return pthread_mutex_trylock(&mutex) == 0;
+               }
+
+               void lock()
+               {
+                       pthread_mutex_lock(&mutex);
+               }
+
+               void unlock()
+               {
+                       pthread_mutex_unlock(&mutex);
+               }
+
+       private:
+               pthread_mutex_t mutex;
+       };
+}
+
+#else   // !__linux__
+
+#include <atomic>
+
+namespace rr
+{
+       class BackoffLock
+       {
+       public:
+               BackoffLock()
+               {
+                       mutex = 0;
+               }
+
+               bool attemptLock()
+               {
+                       if(!isLocked())
+                       {
+                               if(mutex.exchange(true) == false)
+                               {
+                                       return true;
+                               }
+                       }
+
+                       return false;
+               }
+
+               void lock()
+               {
+                       int backoff = 1;
+
+                       while(!attemptLock())
+                       {
+                               if(backoff <= 64)
+                               {
+                                       for(int i = 0; i < backoff; i++)
+                                       {
+                                               nop();
+                                               nop();
+                                               nop();
+                                               nop();
+                                               nop();
+
+                                               nop();
+                                               nop();
+                                               nop();
+                                               nop();
+                                               nop();
+
+                                               nop();
+                                               nop();
+                                               nop();
+                                               nop();
+                                               nop();
+
+                                               nop();
+                                               nop();
+                                               nop();
+                                               nop();
+                                               nop();
+
+                                               nop();
+                                               nop();
+                                               nop();
+                                               nop();
+                                               nop();
+
+                                               nop();
+                                               nop();
+                                               nop();
+                                               nop();
+                                               nop();
+
+                                               nop();
+                                               nop();
+                                               nop();
+                                               nop();
+                                               nop();
+                                       }
+
+                                       backoff *= 2;
+                               }
+                               else
+                               {
+                                       Thread::yield();
+
+                                       backoff = 1;
+                               }
+                       };
+               }
+
+               void unlock()
+               {
+                       mutex.store(false, std::memory_order_release);
+               }
+
+               bool isLocked()
+               {
+                       return mutex.load(std::memory_order_acquire);
+               }
+
+       private:
+               struct
+               {
+                       // Ensure that the mutex variable is on its own 64-byte cache line to avoid false sharing
+                       // Padding must be public to avoid compiler warnings
+                       volatile int padding1[16];
+                       std::atomic<bool> mutex;
+                       volatile int padding2[15];
+               };
+       };
+
+       using MutexLock = BackoffLock;
+}
+
+#endif   // !__linux__
+
+#endif   // rr_MutexLock_hpp
index 788de64..dbf7b5f 100644 (file)
     </ProjectReference>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
+    <ClCompile Include="CPUID.cpp" />\r
+    <ClCompile Include="Debug.cpp" />\r
     <ClCompile Include="LLVMRoutine.cpp" />\r
     <ClCompile Include="LLVMRoutineManager.cpp" />\r
     <ClCompile Include="LLVMReactor.cpp" />\r
+    <ClCompile Include="Memory.cpp" />\r
     <ClCompile Include="Routine.cpp" />\r
+    <ClCompile Include="Thread.cpp" />\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <ClInclude Include="CPUID.hpp" />\r
+    <ClInclude Include="Debug.hpp" />\r
     <ClInclude Include="LLVMRoutine.hpp" />\r
     <ClInclude Include="LLVMRoutineManager.hpp" />\r
+    <ClInclude Include="Memory.hpp" />\r
+    <ClInclude Include="MutexLock.hpp" />\r
     <ClInclude Include="Nucleus.hpp" />\r
     <ClInclude Include="Reactor.hpp" />\r
     <ClInclude Include="Routine.hpp" />\r
+    <ClInclude Include="Thread.hpp" />\r
+    <ClInclude Include="Types.hpp" />\r
     <ClInclude Include="x86.hpp" />\r
   </ItemGroup>\r
   <ItemGroup>\r
index 2aebff5..34bb0f1 100644 (file)
     <ClCompile Include="LLVMReactor.cpp">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="CPUID.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Debug.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Memory.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Thread.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="Nucleus.hpp">\r
     <ClInclude Include="LLVMRoutine.hpp">\r
       <Filter>Header Files</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="CPUID.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Debug.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Memory.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="MutexLock.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Thread.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Types.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
 </Project>
\ No newline at end of file
similarity index 97%
rename from src/Reactor/Main.cpp
rename to src/Reactor/ReactorUnitTests.cpp
index 2bc9f7e..f6484f4 100644 (file)
@@ -33,7 +33,7 @@ int reference(int *p, int y)
        return sum;
 }
 
-TEST(SubzeroReactorTest, Sample)
+TEST(ReactorUnitTests, Sample)
 {
        Routine *routine = nullptr;
 
@@ -73,7 +73,7 @@ TEST(SubzeroReactorTest, Sample)
        delete routine;
 }
 
-TEST(SubzeroReactorTest, Uninitialized)
+TEST(ReactorUnitTests, Uninitialized)
 {
        Routine *routine = nullptr;
 
@@ -110,7 +110,7 @@ TEST(SubzeroReactorTest, Uninitialized)
        delete routine;
 }
 
-TEST(SubzeroReactorTest, SubVectorLoadStore)
+TEST(ReactorUnitTests, SubVectorLoadStore)
 {
        Routine *routine = nullptr;
 
@@ -170,7 +170,7 @@ TEST(SubzeroReactorTest, SubVectorLoadStore)
        delete routine;
 }
 
-TEST(SubzeroReactorTest, VectorConstant)
+TEST(ReactorUnitTests, VectorConstant)
 {
        Routine *routine = nullptr;
 
@@ -219,7 +219,7 @@ TEST(SubzeroReactorTest, VectorConstant)
        delete routine;
 }
 
-TEST(SubzeroReactorTest, Concatenate)
+TEST(ReactorUnitTests, Concatenate)
 {
        Routine *routine = nullptr;
 
@@ -262,7 +262,7 @@ TEST(SubzeroReactorTest, Concatenate)
        delete routine;
 }
 
-TEST(SubzeroReactorTest, Swizzle)
+TEST(ReactorUnitTests, Swizzle)
 {
        Routine *routine = nullptr;
 
@@ -389,7 +389,7 @@ TEST(SubzeroReactorTest, Swizzle)
        delete routine;
 }
 
-TEST(SubzeroReactorTest, Branching)
+TEST(ReactorUnitTests, Branching)
 {
        Routine *routine = nullptr;
 
@@ -454,7 +454,7 @@ TEST(SubzeroReactorTest, Branching)
        delete routine;
 }
 
-TEST(SubzeroReactorTest, MinMax)
+TEST(ReactorUnitTests, MinMax)
 {
        Routine *routine = nullptr;
 
@@ -545,7 +545,7 @@ TEST(SubzeroReactorTest, MinMax)
        delete routine;
 }
 
-TEST(SubzeroReactorTest, NotNeg)
+TEST(ReactorUnitTests, NotNeg)
 {
        Routine *routine = nullptr;
 
@@ -630,7 +630,7 @@ TEST(SubzeroReactorTest, NotNeg)
        delete routine;
 }
 
-TEST(SubzeroReactorTest, VectorCompare)
+TEST(ReactorUnitTests, VectorCompare)
 {
        Routine *routine = nullptr;
 
@@ -692,7 +692,7 @@ TEST(SubzeroReactorTest, VectorCompare)
        delete routine;
 }
 
-TEST(SubzeroReactorTest, SaturatedAddAndSubtract)
+TEST(ReactorUnitTests, SaturatedAddAndSubtract)
 {
        Routine *routine = nullptr;
 
@@ -805,7 +805,7 @@ TEST(SubzeroReactorTest, SaturatedAddAndSubtract)
        delete routine;
 }
 
-TEST(SubzeroReactorTest, Unpack)
+TEST(ReactorUnitTests, Unpack)
 {
        Routine *routine = nullptr;
 
@@ -852,7 +852,7 @@ TEST(SubzeroReactorTest, Unpack)
        delete routine;
 }
 
-TEST(SubzeroReactorTest, Pack)
+TEST(ReactorUnitTests, Pack)
 {
        Routine *routine = nullptr;
 
@@ -914,7 +914,7 @@ TEST(SubzeroReactorTest, Pack)
        delete routine;
 }
 
-TEST(SubzeroReactorTest, MulHigh)
+TEST(ReactorUnitTests, MulHigh)
 {
        Routine *routine = nullptr;
 
@@ -956,7 +956,7 @@ TEST(SubzeroReactorTest, MulHigh)
        delete routine;
 }
 
-TEST(SubzeroReactorTest, MulAdd)
+TEST(ReactorUnitTests, MulAdd)
 {
        Routine *routine = nullptr;
 
similarity index 71%
rename from src/Reactor/SubzeroTest.vcxproj
rename to src/Reactor/ReactorUnitTests.vcxproj
index 218073b..0471ba6 100644 (file)
@@ -21,7 +21,7 @@
   <PropertyGroup Label="Globals">\r
     <ProjectGuid>{4EC107AB-89E8-4A0B-8366-B3E81085AE07}</ProjectGuid>\r
     <Keyword>Win32Proj</Keyword>\r
-    <RootNamespace>SubzeroTest</RootNamespace>\r
+    <RootNamespace>ReactorUnitTests</RootNamespace>\r
     <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>\r
   </PropertyGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
     </Link>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
-    <ProjectReference Include="Subzero.vcxproj">\r
-      <Project>{0eb31aec-b020-46ab-ba05-730f6d01c29b}</Project>\r
-      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
-      <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
-      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
-    </ProjectReference>\r
-  </ItemGroup>\r
-  <ItemGroup>\r
     <ClCompile Include="..\..\third_party\googletest\googletest\src\gtest-all.cc" />\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8632\ControlFlow.cpp">\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8632\DataMov.cpp">\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8632\LowLevel.cpp">\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8632\Other.cpp">\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8632\XmmArith.cpp">\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8664\ControlFlow.cpp">\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8664\DataMov.cpp">\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8664\LowLevel.cpp">\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8664\Other.cpp">\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8664\XmmArith.cpp">\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
-    </ClCompile>\r
-    <ClCompile Include="Main.cpp" />\r
+    <ClCompile Include="ReactorUnitTests.cpp" />\r
   </ItemGroup>\r
   <ItemGroup>\r
-    <ClInclude Include="..\..\third_party\subzero\unittest\AssemblerX8632\TestUtil.h">\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>\r
-    </ClInclude>\r
-    <ClInclude Include="..\..\third_party\subzero\unittest\AssemblerX8664\TestUtil.h">\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
-      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>\r
-    </ClInclude>\r
+    <ProjectReference Include="Subzero.vcxproj">\r
+      <Project>{0eb31aec-b020-46ab-ba05-730f6d01c29b}</Project>\r
+    </ProjectReference>\r
   </ItemGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
   <ImportGroup Label="ExtensionTargets">\r
diff --git a/src/Reactor/ReactorUnitTests.vcxproj.filters b/src/Reactor/ReactorUnitTests.vcxproj.filters
new file mode 100644 (file)
index 0000000..721fc57
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup>\r
+    <Filter Include="Source Files">\r
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r
+    </Filter>\r
+    <Filter Include="Header Files">\r
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r
+      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\r
+    </Filter>\r
+    <Filter Include="Resource Files">\r
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r
+    </Filter>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="..\..\third_party\googletest\googletest\src\gtest-all.cc">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="ReactorUnitTests.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+  </ItemGroup>\r
+</Project>
\ No newline at end of file
index 5899c58..23cf929 100644 (file)
@@ -14,7 +14,7 @@
 
 #include "Routine.hpp"
 
-#include "Common/Thread.hpp"
+#include "Thread.hpp"
 
 #include <cassert>
 
@@ -27,12 +27,12 @@ namespace rr
 
        void Routine::bind()
        {
-               sw::atomicIncrement(&bindCount);
+               atomicIncrement(&bindCount);
        }
 
        void Routine::unbind()
        {
-               long count = sw::atomicDecrement(&bindCount);
+               long count = atomicDecrement(&bindCount);
 
                if(count == 0)
                {
index 7f7525e..3aaf7b4 100644 (file)
@@ -95,7 +95,7 @@
       <Optimization>Disabled</Optimization>\r
       <PreprocessorDefinitions>SZTARGET=X8632;ALLOW_DUMP=0;ALLOW_TIMERS=0;ALLOW_LLVM_CL=0;ALLOW_LLVM_IR=0;ALLOW_LLVM_IR_AS_INPUT=0;ALLOW_MINIMAL_BUILD=0;ALLOW_WASM=0;ICE_THREAD_LOCAL_HACK=0;SUBZERO_USE_MICROSOFT_ABI;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <AdditionalUsingDirectories>%(AdditionalUsingDirectories)</AdditionalUsingDirectories>\r
-      <AdditionalIncludeDirectories>$(SolutionDir)third_party\subzero;$(SolutionDir)third_party\llvm-subzero\include;$(SolutionDir)third_party\llvm-subzero\build\Windows\include;$(SolutionDir)third_party\subzero\pnacl-llvm\include;$(SolutionDir)src\</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)third_party\subzero;$(SolutionDir)third_party\llvm-subzero\include;$(SolutionDir)third_party\llvm-subzero\build\Windows\include;$(SolutionDir)third_party\subzero\pnacl-llvm\include</AdditionalIncludeDirectories>\r
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
       <ForcedIncludeFiles>src/IceTypes.h</ForcedIncludeFiles>\r
       <MultiProcessorCompilation>true</MultiProcessorCompilation>\r
       <Optimization>Disabled</Optimization>\r
       <PreprocessorDefinitions>SZTARGET=X8664;ALLOW_DUMP=0;ALLOW_TIMERS=0;ALLOW_LLVM_CL=0;ALLOW_LLVM_IR=0;ALLOW_LLVM_IR_AS_INPUT=0;ALLOW_MINIMAL_BUILD=0;ALLOW_WASM=0;ICE_THREAD_LOCAL_HACK=0;SUBZERO_USE_MICROSOFT_ABI;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <AdditionalUsingDirectories>%(AdditionalUsingDirectories)</AdditionalUsingDirectories>\r
-      <AdditionalIncludeDirectories>$(SolutionDir)third_party\subzero;$(SolutionDir)third_party\llvm-subzero\include;$(SolutionDir)third_party\llvm-subzero\build\Windows\include;$(SolutionDir)third_party\subzero\pnacl-llvm\include;$(SolutionDir)src\</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)third_party\subzero;$(SolutionDir)third_party\llvm-subzero\include;$(SolutionDir)third_party\llvm-subzero\build\Windows\include;$(SolutionDir)third_party\subzero\pnacl-llvm\include</AdditionalIncludeDirectories>\r
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
       <ForcedIncludeFiles>src/IceTypes.h</ForcedIncludeFiles>\r
       <MultiProcessorCompilation>true</MultiProcessorCompilation>\r
       <IntrinsicFunctions>true</IntrinsicFunctions>\r
       <PreprocessorDefinitions>SZTARGET=X8632;ALLOW_DUMP=0;ALLOW_TIMERS=0;ALLOW_LLVM_CL=0;ALLOW_LLVM_IR=0;ALLOW_LLVM_IR_AS_INPUT=0;ALLOW_MINIMAL_BUILD=0;ALLOW_WASM=0;ICE_THREAD_LOCAL_HACK=0;SUBZERO_USE_MICROSOFT_ABI;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <AdditionalUsingDirectories>%(AdditionalUsingDirectories)</AdditionalUsingDirectories>\r
-      <AdditionalIncludeDirectories>$(SolutionDir)third_party\subzero;$(SolutionDir)third_party\llvm-subzero\include;$(SolutionDir)third_party\llvm-subzero\build\Windows\include;$(SolutionDir)third_party\subzero\pnacl-llvm\include;$(SolutionDir)src\</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)third_party\subzero;$(SolutionDir)third_party\llvm-subzero\include;$(SolutionDir)third_party\llvm-subzero\build\Windows\include;$(SolutionDir)third_party\subzero\pnacl-llvm\include</AdditionalIncludeDirectories>\r
       <ForcedIncludeFiles>src/IceTypes.h</ForcedIncludeFiles>\r
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
       <MultiProcessorCompilation>true</MultiProcessorCompilation>\r
       <IntrinsicFunctions>true</IntrinsicFunctions>\r
       <PreprocessorDefinitions>SZTARGET=X8664;ALLOW_DUMP=0;ALLOW_TIMERS=0;ALLOW_LLVM_CL=0;ALLOW_LLVM_IR=0;ALLOW_LLVM_IR_AS_INPUT=0;ALLOW_MINIMAL_BUILD=0;ALLOW_WASM=0;ICE_THREAD_LOCAL_HACK=0;SUBZERO_USE_MICROSOFT_ABI;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
       <AdditionalUsingDirectories>%(AdditionalUsingDirectories)</AdditionalUsingDirectories>\r
-      <AdditionalIncludeDirectories>$(SolutionDir)third_party\subzero;$(SolutionDir)third_party\llvm-subzero\include;$(SolutionDir)third_party\llvm-subzero\build\Windows\include;$(SolutionDir)third_party\subzero\pnacl-llvm\include;$(SolutionDir)src\</AdditionalIncludeDirectories>\r
+      <AdditionalIncludeDirectories>$(SolutionDir)third_party\subzero;$(SolutionDir)third_party\llvm-subzero\include;$(SolutionDir)third_party\llvm-subzero\build\Windows\include;$(SolutionDir)third_party\subzero\pnacl-llvm\include</AdditionalIncludeDirectories>\r
       <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>\r
       <OmitFramePointers>true</OmitFramePointers>\r
       <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>\r
     <ClCompile Include="$(SolutionDir)third_party\subzero\src\IceTimerTree.cpp" />\r
     <ClCompile Include="$(SolutionDir)third_party\subzero\src\IceTypes.cpp" />\r
     <ClCompile Include="$(SolutionDir)third_party\subzero\src\IceVariableSplitting.cpp" />\r
-    <ClCompile Include="..\Common\Debug.cpp" />\r
-    <ClCompile Include="..\Common\Memory.cpp" />\r
+    <ClCompile Include="CPUID.cpp" />\r
+    <ClCompile Include="Debug.cpp" />\r
+    <ClCompile Include="Memory.cpp" />\r
     <ClCompile Include="Optimizer.cpp" />\r
     <ClCompile Include="Routine.cpp" />\r
     <ClCompile Include="SubzeroReactor.cpp" />\r
     <ClInclude Include="$(SolutionDir)third_party\subzero\src\IceConditionCodesX8664.h" />\r
     <ClInclude Include="$(SolutionDir)third_party\subzero\src\IceInstX8664.h" />\r
     <ClInclude Include="$(SolutionDir)third_party\subzero\src\IceRegistersX8664.h" />\r
+    <ClInclude Include="CPUID.hpp" />\r
+    <ClInclude Include="Debug.hpp" />\r
     <ClInclude Include="Optimizer.hpp" />\r
   </ItemGroup>\r
   <ItemGroup>\r
   <ItemGroup>\r
     <ProjectReference Include="SubzeroLLVMDependencies.vcxproj">\r
       <Project>{e3bbd7da-45c1-43ef-9c87-3f411031bde4}</Project>\r
+      <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
     </ProjectReference>\r
   </ItemGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
index 68cb2e8..42f0bda 100644 (file)
     <ClCompile Include="Optimizer.cpp">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\Common\Memory.cpp">\r
+    <ClCompile Include="CPUID.cpp">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="..\Common\Debug.cpp">\r
+    <ClCompile Include="Memory.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="Debug.cpp">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
   </ItemGroup>\r
     <ClInclude Include="Optimizer.hpp">\r
       <Filter>Header Files</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="CPUID.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="Debug.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <None Include="$(SolutionDir)third_party\subzero\src\IceClFlags.def">\r
index b92005c..a691037 100644 (file)
@@ -15,8 +15,7 @@
 #include "Reactor.hpp"
 
 #include "Optimizer.hpp"
-
-#include "Common/Memory.hpp"
+#include "Memory.hpp"
 
 #include "src/IceTypes.h"
 #include "src/IceCfg.h"
@@ -49,7 +48,7 @@
 #endif
 #endif
 
-//#include <mutex>
+#include <mutex>
 #include <limits>
 #include <iostream>
 #include <cassert>
@@ -427,12 +426,12 @@ namespace rr
 
                T *allocate(size_type n)
                {
-                       return (T*)sw::allocateExecutable(sizeof(T) * n);
+                       return (T*)allocateExecutable(sizeof(T) * n);
                }
 
                void deallocate(T *p, size_type n)
                {
-                       sw::deallocateExecutable(p, sizeof(T) * n);
+                       deallocateExecutable(p, sizeof(T) * n);
                }
        };
 
diff --git a/src/Reactor/SubzeroTest.vcxproj.filters b/src/Reactor/SubzeroTest.vcxproj.filters
deleted file mode 100644 (file)
index 4fc3643..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>\r
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
-  <ItemGroup>\r
-    <Filter Include="Source Files">\r
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r
-    </Filter>\r
-    <Filter Include="Header Files">\r
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r
-      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\r
-    </Filter>\r
-    <Filter Include="Resource Files">\r
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r
-    </Filter>\r
-  </ItemGroup>\r
-  <ItemGroup>\r
-    <ClCompile Include="Main.cpp">\r
-      <Filter>Source Files</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\googletest\googletest\src\gtest-all.cc">\r
-      <Filter>Source Files</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8632\XmmArith.cpp">\r
-      <Filter>Source Files</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8664\XmmArith.cpp">\r
-      <Filter>Source Files</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8664\DataMov.cpp">\r
-      <Filter>Source Files</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8632\DataMov.cpp">\r
-      <Filter>Source Files</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8664\ControlFlow.cpp">\r
-      <Filter>Source Files</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8632\ControlFlow.cpp">\r
-      <Filter>Source Files</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8664\LowLevel.cpp">\r
-      <Filter>Source Files</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8664\Other.cpp">\r
-      <Filter>Source Files</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8632\LowLevel.cpp">\r
-      <Filter>Source Files</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="..\..\third_party\subzero\unittest\AssemblerX8632\Other.cpp">\r
-      <Filter>Source Files</Filter>\r
-    </ClCompile>\r
-  </ItemGroup>\r
-  <ItemGroup>\r
-    <ClInclude Include="..\..\third_party\subzero\unittest\AssemblerX8632\TestUtil.h">\r
-      <Filter>Header Files</Filter>\r
-    </ClInclude>\r
-    <ClInclude Include="..\..\third_party\subzero\unittest\AssemblerX8664\TestUtil.h">\r
-      <Filter>Header Files</Filter>\r
-    </ClInclude>\r
-  </ItemGroup>\r
-</Project>
\ No newline at end of file
diff --git a/src/Reactor/Thread.cpp b/src/Reactor/Thread.cpp
new file mode 100644 (file)
index 0000000..7a9b07d
--- /dev/null
@@ -0,0 +1,91 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "Thread.hpp"
+
+namespace rr
+{
+       Thread::Thread(void (*threadFunction)(void *parameters), void *parameters)
+       {
+               Event init;
+               Entry entry = {threadFunction, parameters, &init};
+
+               #if defined(_WIN32)
+                       handle = CreateThread(NULL, 1024 * 1024, startFunction, &entry, 0, NULL);
+               #else
+                       pthread_create(&handle, NULL, startFunction, &entry);
+               #endif
+
+               init.wait();
+       }
+
+       Thread::~Thread()
+       {
+               join();   // Make threads exit before deleting them to not block here
+       }
+
+       void Thread::join()
+       {
+               if(!hasJoined)
+               {
+                       #if defined(_WIN32)
+                               WaitForSingleObject(handle, INFINITE);
+                               CloseHandle(handle);
+                       #else
+                               pthread_join(handle, NULL);
+                       #endif
+
+                       hasJoined = true;
+               }
+       }
+
+       #if defined(_WIN32)
+               unsigned long __stdcall Thread::startFunction(void *parameters)
+               {
+                       Entry entry = *(Entry*)parameters;
+                       entry.init->signal();
+                       entry.threadFunction(entry.threadParameters);
+                       return 0;
+               }
+       #else
+               void *Thread::startFunction(void *parameters)
+               {
+                       Entry entry = *(Entry*)parameters;
+                       entry.init->signal();
+                       entry.threadFunction(entry.threadParameters);
+                       return nullptr;
+               }
+       #endif
+
+       Event::Event()
+       {
+               #if defined(_WIN32)
+                       handle = CreateEvent(NULL, FALSE, FALSE, NULL);
+               #else
+                       pthread_cond_init(&handle, NULL);
+                       pthread_mutex_init(&mutex, NULL);
+                       signaled = false;
+               #endif
+       }
+
+       Event::~Event()
+       {
+               #if defined(_WIN32)
+                       CloseHandle(handle);
+               #else
+                       pthread_cond_destroy(&handle);
+                       pthread_mutex_destroy(&mutex);
+               #endif
+       }
+}
diff --git a/src/Reactor/Thread.hpp b/src/Reactor/Thread.hpp
new file mode 100644 (file)
index 0000000..7f8be13
--- /dev/null
@@ -0,0 +1,338 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef rr_Thread_hpp
+#define rr_Thread_hpp
+
+#if defined(_WIN32)
+       #ifndef WIN32_LEAN_AND_MEAN
+               #define WIN32_LEAN_AND_MEAN
+       #endif
+       #include <windows.h>
+       #include <intrin.h>
+#else
+       #include <pthread.h>
+       #include <sched.h>
+       #include <unistd.h>
+       #define TLS_OUT_OF_INDEXES (pthread_key_t)(~0)
+#endif
+
+#include <stdlib.h>
+
+#if defined(__clang__)
+#if __has_include(<atomic>) // clang has an explicit check for the availability of atomic
+#define USE_STD_ATOMIC 1
+#endif
+// atomic is available in C++11 or newer, and in Visual Studio 2012 or newer
+#elif (defined(_MSC_VER) && (_MSC_VER >= 1700)) || (__cplusplus >= 201103L)
+#define USE_STD_ATOMIC 1
+#endif
+
+#if USE_STD_ATOMIC
+#include <atomic>
+#endif
+
+namespace rr
+{
+       class Event;
+
+       class Thread
+       {
+       public:
+               Thread(void (*threadFunction)(void *parameters), void *parameters);
+
+               ~Thread();
+
+               void join();
+
+               static void yield();
+               static void sleep(int milliseconds);
+
+               #if defined(_WIN32)
+                       typedef DWORD LocalStorageKey;
+               #else
+                       typedef pthread_key_t LocalStorageKey;
+               #endif
+
+               static LocalStorageKey allocateLocalStorageKey(void (*destructor)(void *storage) = free);
+               static void freeLocalStorageKey(LocalStorageKey key);
+               static void *allocateLocalStorage(LocalStorageKey key, size_t size);
+               static void *getLocalStorage(LocalStorageKey key);
+               static void freeLocalStorage(LocalStorageKey key);
+
+       private:
+               struct Entry
+               {
+                       void (*const threadFunction)(void *parameters);
+                       void *threadParameters;
+                       Event *init;
+               };
+
+               #if defined(_WIN32)
+                       static unsigned long __stdcall startFunction(void *parameters);
+                       HANDLE handle;
+               #else
+                       static void *startFunction(void *parameters);
+                       pthread_t handle;
+               #endif
+
+               bool hasJoined = false;
+       };
+
+       class Event
+       {
+               friend class Thread;
+
+       public:
+               Event();
+
+               ~Event();
+
+               void signal();
+               void wait();
+
+       private:
+               #if defined(_WIN32)
+                       HANDLE handle;
+               #else
+                       pthread_cond_t handle;
+                       pthread_mutex_t mutex;
+                       volatile bool signaled;
+               #endif
+       };
+
+       #if PERF_PROFILE
+       int64_t atomicExchange(int64_t volatile *target, int64_t value);
+       #endif
+
+       int atomicExchange(int volatile *target, int value);
+       int atomicIncrement(int volatile *value);
+       int atomicDecrement(int volatile *value);
+       int atomicAdd(int volatile *target, int value);
+       void nop();
+}
+
+namespace rr
+{
+       inline void Thread::yield()
+       {
+               #if defined(_WIN32)
+                       Sleep(0);
+               #elif defined(__APPLE__)
+                       pthread_yield_np();
+               #else
+                       sched_yield();
+               #endif
+       }
+
+       inline void Thread::sleep(int milliseconds)
+       {
+               #if defined(_WIN32)
+                       Sleep(milliseconds);
+               #else
+                       usleep(1000 * milliseconds);
+               #endif
+       }
+
+       inline Thread::LocalStorageKey Thread::allocateLocalStorageKey(void (*destructor)(void *storage))
+       {
+               #if defined(_WIN32)
+                       return TlsAlloc();
+               #else
+                       LocalStorageKey key;
+                       pthread_key_create(&key, destructor);
+                       return key;
+               #endif
+       }
+
+       inline void Thread::freeLocalStorageKey(LocalStorageKey key)
+       {
+               #if defined(_WIN32)
+                       TlsFree(key);
+               #else
+                       pthread_key_delete(key);   // Using an invalid key is an error but not undefined behavior.
+               #endif
+       }
+
+       inline void *Thread::allocateLocalStorage(LocalStorageKey key, size_t size)
+       {
+               if(key == TLS_OUT_OF_INDEXES)
+               {
+                       return nullptr;
+               }
+
+               freeLocalStorage(key);
+
+               void *storage = malloc(size);
+
+               #if defined(_WIN32)
+                       TlsSetValue(key, storage);
+               #else
+                       pthread_setspecific(key, storage);
+               #endif
+
+               return storage;
+       }
+
+       inline void *Thread::getLocalStorage(LocalStorageKey key)
+       {
+               #if defined(_WIN32)
+                       return TlsGetValue(key);
+               #else
+                       if(key == TLS_OUT_OF_INDEXES)   // Avoid undefined behavior.
+                       {
+                               return nullptr;
+                       }
+
+                       return pthread_getspecific(key);
+               #endif
+       }
+
+       inline void Thread::freeLocalStorage(LocalStorageKey key)
+       {
+               free(getLocalStorage(key));
+
+               #if defined(_WIN32)
+                       TlsSetValue(key, nullptr);
+               #else
+                       pthread_setspecific(key, nullptr);
+               #endif
+       }
+
+       inline void Event::signal()
+       {
+               #if defined(_WIN32)
+                       SetEvent(handle);
+               #else
+                       pthread_mutex_lock(&mutex);
+                       signaled = true;
+                       pthread_cond_signal(&handle);
+                       pthread_mutex_unlock(&mutex);
+               #endif
+       }
+
+       inline void Event::wait()
+       {
+               #if defined(_WIN32)
+                       WaitForSingleObject(handle, INFINITE);
+               #else
+                       pthread_mutex_lock(&mutex);
+                       while(!signaled) pthread_cond_wait(&handle, &mutex);
+                       signaled = false;
+                       pthread_mutex_unlock(&mutex);
+               #endif
+       }
+
+       #if PERF_PROFILE
+       inline int64_t atomicExchange(volatile int64_t *target, int64_t value)
+       {
+               #if defined(_WIN32)
+                       return InterlockedExchange64(target, value);
+               #else
+                       int ret;
+                       __asm__ __volatile__("lock; xchg8 %0,(%1)" : "=r" (ret) :"r" (target), "0" (value) : "memory" );
+                       return ret;
+               #endif
+       }
+       #endif
+
+       inline int atomicExchange(volatile int *target, int value)
+       {
+               #if defined(_WIN32)
+                       return InterlockedExchange((volatile long*)target, (long)value);
+               #else
+                       int ret;
+                       __asm__ __volatile__("lock; xchgl %0,(%1)" : "=r" (ret) :"r" (target), "0" (value) : "memory" );
+                       return ret;
+               #endif
+       }
+
+       inline int atomicIncrement(volatile int *value)
+       {
+               #if defined(_WIN32)
+                       return InterlockedIncrement((volatile long*)value);
+               #else
+                       return __sync_add_and_fetch(value, 1);
+               #endif
+       }
+
+       inline int atomicDecrement(volatile int *value)
+       {
+               #if defined(_WIN32)
+                       return InterlockedDecrement((volatile long*)value);
+               #else
+                       return __sync_sub_and_fetch(value, 1);
+               #endif
+       }
+
+       inline int atomicAdd(volatile int* target, int value)
+       {
+               #if defined(_WIN32)
+                       return InterlockedExchangeAdd((volatile long*)target, value) + value;
+               #else
+                       return __sync_add_and_fetch(target, value);
+               #endif
+       }
+
+       inline void nop()
+       {
+               #if defined(_WIN32)
+                       __nop();
+               #else
+                       __asm__ __volatile__ ("nop");
+               #endif
+       }
+
+       #if USE_STD_ATOMIC
+               class AtomicInt
+               {
+               public:
+                       AtomicInt() : ai() {}
+                       AtomicInt(int i) : ai(i) {}
+
+                       inline operator int() const { return ai.load(std::memory_order_acquire); }
+                       inline void operator=(const AtomicInt& i) { ai.store(i.ai.load(std::memory_order_acquire), std::memory_order_release); }
+                       inline void operator=(int i) { ai.store(i, std::memory_order_release); }
+                       inline void operator--() { ai.fetch_sub(1, std::memory_order_acq_rel); }
+                       inline void operator++() { ai.fetch_add(1, std::memory_order_acq_rel); }
+                       inline int operator--(int) { return ai.fetch_sub(1, std::memory_order_acq_rel) - 1; }
+                       inline int operator++(int) { return ai.fetch_add(1, std::memory_order_acq_rel) + 1; }
+                       inline void operator-=(int i) { ai.fetch_sub(i, std::memory_order_acq_rel); }
+                       inline void operator+=(int i) { ai.fetch_add(i, std::memory_order_acq_rel); }
+               private:
+                       std::atomic<int> ai;
+               };
+       #else
+               class AtomicInt
+               {
+               public:
+                       AtomicInt() {}
+                       AtomicInt(int i) : vi(i) {}
+
+                       inline operator int() const { return vi; } // Note: this isn't a guaranteed atomic operation
+                       inline void operator=(const AtomicInt& i) { atomicExchange(&vi, i.vi); }
+                       inline void operator=(int i) { atomicExchange(&vi, i); }
+                       inline void operator--() { atomicDecrement(&vi); }
+                       inline void operator++() { atomicIncrement(&vi); }
+                       inline int operator--(int) { return atomicDecrement(&vi); }
+                       inline int operator++(int) { return atomicIncrement(&vi); }
+                       inline void operator-=(int i) { atomicAdd(&vi, -i); }
+                       inline void operator+=(int i) { atomicAdd(&vi, i); }
+               private:
+                       volatile int vi;
+               };
+       #endif
+}
+
+#endif   // rr_Thread_hpp
diff --git a/src/Reactor/Types.hpp b/src/Reactor/Types.hpp
new file mode 100644 (file)
index 0000000..428da51
--- /dev/null
@@ -0,0 +1,157 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef r3_Types_hpp
+#define r3_Types_hpp
+
+#include <limits>
+#include <type_traits>
+
+// GCC warns against bitfields not fitting the entire range of an enum with a fixed underlying type of unsigned int, which gets promoted to an error with -Werror and cannot be suppressed.
+// However, GCC already defaults to using unsigned int as the underlying type of an unscoped enum without a fixed underlying type. So we can just omit it.
+#if defined(__GNUC__) && !defined(__clang__)
+namespace {enum E {}; static_assert(!std::numeric_limits<std::underlying_type<E>::type>::is_signed, "expected unscoped enum whose underlying type is not fixed to be unsigned");}
+#define ENUM_UNDERLYING_TYPE_UNSIGNED_INT
+#else
+#define ENUM_UNDERLYING_TYPE_UNSIGNED_INT : unsigned int
+#endif
+
+#if defined(_MSC_VER)
+       typedef signed __int8 int8_t;
+       typedef signed __int16 int16_t;
+       typedef signed __int32 int32_t;
+       typedef signed __int64 int64_t;
+       typedef unsigned __int8 uint8_t;
+       typedef unsigned __int16 uint16_t;
+       typedef unsigned __int32 uint32_t;
+       typedef unsigned __int64 uint64_t;
+       #define ALIGN(bytes, type) __declspec(align(bytes)) type
+#else
+       #include <stdint.h>
+       #define ALIGN(bytes, type) type __attribute__((aligned(bytes)))
+#endif
+
+namespace rr
+{
+       typedef ALIGN(1, uint8_t) byte;
+       typedef ALIGN(2, uint16_t) word;
+       typedef ALIGN(4, uint32_t) dword;
+       typedef ALIGN(8, uint64_t) qword;
+       typedef ALIGN(16, uint64_t) qword2[2];
+       typedef ALIGN(4, uint8_t) byte4[4];
+       typedef ALIGN(8, uint8_t) byte8[8];
+       typedef ALIGN(16, uint8_t) byte16[16];
+       typedef ALIGN(8, uint16_t) word4[4];
+       typedef ALIGN(8, uint32_t) dword2[2];
+       typedef ALIGN(16, uint32_t) dword4[4];
+       typedef ALIGN(16, uint64_t) xword[2];
+
+       typedef ALIGN(1, int8_t) sbyte;
+       typedef ALIGN(4, int8_t) sbyte4[4];
+       typedef ALIGN(8, int8_t) sbyte8[8];
+       typedef ALIGN(16, int8_t) sbyte16[16];
+       typedef ALIGN(8, short) short4[4];
+       typedef ALIGN(8, unsigned short) ushort4[4];
+       typedef ALIGN(16, short) short8[8];
+       typedef ALIGN(16, unsigned short) ushort8[8];
+       typedef ALIGN(8, int) int2[2];
+       typedef ALIGN(8, unsigned int) uint2[2];
+       typedef ALIGN(16, unsigned int) uint4[4];
+
+       typedef ALIGN(8, float) float2[2];
+
+       ALIGN(16, struct int4
+       {
+               int x;
+               int y;
+               int z;
+               int w;
+
+               int &operator[](int i)
+               {
+                       return (&x)[i];
+               }
+
+               const int &operator[](int i) const
+               {
+                       return (&x)[i];
+               }
+
+               bool operator!=(const int4 &rhs)
+               {
+                       return x != rhs.x || y != rhs.y || z != rhs.z || w != rhs.w;
+               }
+
+               bool operator==(const int4 &rhs)
+               {
+                       return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w;
+               }
+       });
+
+       ALIGN(16, struct float4
+       {
+               float x;
+               float y;
+               float z;
+               float w;
+
+               float &operator[](int i)
+               {
+                       return (&x)[i];
+               }
+
+               const float &operator[](int i) const
+               {
+                       return (&x)[i];
+               }
+
+               bool operator!=(const float4 &rhs)
+               {
+                       return x != rhs.x || y != rhs.y || z != rhs.z || w != rhs.w;
+               }
+
+               bool operator==(const float4 &rhs)
+               {
+                       return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w;
+               }
+       });
+
+       inline float4 vector(float x, float y, float z, float w)
+       {
+               float4 v;
+
+               v.x = x;
+               v.y = y;
+               v.z = z;
+               v.w = w;
+
+               return v;
+       }
+
+       inline float4 replicate(float f)
+       {
+               float4 v;
+
+               v.x = f;
+               v.y = f;
+               v.z = f;
+               v.w = f;
+
+               return v;
+       }
+
+       #define OFFSET(s,m) (int)(size_t)&reinterpret_cast<const volatile char&>((((s*)0)->m))
+}
+
+#endif   // r3_Types_hpp
similarity index 97%
rename from tests/unittests/unittests.vcxproj
rename to tests/unittests/GLESUnitTests.vcxproj
index 424d30a..7769b92 100644 (file)
@@ -21,7 +21,7 @@
   <PropertyGroup Label="Globals">\r
     <ProjectGuid>{CF8EBC89-8762-49DC-9440-6C82B3499913}</ProjectGuid>\r
     <Keyword>Win32Proj</Keyword>\r
-    <RootNamespace>unittests</RootNamespace>\r
+    <RootNamespace>GLESUnitTests</RootNamespace>\r
     <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>\r
   </PropertyGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r