git subrepo pull --force deps/lightrec
authorPaul Cercueil <paul@crapouillou.net>
Fri, 15 Aug 2025 07:50:45 +0000 (09:50 +0200)
committernotaz <notasas@gmail.com>
Fri, 15 Aug 2025 18:07:14 +0000 (21:07 +0300)
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
deps/lightrec/disassembler.c
deps/lightrec/disassembler.h
deps/lightrec/emitter.c
deps/lightrec/lightrec.c
deps/lightrec/optimizer.c
deps/lightrec/recompiler.c

index e7d7695..654cb04 100644 (file)
@@ -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
index f0aef60..206e8fe 100644 (file)
@@ -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);
        }
 }
index a19588a..af0bfe7 100644 (file)
@@ -111,6 +111,8 @@ enum standard_opcodes {
        OP_LWC2                 = 0x32,
        OP_SWC2                 = 0x3a,
 
+       OP_META_BIOS            = 0x3b,
+
        OP_META                 = 0x3c,
 
        OP_META_MULT2           = 0x19,
index f84f049..1da3b70 100644 (file)
@@ -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. */
index 488ceb2..0adb984 100644 (file)
@@ -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;
        }
index 035e52b..139cd4d 100644 (file)
@@ -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)
index 1ccef7a..5691170 100644 (file)
@@ -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;
                }