[subrepo]
remote = https://github.com/pcercuei/lightrec.git
branch = master
- commit = 8293acf768e57060bb3ee66eeb0942d3d06b964e
- parent = b7027dbf9b020077be29014680d96b19c97f7d20
+ commit = 3ebca4b2940c0f5ed73068cd690cca15e50ca73a
+ parent = 6365a756c02d25c76bf90c78e42316b46f876c49
method = merge
cmdver = 0.4.6
[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 ",
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],
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;
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);
}
}
OP_LWC2 = 0x32,
OP_SWC2 = 0x3a,
+ OP_META_BIOS = 0x3b,
+
OP_META = 0x3c,
OP_META_MULT2 = 0x19,
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. */
if (is_syscall(c))
return i;
+ if (c.i.op == OP_META_BIOS)
+ return i;
+
if (is_unconditional_jump(c))
return i + 1;
}
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)
pthread_mutex_t alloc_mutex;
- unsigned int nb_recs;
+ unsigned int nb_recs, nb_cpus;
struct recompiler_thd thds[];
};
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);
/* 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;
}