Skip to content

Commit

Permalink
git subrepo pull deps/lightrec
Browse files Browse the repository at this point in the history
subrepo:
  subdir:   "deps/lightrec"
  merged:   "d640c6b4"
upstream:
  origin:   "https://github.com/pcercuei/lightrec.git"
  branch:   "master"
  commit:   "d640c6b4"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "2f68596"
  • Loading branch information
ZachCook committed Nov 17, 2022
1 parent ffa8400 commit c41b8a7
Show file tree
Hide file tree
Showing 28 changed files with 5,794 additions and 1,421 deletions.
4 changes: 2 additions & 2 deletions deps/lightrec/.gitrepo
Expand Up @@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/pcercuei/lightrec.git
branch = master
commit = 0df4ec86ba664dad3b4cc24fd3199131e8e3219f
parent = 364a705dc70b57a734b4e362226a386b34a008fb
commit = d640c6b484ac4936db16d865e4dc8850c1b5e122
parent = ffa840032d55d2fd54f8546f332f91e6b8bbe495
method = merge
cmdver = 0.4.3
20 changes: 9 additions & 11 deletions deps/lightrec/CMakeLists.txt
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.0)
project(lightrec LANGUAGES C VERSION 0.4)
project(lightrec LANGUAGES C VERSION 0.6)

set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries")
if (NOT BUILD_SHARED_LIBS)
Expand Down Expand Up @@ -68,6 +68,7 @@ option(OPT_TRANSFORM_OPS "(optimization) Transform opcodes" ON)
option(OPT_LOCAL_BRANCHES "(optimization) Detect local branches" ON)
option(OPT_SWITCH_DELAY_SLOTS "(optimization) Switch delay slots" ON)
option(OPT_FLAG_STORES "(optimization) Flag stores that don't require invalidation" ON)
option(OPT_FLAG_IO "(optimization) Flag I/O opcodes whose target is known" ON)
option(OPT_FLAG_MULT_DIV "(optimization) Flag MULT/DIV that only use one of HI/LO" ON)
option(OPT_EARLY_UNLOAD "(optimization) Unload registers early" ON)

Expand All @@ -90,15 +91,6 @@ if (CMAKE_C_COMPILER_ID STREQUAL "Clang")
target_compile_options(${PROJECT_NAME} PRIVATE -Wno-initializer-overrides)
endif()

option(ENABLE_TINYMM "Enable optional libtinymm dependency" OFF)
if (ENABLE_TINYMM)
find_library(TINYMM_LIBRARIES tinymm REQUIRED)
find_path(TINYMM_INCLUDE_DIR tinymm.h REQUIRED)

include_directories(${TINYMM_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} PRIVATE ${TINYMM_LIBRARIES})
endif (ENABLE_TINYMM)

if (ENABLE_THREADED_COMPILER)
find_library(PTHREAD_LIBRARIES pthread REQUIRED)
find_path(PTHREAD_INCLUDE_DIR pthread.h REQUIRED)
Expand All @@ -107,6 +99,12 @@ if (ENABLE_THREADED_COMPILER)
target_link_libraries(${PROJECT_NAME} PRIVATE ${PTHREAD_LIBRARIES})
endif (ENABLE_THREADED_COMPILER)

option(ENABLE_CODE_BUFFER "Enable external code buffer" OFF)
if (ENABLE_CODE_BUFFER)
target_sources(${PROJECT_NAME} PRIVATE tlsf/tlsf.c)
target_include_directories(${PROJECT_NAME} PRIVATE tlsf)
endif (ENABLE_CODE_BUFFER)

find_library(LIBLIGHTNING lightning REQUIRED)
find_path(LIBLIGHTNING_INCLUDE_DIR lightning.h REQUIRED)

Expand All @@ -118,7 +116,7 @@ if (LOG_LEVEL STREQUAL Debug)
target_sources(${PROJECT_NAME} PRIVATE disassembler.c)
endif()

configure_file(config.h.cmakein config.h @ONLY)
configure_file(lightrec-config.h.cmakein lightrec-config.h @ONLY)

