X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=deps%2Flightrec%2Fconstprop.c;h=19403a69793f517dda47aa65cda780b9b1357d8a;hb=9159f799aba897c27569a7a51a40736bd8a90d2f;hp=353f42f11418a34be7f6302a667f1ac27a9007eb;hpb=9259d7486618d69721fee743c3e4d0b5c83805fe;p=pcsx_rearmed.git diff --git a/deps/lightrec/constprop.c b/deps/lightrec/constprop.c index 353f42f1..19403a69 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: @@ -323,7 +329,7 @@ void lightrec_consts_propagate(const struct opcode *list, case OP_SPECIAL_SRL: v[c.r.rd].value = v[c.r.rt].value >> c.r.imm; v[c.r.rd].known = (v[c.r.rt].known >> c.r.imm) - | (BIT(c.r.imm) - 1 << 32 - c.r.imm); + | ((BIT(c.r.imm) - 1) << (32 - c.r.imm)); v[c.r.rd].sign = c.r.imm ? 0 : v[c.r.rt].sign; break; @@ -351,7 +357,7 @@ void lightrec_consts_propagate(const struct opcode *list, imm = v[c.r.rs].value & 0x1f; v[c.r.rd].value = v[c.r.rt].value >> imm; v[c.r.rd].known = (v[c.r.rt].known >> imm) - | (BIT(imm) - 1 << 32 - imm); + | ((BIT(imm) - 1) << (32 - imm)); if (imm) v[c.r.rd].sign = 0; } else { @@ -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; } @@ -471,18 +484,18 @@ void lightrec_consts_propagate(const struct opcode *list, if (OPT_FLAG_MULT_DIV && c.r.imm) { if (c.r.op >= 32) { - v[c.r.imm].value = v[c.r.rs].value << c.r.op - 32; - v[c.r.imm].known = (v[c.r.rs].known << c.r.op - 32) + v[c.r.imm].value = v[c.r.rs].value << (c.r.op - 32); + v[c.r.imm].known = (v[c.r.rs].known << (c.r.op - 32)) | (BIT(c.r.op - 32) - 1); - v[c.r.imm].sign = v[c.r.rs].sign << c.r.op - 32; + v[c.r.imm].sign = v[c.r.rs].sign << (c.r.op - 32); } else if (c.i.op == OP_META_MULT2) { - v[c.r.imm].value = (s32)v[c.r.rs].value >> 32 - c.r.op; - v[c.r.imm].known = (s32)v[c.r.rs].known >> 32 - c.r.op; - v[c.r.imm].sign = (s32)v[c.r.rs].sign >> 32 - c.r.op; + v[c.r.imm].value = (s32)v[c.r.rs].value >> (32 - c.r.op); + v[c.r.imm].known = (s32)v[c.r.rs].known >> (32 - c.r.op); + v[c.r.imm].sign = (s32)v[c.r.rs].sign >> (32 - c.r.op); } else { - v[c.r.imm].value = v[c.r.rs].value >> 32 - c.r.op; - v[c.r.imm].known = v[c.r.rs].known >> 32 - c.r.op; - v[c.r.imm].sign = v[c.r.rs].sign >> 32 - c.r.op; + v[c.r.imm].value = v[c.r.rs].value >> (32 - c.r.op); + v[c.r.imm].known = v[c.r.rs].known >> (32 - c.r.op); + v[c.r.imm].sign = v[c.r.rs].sign >> (32 - c.r.op); } } break; @@ -644,38 +657,57 @@ 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; case OP_LW: + case OP_META_LWU: 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;