diff --git a/src/core/core.cpp b/src/core/core.cpp
index 82db5cccff..9bd9f4bd95 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -26,11 +26,13 @@ namespace Core {
 
 /*static*/ System System::s_instance;
 
+System::System() = default;
+
 System::~System() = default;
 
 /// Runs a CPU core while the system is powered on
 static void RunCpuCore(std::shared_ptr<Cpu> cpu_state) {
-    while (Core::System().GetInstance().IsPoweredOn()) {
+    while (Core::System::GetInstance().IsPoweredOn()) {
         cpu_state->RunLoop(true);
     }
 }
diff --git a/src/core/core.h b/src/core/core.h
index f90f085ad1..c6f69f001d 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -168,6 +168,8 @@ public:
     }
 
 private:
+    System();
+
     /// Returns the currently running CPU core
     Cpu& CurrentCpuCore();
 
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 9a9746585b..0b3c66428f 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -165,7 +165,7 @@ void Thread::CancelWakeupTimer() {
 static boost::optional<s32> GetNextProcessorId(u64 mask) {
     for (s32 index = 0; index < Core::NUM_CPU_CORES; ++index) {
         if (mask & (1ULL << index)) {
-            if (!Core::System().GetInstance().Scheduler(index)->GetCurrentThread()) {
+            if (!Core::System::GetInstance().Scheduler(index)->GetCurrentThread()) {
                 // Core is enabled and not running any threads, use this one
                 return index;
             }
@@ -215,14 +215,14 @@ void Thread::ResumeFromWait() {
         new_processor_id = processor_id;
     }
     if (ideal_core != -1 &&
-        Core::System().GetInstance().Scheduler(ideal_core)->GetCurrentThread() == nullptr) {
+        Core::System::GetInstance().Scheduler(ideal_core)->GetCurrentThread() == nullptr) {
         new_processor_id = ideal_core;
     }
 
     ASSERT(*new_processor_id < 4);
 
     // Add thread to new core's scheduler
-    auto& next_scheduler = Core::System().GetInstance().Scheduler(*new_processor_id);
+    auto& next_scheduler = Core::System::GetInstance().Scheduler(*new_processor_id);
 
     if (*new_processor_id != processor_id) {
         // Remove thread from previous core's scheduler
@@ -325,7 +325,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
     thread->name = std::move(name);
     thread->callback_handle = wakeup_callback_handle_table.Create(thread).Unwrap();
     thread->owner_process = owner_process;
-    thread->scheduler = Core::System().GetInstance().Scheduler(processor_id);
+    thread->scheduler = Core::System::GetInstance().Scheduler(processor_id);
     thread->scheduler->AddThread(thread, priority);
 
     // Find the next available TLS index, and mark it as used
@@ -481,14 +481,14 @@ void Thread::ChangeCore(u32 core, u64 mask) {
         new_processor_id = processor_id;
     }
     if (ideal_core != -1 &&
-        Core::System().GetInstance().Scheduler(ideal_core)->GetCurrentThread() == nullptr) {
+        Core::System::GetInstance().Scheduler(ideal_core)->GetCurrentThread() == nullptr) {
         new_processor_id = ideal_core;
     }
 
     ASSERT(*new_processor_id < 4);
 
     // Add thread to new core's scheduler
-    auto& next_scheduler = Core::System().GetInstance().Scheduler(*new_processor_id);
+    auto& next_scheduler = Core::System::GetInstance().Scheduler(*new_processor_id);
 
     if (*new_processor_id != processor_id) {
         // Remove thread from previous core's scheduler
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index eecbc5ff04..7e620584f7 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -128,8 +128,8 @@ RasterizerOpenGL::~RasterizerOpenGL() {
 std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,
                                                              GLintptr buffer_offset) {
     MICROPROFILE_SCOPE(OpenGL_VAO);
-    const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
-    const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager;
+    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
+    const auto& memory_manager = Core::System::GetInstance().GPU().memory_manager;
 
     state.draw.vertex_array = hw_vao.handle;
     state.draw.vertex_buffer = stream_buffer->GetHandle();
@@ -184,7 +184,7 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,
 }
 
 static GLShader::ProgramCode GetShaderProgramCode(Maxwell::ShaderProgram program) {
-    auto& gpu = Core::System().GetInstance().GPU().Maxwell3D();
+    auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
 
     // Fetch program code from memory
     GLShader::ProgramCode program_code;
@@ -207,7 +207,7 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) {
         }
     };
 
-    auto& gpu = Core::System().GetInstance().GPU().Maxwell3D();
+    auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
 
     // Next available bindpoints to use when uploading the const buffers and textures to the GLSL
     // shaders. The constbuffer bindpoint starts after the shader stage configuration bind points.
@@ -297,7 +297,7 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) {
 }
 
 size_t RasterizerOpenGL::CalculateVertexArraysSize() const {
-    const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
+    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
 
     size_t size = 0;
     for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) {
@@ -322,7 +322,7 @@ bool RasterizerOpenGL::AccelerateDrawBatch(bool is_indexed) {
 
 std::pair<Surface, Surface> RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb,
                                                                     bool using_depth_fb) {
-    const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
+    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
 
     // TODO(bunnei): Implement this
     const bool has_stencil = false;
@@ -374,7 +374,7 @@ std::pair<Surface, Surface> RasterizerOpenGL::ConfigureFramebuffers(bool using_c
 }
 
 void RasterizerOpenGL::Clear() {
-    const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
+    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
 
     bool use_color_fb = false;
     bool use_depth_fb = false;
@@ -426,7 +426,7 @@ void RasterizerOpenGL::DrawArrays() {
         return;
 
     MICROPROFILE_SCOPE(OpenGL_Drawing);
-    const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
+    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
 
     ScopeAcquireGLContext acquire_context;
 
@@ -473,7 +473,7 @@ void RasterizerOpenGL::DrawArrays() {
     // If indexed mode, copy the index buffer
     GLintptr index_buffer_offset = 0;
     if (is_indexed) {
-        const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager;
+        const auto& memory_manager = Core::System::GetInstance().GPU().memory_manager;
         const boost::optional<VAddr> index_data_addr{
             memory_manager->GpuToCpuAddress(regs.index_array.StartAddress())};
         Memory::ReadBlock(*index_data_addr, offseted_buffer, index_buffer_size);
@@ -775,7 +775,7 @@ void RasterizerOpenGL::BindFramebufferSurfaces(const Surface& color_surface,
 }
 
 void RasterizerOpenGL::SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect) {
-    const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
+    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
     const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()};
 
     state.viewport.x = static_cast<GLint>(surfaces_rect.left) + viewport_rect.left;
@@ -793,7 +793,7 @@ void RasterizerOpenGL::SyncClipCoef() {
 }
 
 void RasterizerOpenGL::SyncCullMode() {
-    const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
+    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
 
     state.cull.enabled = regs.cull.enabled != 0;
 
@@ -825,7 +825,7 @@ void RasterizerOpenGL::SyncDepthOffset() {
 }
 
 void RasterizerOpenGL::SyncDepthTestState() {
-    const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
+    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
 
     state.depth.test_enabled = regs.depth_test_enable != 0;
     state.depth.write_mask = regs.depth_write_enabled ? GL_TRUE : GL_FALSE;
@@ -837,7 +837,7 @@ void RasterizerOpenGL::SyncDepthTestState() {
 }
 
 void RasterizerOpenGL::SyncBlendState() {
-    const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
+    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
 
     // TODO(Subv): Support more than just render target 0.
     state.blend.enabled = regs.blend.enable[0] != 0;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index c171c4c5ba..2c43982b09 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -505,7 +505,7 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu
 
 SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(
     bool using_color_fb, bool using_depth_fb, const MathUtil::Rectangle<s32>& viewport) {
-    const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
+    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
 
     // TODO(bunnei): This is hard corded to use just the first render buffer
     LOG_WARNING(Render_OpenGL, "hard-coded for render target 0!");
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp
index d7167b2989..1aa437f764 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp
@@ -35,7 +35,7 @@ void SetShaderUniformBlockBindings(GLuint shader) {
 } // namespace Impl
 
 void MaxwellUniformData::SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage) {
-    const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
+    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
 
     // TODO(bunnei): Support more than one viewport
     viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f;