include(GNUInstallDirs)
install(TARGETS ${PROJECT_NAME}
Expand Down
4 changes: 3 additions & 1 deletion deps/lightrec/README.md
Expand Up @@ -50,4 +50,6 @@ Lightrec has been ported to the following emulators:

* [__pcsx4all__ (my own fork)](https://github.com/pcercuei/pcsx4all)

* [__Beetle__ (libretro)](https://github.com/libretro/beetle-psx-libretro/)
* [__Beetle__ (libretro)](https://github.com/libretro/beetle-psx-libretro/)

[![Star History Chart](https://api.star-history.com/svg?repos=pcercuei/lightrec&type=Date)](https://star-history.com/#pcercuei/lightrec&Date)
99 changes: 89 additions & 10 deletions deps/lightrec/blockcache.c
Expand Up @@ -7,6 +7,8 @@
#include "debug.h"
#include "lightrec-private.h"
#include "memmanager.h"
#include "reaper.h"
#include "recompiler.h"

#include <stdbool.h>
#include <stdlib.h>
Expand Down Expand Up @@ -63,8 +65,8 @@ void remove_from_code_lut(struct blockcache *cache, struct block *block)
u32 offset = lut_offset(block->pc);

if (block->function) {
memset(&state->code_lut[offset], 0,
block->nb_ops * sizeof(*state->code_lut));
memset(lut_address(state, offset), 0,
block->nb_ops * lut_elm_size(state));
}
}

Expand Down Expand Up @@ -102,18 +104,64 @@ void lightrec_unregister_block(struct blockcache *cache, struct block *block)
pr_err("Block at PC 0x%x is not in cache\n", block->pc);
}

void lightrec_free_block_cache(struct blockcache *cache)
static bool lightrec_block_is_old(const struct lightrec_state *state,
const struct block *block)
{
u32 diff = state->current_cycle - block->precompile_date;

return diff > (1 << 27); /* About 4 seconds */
}

static void lightrec_free_blocks(struct blockcache *cache,
const struct block *except, bool all)
{
struct lightrec_state *state = cache->state;
struct block *block, *next;
bool outdated = all;
unsigned int i;
u8 old_flags;

for (i = 0; i < LUT_SIZE; i++) {
for (block = cache->lut[i]; block; block = next) {
next = block->next;
lightrec_free_block(cache->state, block);

if (except && block == except)
continue;

if (!all) {
outdated = lightrec_block_is_old(state, block) ||
lightrec_block_is_outdated(state, block);
}

if (!outdated)
continue;

old_flags = block_set_flags(block, BLOCK_IS_DEAD);

if (!(old_flags & BLOCK_IS_DEAD)) {
if (ENABLE_THREADED_COMPILER)
lightrec_recompiler_remove(state->rec, block);

pr_debug("Freeing outdated block at PC 0x%08x\n", block->pc);
remove_from_code_lut(cache, block);
lightrec_unregister_block(cache, block);
lightrec_free_block(state, block);
}
}
}
}

void lightrec_remove_outdated_blocks(struct blockcache *cache,
const struct block *except)
{
pr_info("Running out of code space. Cleaning block cache...\n");

lightrec_free_blocks(cache, except, false);
}

void lightrec_free_block_cache(struct blockcache *cache)
{
lightrec_free_blocks(cache, NULL, true);
lightrec_free(cache->state, MEM_FOR_LIGHTREC, sizeof(*cache), cache);
}

Expand Down Expand Up @@ -150,22 +198,53 @@ u32 lightrec_calculate_block_hash(const struct block *block)
return hash;
}

static void lightrec_reset_lut_offset(struct lightrec_state *state, void *d)
{
u32 pc = (u32)(uintptr_t) d;
struct block *block;
void *addr;

block = lightrec_find_block(state->block_cache, pc);
if (!block)
return;

if (block_has_flag(block, BLOCK_IS_DEAD))
return;

addr = block->function ?: state->get_next_block;
lut_write(state, lut_offset(pc), addr);
}

bool lightrec_block_is_outdated(struct lightrec_state *state, struct block *block)
{
void **lut_entry = &state->code_lut[lut_offset(block->pc)];
u32 offset = lut_offset(block->pc);
bool outdated;

if (*lut_entry)
if (lut_read(state, offset))
return false;

outdated = block->hash != lightrec_calculate_block_hash(block);
if (likely(!outdated)) {
/* The block was marked as outdated, but the content is still
* the same */
if (block->function)
*lut_entry = block->function;
else
*lut_entry = state->get_next_block;

if (ENABLE_THREADED_COMPILER) {
/*
* When compiling a block that covers ours, the threaded
* compiler will set the LUT entries of the various
* entry points. Therefore we cannot write the LUT here,
* as we would risk overwriting the new entry points.
* Leave it to the reaper to re-install the LUT entries.
*/

lightrec_reaper_add(state->reaper,
lightrec_reset_lut_offset,
(void *)(uintptr_t) block->pc);
} else if (block->function) {
lut_write(state, offset, block->function);
} else {
lut_write(state, offset, state->get_next_block);
}
}

return outdated;
Expand Down
3 changes: 3 additions & 0 deletions deps/lightrec/blockcache.h
Expand Up @@ -24,4 +24,7 @@ void lightrec_free_block_cache(struct blockcache *cache);
u32 lightrec_calculate_block_hash(const struct block *block);
_Bool lightrec_block_is_outdated(struct lightrec_state *state, struct block *block);

void lightrec_remove_outdated_blocks(struct blockcache *cache,
const struct block *except);

#endif /* __BLOCKCACHE_H__ */

0 comments on commit c41b8a7

Please sign in to comment.