From 583e702547d0347d4634d48a314fc8dd3de75db2 Mon Sep 17 00:00:00 2001 From: patchzyy <64382339+patchzyy@users.noreply.github.com> Date: Thu, 24 Sep 2026 18:06:32 +0200 Subject: [PATCH] add bltl (#254) --- .../src/Translator.Core/Lifting/PpcLifter.cs | 16 ++++++++++++++++ .../PpcLifterAdditionalCoverageTests.cs | 17 +++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/translator/src/Translator.Core/Lifting/PpcLifter.cs b/translator/src/Translator.Core/Lifting/PpcLifter.cs index c32cdc6..4d41475 100644 --- a/translator/src/Translator.Core/Lifting/PpcLifter.cs +++ b/translator/src/Translator.Core/Lifting/PpcLifter.cs @@ -1942,6 +1942,22 @@ public sealed partial class PpcLifter new IrCall(string.Empty, TargetLabel(ins, validAddresses, preferFallthrough: false), blArgs) }; + case "bltl": + { + var crField = "cr0"; + if (ops.Count > 0 && ops[0] is PpcConditionRegisterOperand crOp) + { + crField = NormalizeRegister(crOp.Name); + } + + return new IrInstruction[] + { + new IrAssign("lr", IrValue.Imm((int)ins.EndAddress)), + new IrBranch("blt", TargetLabel(ins, validAddresses, preferFallthrough: false), + $"0x{ins.EndAddress:X8}", crField) + }; + } + case "bcl": { var rawInstr = ReadRawInstruction(ins); diff --git a/translator/tests/Translator.Tests/PpcLifterAdditionalCoverageTests.cs b/translator/tests/Translator.Tests/PpcLifterAdditionalCoverageTests.cs index 3fc944d..9637084 100644 --- a/translator/tests/Translator.Tests/PpcLifterAdditionalCoverageTests.cs +++ b/translator/tests/Translator.Tests/PpcLifterAdditionalCoverageTests.cs @@ -14,6 +14,23 @@ public class PpcLifterAdditionalCoverageTests private static PpcInstruction Instruction(uint raw, string mnemonic, params PpcOperand[] operands) => PpcInstruction.Synthetic(0x80000000, raw, mnemonic, operands); + [Fact] + public void LinkedConditionalBranchSetsLrBeforeEitherPath() + { + var branch = PpcDecoder.Decode(0x80004394, 0x41800029); + var ir = Assert.Single(new PpcLifter().Lift(new[] { branch })).Ir; + + Assert.Equal("bltl", branch.Mnemonic); + var lr = Assert.IsType(ir[0]); + Assert.Equal("lr", lr.Destination); + Assert.Equal(unchecked((int)0x80004398u), lr.Value.Constant); + + var decision = Assert.IsType(ir[1]); + Assert.Equal("blt", decision.Condition); + Assert.Equal("0x800043BC", decision.TrueLabel); + Assert.Equal("0x80004398", decision.FalseLabel); + } + [Fact] public void LiftsAdditionalNonDotArithmeticAndLogicalForms() {