diff --git a/deps/lightrec/.gitrepo b/deps/lightrec/.gitrepo index 3e1aed00..6ab25225 100644 --- a/deps/lightrec/.gitrepo +++ b/deps/lightrec/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/pcercuei/lightrec.git branch = master - commit = a6ac0156560afd3ddcbed737e84198a270dc7953 + commit = 96b4f0314f1906d78069ec45a18d7cc660e73aeb parent = 9f797430963d9cf0fcef7d963466f9cac7026de2 method = merge cmdver = 0.4.1 diff --git a/deps/lightrec/blockcache.c b/deps/lightrec/blockcache.c index f50a2d6a..cdd8a0dc 100644 --- a/deps/lightrec/blockcache.c +++ b/deps/lightrec/blockcache.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Paul Cercueil + * Copyright (C) 2015-2020 Paul Cercueil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/deps/lightrec/disassembler.c b/deps/lightrec/disassembler.c index 1c3ef092..06fcec9d 100644 --- a/deps/lightrec/disassembler.c +++ b/deps/lightrec/disassembler.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Paul Cercueil + * Copyright (C) 2014-2020 Paul Cercueil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/deps/lightrec/emitter.c b/deps/lightrec/emitter.c index fb3faa8b..bc04c6ae 100644 --- a/deps/lightrec/emitter.c +++ b/deps/lightrec/emitter.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Paul Cercueil + * Copyright (C) 2014-2020 Paul Cercueil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/deps/lightrec/interpreter.c b/deps/lightrec/interpreter.c index b0fd66dc..acc41eaf 100644 --- a/deps/lightrec/interpreter.c +++ b/deps/lightrec/interpreter.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Paul Cercueil + * Copyright (C) 2019-2020 Paul Cercueil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/deps/lightrec/lightrec.c b/deps/lightrec/lightrec.c index a283b5ae..14e22ce4 100644 --- a/deps/lightrec/lightrec.c +++ b/deps/lightrec/lightrec.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Paul Cercueil + * Copyright (C) 2014-2020 Paul Cercueil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -777,6 +777,8 @@ static struct block * lightrec_precompile_block(struct lightrec_state *state, lightrec_print_disassembly(block, code, length); } + pr_debug("Block size: %lu opcodes\n", block->nb_ops); + /* If the first opcode is an 'impossible' branch, never compile the * block */ if (list->flags & LIGHTREC_EMULATE_BRANCH) @@ -825,6 +827,7 @@ int lightrec_compile_block(struct block *block) bool op_list_freed = false, fully_tagged = false; struct opcode *elm; jit_state_t *_jit; + jit_node_t *start_of_block; bool skip_next = false; jit_word_t code_size; unsigned int i, j; @@ -849,6 +852,8 @@ int lightrec_compile_block(struct block *block) jit_prolog(); jit_tramp(256); + start_of_block = jit_label(); + for (elm = block->opcode_list; elm; elm = elm->next) { next_pc = block->pc + elm->offset * sizeof(u32); @@ -887,6 +892,11 @@ int lightrec_compile_block(struct block *block) pr_debug("Patch local branch to offset 0x%x\n", branch->target << 2); + if (branch->target == 0) { + jit_patch_at(branch->branch, start_of_block); + continue; + } + for (j = 0; j < state->nb_targets; j++) { if (state->targets[j].offset == branch->target) { jit_patch_at(branch->branch, diff --git a/deps/lightrec/memmanager.c b/deps/lightrec/memmanager.c index 24600d5a..2e6b99bf 100644 --- a/deps/lightrec/memmanager.c +++ b/deps/lightrec/memmanager.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Paul Cercueil + * Copyright (C) 2019-2020 Paul Cercueil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/deps/lightrec/optimizer.c b/deps/lightrec/optimizer.c index 83d5048a..92b4daa5 100644 --- a/deps/lightrec/optimizer.c +++ b/deps/lightrec/optimizer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Paul Cercueil + * Copyright (C) 2014-2020 Paul Cercueil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -136,6 +136,18 @@ bool opcode_writes_register(union code op, u8 reg) default: return false; } + case OP_CP2: + if (op.r.op == OP_CP2_BASIC) { + switch (op.r.rs) { + case OP_CP2_BASIC_MFC2: + case OP_CP2_BASIC_CFC2: + return op.i.rt == reg; + default: + return false; + } + } else { + return false; + } case OP_META_MOV: return op.r.rd == reg; default: @@ -525,6 +537,9 @@ static int lightrec_transform_ops(struct block *block) list->i.rs = list->i.rt; list->i.rt = 0; } + } else if (list->i.rs == list->i.rt) { + list->i.rs = 0; + list->i.rt = 0; } break; case OP_BNE: @@ -625,11 +640,13 @@ static int lightrec_switch_delay_slots(struct block *block) break; case OP_BEQ: case OP_BNE: - if (opcode_writes_register(next_op, op.i.rt)) + if (op.i.rt && opcode_writes_register(next_op, op.i.rt)) continue; case OP_BLEZ: /* fall-through */ case OP_BGTZ: - if (opcode_writes_register(next_op, op.i.rs)) + case OP_META_BEQZ: + case OP_META_BNEZ: + if (op.i.rs && opcode_writes_register(next_op, op.i.rs)) continue; break; case OP_REGIMM: @@ -641,15 +658,11 @@ static int lightrec_switch_delay_slots(struct block *block) continue; case OP_REGIMM_BLTZ: /* fall-through */ case OP_REGIMM_BGEZ: - if (opcode_writes_register(next_op, op.i.rs)) + if (op.i.rs && + opcode_writes_register(next_op, op.i.rs)) continue; break; } - break; - case OP_META_BEQZ: - case OP_META_BNEZ: - if (opcode_writes_register(next_op, op.i.rs)) - continue; default: /* fall-through */ break; } @@ -749,16 +762,13 @@ static int lightrec_local_branches(struct block *block) break; } - if (!prev || prev->j.op != OP_META_SYNC) { + if (prev && prev->j.op != OP_META_SYNC) { pr_debug("Adding sync before offset " "0x%x\n", offset << 2); ret = lightrec_add_sync(block, prev); if (ret) return ret; - if (!prev) - prev = block->opcode_list; - prev->next->offset = target->offset; } diff --git a/deps/lightrec/recompiler.c b/deps/lightrec/recompiler.c index 3321a575..379881a0 100644 --- a/deps/lightrec/recompiler.c +++ b/deps/lightrec/recompiler.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Paul Cercueil + * Copyright (C) 2019-2020 Paul Cercueil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/deps/lightrec/regcache.c b/deps/lightrec/regcache.c index 0ce3456f..0256015d 100644 --- a/deps/lightrec/regcache.c +++ b/deps/lightrec/regcache.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Paul Cercueil + * Copyright (C) 2014-2020 Paul Cercueil * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public