#!/usr/bin/env python3

# SPDX-FileCopyrightText: © 2022 Decompollaborate
# SPDX-License-Identifier: MIT

from __future__ import annotations

from .Enum import Enum
from .InstrCategory import InstrCategory


class Instruction:
    rs: Enum
    """The value of the `rs` register for this instruction.
    The type of this attribute will be either a `RegGprO32` or a `RegGprN32` depending on the current `config.regNames_gprAbiNames` value.
    If the current instruction does not use the `rs` register, then a Runtime exception will be raised.
    Read-only."""
    rt: Enum
    """The value of the `rt` register for this instruction.
    The type of this attribute will be either a `RegGprO32` or a `RegGprN32` depending on the current `config.regNames_gprAbiNames` value.
    If the current instruction does not use the `rt` register, then a Runtime exception will be raised.
    Read-only."""
    rd: Enum
    """The value of the `rd` register for this instruction.
    The type of this attribute will be either a `RegGprO32` or a `RegGprN32` depending on the current `config.regNames_gprAbiNames` value.
    If the current instruction does not use the `rd` register, then a Runtime exception will be raised.
    Read-only."""
    sa: int
    """The value of the `sa` field for this instruction.
    If the current instruction does not have a `sa` field, then a Runtime exception will be raised.
    Read-only."""

    uniqueId: Enum
    """An unique identificator for the opcode of this instruction.
    The type is an `InstrId` enum.
    Read-only."""

    vram: int = 0
    """The vram (virtual ram) address for this instruction"""
    inHandwrittenFunction: bool = False
    """Boolean value indicating if the current instruction is used on a handwritten function. This is intended to be determined by the user."""


    def __init__(self, word: int, vram: int=0, category: Enum=InstrCategory.CPU) -> None: ...

    def getRaw(self) -> int: ...
    def getImmediate(self) -> int: ...
    def getProcessedImmediate(self) -> int: ...
    def getInstrIndexAsVram(self) -> int: ...
    def getBranchOffset(self) -> int: ...
    def getGenericBranchOffset(self, currentVram: int) -> int: ...
    def getOpcodeName(self) -> str: ...

    def blankOut(self) -> None: ...

    def isImplemented(self) -> bool: ...
    def isLikelyHandwritten(self) -> bool: ...
    def isNop(self) -> bool: ...
    def isUnconditionalBranch(self) -> bool: ...
    def isJrRa(self) -> bool: ...
    def isJrNotRa(self) -> bool: ...
    def hasDelaySlot(self) -> bool: ...
    def mapInstrToType(self) -> str|None: ...

    def sameOpcode(self, other: Instruction) -> bool: ...
    def sameOpcodeButDifferentArguments(self, other: Instruction) -> bool: ...

    def isValid(self) -> bool: ...

    def isUnknownType(self) -> bool: ...
    def isJType(self) -> bool: ...
    def isIType(self) -> bool: ...
    def isRType(self) -> bool: ...
    def isRegimmType(self) -> bool: ...
    def isBranch(self) -> bool: ...
    def isBranchLikely(self) -> bool: ...
    def isJump(self) -> bool: ...
    def isTrap(self) -> bool: ...
    def isFloat(self) -> bool: ...
    def isDouble(self) -> bool: ...
    def isUnsigned(self) -> bool: ...
    def modifiesRt(self) -> bool: ...
    def modifiesRd(self) -> bool: ...
    def notEmitedByCompilers(self) -> bool: ...
    def canBeHi(self) -> bool: ...
    def canBeLo(self) -> bool: ...
    def doesLink(self) -> bool: ...
    def doesDereference(self) -> bool: ...
    def doesLoad(self) -> bool: ...
    def doesStore(self) -> bool: ...
    def maybeIsMove(self) -> bool: ...
    def isPseudo(self) -> bool: ...

    def disassemble(self, immOverride: str|None=None, extraLJust: int=0) -> str: ...

    def __reduce__(self) -> tuple: ...

    def __repr__(self) -> str: ...
    def __str__(self) -> str: ...
