From f97ab52420102890428af9814af97ff7de9b72c3 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Fri, 15 Aug 2025 09:50:45 +0200 Subject: [PATCH] git subrepo pull --force deps/lightrec subrepo: subdir: "deps/lightrec" merged: "3ebca4b2940" upstream: origin: "https://github.com/pcercuei/lightrec.git" branch: "master" commit: "3ebca4b2940" git-subrepo: version: "0.4.6" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "110b9eb" --- deps/lightrec/.gitrepo | 4 ++-- deps/lightrec/disassembler.c | 12 ++++++++++-- deps/lightrec/disassembler.h | 2 ++ deps/lightrec/emitter.c | 9 +++++---- deps/lightrec/lightrec.c | 3 +++ deps/lightrec/optimizer.c | 1 + deps/lightrec/recompiler.c | 14 +++++++++++++- 7 files changed, 36 insertions(+), 9 deletions(-) diff --git a/deps/lightrec/.gitrepo b/deps/lightrec/.gitrepo index e7d76955..654cb042 100644 --- a/deps/lightrec/.gitrepo +++ b/deps/lightrec/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/pcercuei/lightrec.git branch = master - commit = 8293acf768e57060bb3ee66eeb0942d3d06b964e - parent = b7027dbf9b020077be29014680d96b19c97f7d20 + commit = 3ebca4b2940c0f5ed73068cd690cca15e50ca73a + parent = 6365a756c02d25c76bf90c78e42316b46f876c49 method = merge cmdver = 0.4.6 diff --git a/deps/lightrec/disassembler.c b/deps/lightrec/disassembler.c index f0aef604..206e8fe3 100644 --- a/deps/lightrec/disassembler.c +++ b/deps/lightrec/disassembler.c @@ -40,6 +40,7 @@ static const char * const std_opcodes[] = { [OP_SWR] = "swr ", [OP_LWC2] = "lwc2 ", [OP_SWC2] = "swc2 ", + [OP_META_BIOS] = "bios ", [OP_META_MULT2] = "mult2 ", [OP_META_MULTU2] = "multu2 ", [OP_META_LWU] = "lwu ", @@ -467,6 +468,10 @@ static int print_op(union code c, u32 pc, char *buf, size_t len, lightrec_reg_name(c.i.rt), (s16)c.i.imm, lightrec_reg_name(c.i.rs)); + case OP_META_BIOS: + return snprintf(buf, len, "%s0x%x", + std_opcodes[c.i.op], + c.opcode & 0x03ffffff); case OP_META: return snprintf(buf, len, "%s%s,%s", meta_opcodes[c.m.op], @@ -492,7 +497,7 @@ void lightrec_print_disassembly(const struct block *block, const u32 *code_ptr) const char * const *flags_ptr; size_t nb_flags, count, count2; char buf[256], buf2[256], buf3[256]; - unsigned int i; + unsigned int i, nb_spaces1, nb_spaces2; u32 pc, branch_pc, code; bool is_io; @@ -518,7 +523,10 @@ void lightrec_print_disassembly(const struct block *block, const u32 *code_ptr) print_flags(buf3, sizeof(buf3), op, flags_ptr, nb_flags, is_io); + nb_spaces1 = (*buf2 || *buf3) ? 30 - (int)count : 0; + nb_spaces2 = *buf3 ? 30 - (int)count2 : 0; + printf(X32_FMT" (0x%x)\t%s%*c%s%*c%s\n", pc, i << 2, - buf, 30 - (int)count, ' ', buf2, 30 - (int)count2, ' ', buf3); + buf, nb_spaces1, ' ', buf2, nb_spaces2, ' ', buf3); } } diff --git a/deps/lightrec/disassembler.h b/deps/lightrec/disassembler.h index a19588a1..af0bfe72 100644 --- a/deps/lightrec/disassembler.h +++ b/deps/lightrec/disassembler.h @@ -111,6 +111,8 @@ enum standard_opcodes { OP_LWC2 = 0x32, OP_SWC2 = 0x3a, + OP_META_BIOS = 0x3b, + OP_META = 0x3c, OP_META_MULT2 = 0x19, diff --git a/deps/lightrec/emitter.c b/deps/lightrec/emitter.c index f84f049f..1da3b70e 100644 --- a/deps/lightrec/emitter.c +++ b/deps/lightrec/emitter.c @@ -1215,19 +1215,20 @@ static void rec_io(struct lightrec_cstate *state, union code c = block->opcode_list[offset].c; u32 flags = block->opcode_list[offset].flags; bool is_tagged = LIGHTREC_FLAGS_GET_IO_MODE(flags); + bool load_delay = op_flag_load_delay(flags) && !state->no_load_delay; + u8 zero, reg = load_delay ? REG_TEMP : c.i.rt; u32 lut_entry; - u8 zero; jit_note(__FILE__, __LINE__); lightrec_clean_reg_if_loaded(reg_cache, _jit, c.i.rs, false); if (read_rt && likely(c.i.rt)) - lightrec_clean_reg_if_loaded(reg_cache, _jit, c.i.rt, true); + lightrec_clean_reg_if_loaded(reg_cache, _jit, reg, true); else if (load_rt) - lightrec_clean_reg_if_loaded(reg_cache, _jit, c.i.rt, false); + lightrec_clean_reg_if_loaded(reg_cache, _jit, reg, false); - if (op_flag_load_delay(flags) && !state->no_load_delay) { + if (load_delay) { /* Clear state->in_delay_slot_n. This notifies the lightrec_rw * wrapper that it should write the REG_TEMP register instead of * the actual output register of the opcode. */ diff --git a/deps/lightrec/lightrec.c b/deps/lightrec/lightrec.c index 488ceb28..0adb984c 100644 --- a/deps/lightrec/lightrec.c +++ b/deps/lightrec/lightrec.c @@ -1362,6 +1362,9 @@ static unsigned int lightrec_get_mips_block_len(const u32 *src) if (is_syscall(c)) return i; + if (c.i.op == OP_META_BIOS) + return i; + if (is_unconditional_jump(c)) return i + 1; } diff --git a/deps/lightrec/optimizer.c b/deps/lightrec/optimizer.c index 035e52bc..139cd4df 100644 --- a/deps/lightrec/optimizer.c +++ b/deps/lightrec/optimizer.c @@ -101,6 +101,7 @@ static u64 opcode_read_mask(union code op) case OP_J: case OP_JAL: case OP_LUI: + case OP_META_BIOS: return 0; case OP_BEQ: if (op.i.rs == op.i.rt) diff --git a/deps/lightrec/recompiler.c b/deps/lightrec/recompiler.c index 1ccef7a0..56911703 100644 --- a/deps/lightrec/recompiler.c +++ b/deps/lightrec/recompiler.c @@ -43,7 +43,7 @@ struct recompiler { pthread_mutex_t alloc_mutex; - unsigned int nb_recs; + unsigned int nb_recs, nb_cpus; struct recompiler_thd thds[]; }; @@ -232,6 +232,7 @@ struct recompiler *lightrec_recompiler_init(struct lightrec_state *state) rec->pause = false; rec->must_flush = false; rec->nb_recs = nb_recs; + rec->nb_cpus = nb_cpus; slist_init(&rec->slist); ret = pthread_cond_init(&rec->cond, NULL); @@ -341,6 +342,17 @@ int lightrec_recompiler_add(struct recompiler *rec, struct block *block) /* The block to compile is already in the queue - * increment its counter to increase its priority */ block_rec->requests++; + + if (rec->nb_cpus == 1) { + /* On single-core CPUs, if we got a request for + * a block that's already in the queue, we'll + * probably get many more before the compiler + * thread can run, which means that the block + * will be interpreted until then, wasting a lot + * of performance. In that case, it is better to + * just let the compiler thread run now. */ + pthread_cond_wait(&rec->cond2, &rec->mutex); + } goto out_unlock; } -- 2.47.2