X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=deps%2Flightrec%2Fconstprop.c;h=8499c6ecc7de279e1964a672aeac119a96d88771;hb=1e766b53a7f090d7d338cd777f362d73203b315c;hp=353f42f11418a34be7f6302a667f1ac27a9007eb;hpb=9259d7486618d69721fee743c3e4d0b5c83805fe;p=pcsx_rearmed.git diff --git a/deps/lightrec/constprop.c b/deps/lightrec/constprop.c index 353f42f1..8499c6ec 100644 --- a/deps/lightrec/constprop.c +++ b/deps/lightrec/constprop.c @@ -243,12 +243,13 @@ static void lightrec_propagate_slt(u32 rs, u32 rd, bool is_signed, } } -void lightrec_consts_propagate(const struct opcode *list, +void lightrec_consts_propagate(const struct block *block, unsigned int idx, struct constprop_data *v) { + const struct opcode *list = block->opcode_list; union code c; - u32 imm; + u32 imm, flags; if (idx == 0) return; @@ -263,8 +264,13 @@ void lightrec_consts_propagate(const struct opcode *list, return; } - if (idx > 1 && !op_flag_sync(list[idx - 1].flags)) { - c = list[idx - 2].c; + flags = list[idx - 1].flags; + + if (idx > 1 && !op_flag_sync(flags)) { + if (op_flag_no_ds(flags)) + c = list[idx - 1].c; + else + c = list[idx - 2].c; switch (c.i.op) { case OP_BNE: @@ -449,6 +455,13 @@ void lightrec_consts_propagate(const struct opcode *list, v[c.r.rd].known = 0; v[c.r.rd].sign = 0; break; + + case OP_SPECIAL_JALR: + v[c.r.rd].known = 0xffffffff; + v[c.r.rd].sign = 0; + v[c.r.rd].value = block->pc + (idx + 2 << 2); + break; + default: break; } @@ -644,7 +657,7 @@ void lightrec_consts_propagate(const struct opcode *list, imm = imm ? GENMASK(31, 32 - imm) : 0; v[c.i.rt].sign = 0; } - v[c.i.rt].known &= ~imm; + v[c.i.rt].known &= imm; break; } fallthrough; @@ -652,30 +665,48 @@ void lightrec_consts_propagate(const struct opcode *list, v[c.i.rt].known = 0; v[c.i.rt].sign = 0; break; - case OP_META_MOV: - v[c.r.rd] = v[c.r.rs]; - break; - case OP_META_EXTC: - v[c.i.rt].value = (s32)(s8)v[c.i.rs].value; - if (v[c.i.rs].known & BIT(7)) { - v[c.i.rt].known = v[c.i.rs].known | 0xffffff00; - v[c.i.rt].sign = 0; - } else { - v[c.i.rt].known = v[c.i.rs].known & 0x7f; - v[c.i.rt].sign = 0xffffff80; - } - break; + case OP_META: + switch (c.m.op) { + case OP_META_MOV: + v[c.m.rd] = v[c.m.rs]; + break; - case OP_META_EXTS: - v[c.i.rt].value = (s32)(s16)v[c.i.rs].value; - if (v[c.i.rs].known & BIT(15)) { - v[c.i.rt].known = v[c.i.rs].known | 0xffff0000; - v[c.i.rt].sign = 0; - } else { - v[c.i.rt].known = v[c.i.rs].known & 0x7fff; - v[c.i.rt].sign = 0xffff8000; + case OP_META_EXTC: + v[c.m.rd].value = (s32)(s8)v[c.m.rs].value; + if (v[c.m.rs].known & BIT(7)) { + v[c.m.rd].known = v[c.m.rs].known | 0xffffff00; + v[c.m.rd].sign = 0; + } else { + v[c.m.rd].known = v[c.m.rs].known & 0x7f; + v[c.m.rd].sign = 0xffffff80; + } + break; + + case OP_META_EXTS: + v[c.m.rd].value = (s32)(s16)v[c.m.rs].value; + if (v[c.m.rs].known & BIT(15)) { + v[c.m.rd].known = v[c.m.rs].known | 0xffff0000; + v[c.m.rd].sign = 0; + } else { + v[c.m.rd].known = v[c.m.rs].known & 0x7fff; + v[c.m.rd].sign = 0xffff8000; + } + break; + + case OP_META_COM: + v[c.m.rd].known = v[c.m.rs].known; + v[c.m.rd].value = ~v[c.m.rs].value; + v[c.m.rd].sign = v[c.m.rs].sign; + break; + default: + break; } break; + case OP_JAL: + v[31].known = 0xffffffff; + v[31].sign = 0; + v[31].value = block->pc + (idx + 2 << 2); + break; default: break;