"""
Test software step-inst, also known as instruction level single step, in risc-v atomic sequence.
For more information about atomic sequences, see the RISC-V Unprivileged ISA specification.
"""

import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil


class TestSoftwareStep(TestBase):
    SHARED_BUILD_TESTCASE = False

    def do_sequence_test(self, filename, bkpt_name):
        source_file = filename + ".c"
        exe_file = filename + ".x"

        self.build(dictionary={"C_SOURCES": source_file, "EXE": exe_file})
        (target, process, cur_thread, bkpt) = lldbutil.run_to_name_breakpoint(
            self, bkpt_name, exe_name=exe_file
        )
        entry_pc = cur_thread.GetFrameAtIndex(0).GetPC()

        self.runCmd("thread step-inst")
        self.expect(
            "thread list",
            substrs=["stopped", "stop reason = instruction step into"],
        )

        # Get the instruction we stopped at
        pc = cur_thread.GetFrameAtIndex(0).GetPCAddress()
        inst = target.ReadInstructions(pc, 1).GetInstructionAtIndex(0)

        inst_mnemonic = inst.GetMnemonic(target)
        inst_operands = inst.GetOperands(target)
        if not inst_operands:
            return inst_mnemonic

        return f"{inst_mnemonic} {inst_operands}"

    @skipIf(archs=no_match("^riscv.*"))
    def test_cas(self):
        """
        This test verifies LLDB instruction step handling of a proper lr/sc pair.
        """
        instruction = self.do_sequence_test("main", "cas")
        self.assertEqual(instruction, "nop")

    @skipIf(archs=no_match("^riscv.*"))
    def test_branch_cas(self):
        """
        LLDB cannot predict the actual state of registers within a critical section (i.e., inside an atomic
        sequence). Therefore, it should identify all forward branches inside the atomic sequence and set
        breakpoints at every jump address that lies beyond the end of the sequence (after the sc instruction).
        This ensures that if any such branch is taken, execution will pause at its target address.

        This test includes an lr/sc sequence containing an active forward branch with a jump address located
        after the end of the atomic section. LLDB should correctly stop at this branch's target address. The
        test is nearly identical to the previous one, except for the branch condition, which is inverted and
        will result in a taken jump.
        """
        instruction = self.do_sequence_test("branch", "branch_cas")
        self.assertEqual(instruction, "ret")

    @skipIf(archs=no_match("^riscv.*"))
    def test_incomplete_sequence_without_lr(self):
        """
        This test verifies the behavior of a standalone sc instruction without a preceding lr. Since the sc
        lacks the required lr pairing, LLDB should treat it as a non-atomic store rather than part of an
        atomic sequence.
        """
        instruction = self.do_sequence_test(
            "incomplete_sequence_without_lr", "incomplete_cas"
        )
        self.assertEqual(instruction, "and a5, a2, a4")

    @skipIf(archs=no_match("^riscv.*"))
    def test_incomplete_sequence_without_sc(self):
        """
        This test checks the behavior of a standalone lr instruction without a subsequent sc. Since the lr
        lacks its required sc counterpart, LLDB should treat it as a non-atomic load rather than part of an
        atomic sequence.
        """
        instruction = self.do_sequence_test(
            "incomplete_sequence_without_sc", "incomplete_cas"
        )
        self.assertEqual(instruction, "and a5, a2, a4")
