from __future__ import annotations
import collections.abc
import datetime
import typing
from warnings import deprecated # type: ignore

import jpype # type: ignore
import jpype.protocol # type: ignore

import ghidra.pcode.emu.jit
import ghidra.pcode.exec_
import ghidra.program.model.address
import ghidra.program.model.lang
import ghidra.program.model.pcode
import java.lang # type: ignore
import java.lang.invoke # type: ignore
import java.util # type: ignore


class JitCompiledPassageClass(java.lang.Record):
    """
    A compiled passage that is not yet bound/instantiated to a thread.
     
     
    
    This is the output of :meth:`JitCompiler.compilePassage(Lookup, JitPassage) <JitCompiler.compilePassage>`, and it will be
    cached (indirectly) by :obj:`JitPcodeEmulator`. The emulator actually caches the various entry
    points returned by :meth:`getBlockEntries() <.getBlockEntries>`. Each of those retains a reference to this object.
    An :obj:`EntryPointPrototype` pairs this with a entry block ID. That prototype can then be
    instantiated/bound to a thread, producing an :obj:`EntryPoint`. That bound entry point is
    produced by invoking :meth:`createInstance(JitPcodeThread) <.createInstance>` and just copying the block id.
     
     
    
    This object wraps the generated (and now loaded) class and provides the mechanisms for reflecting
    and processing the ``ENTRIES`` field, and for reflecting and invoking the generated
    constructor. Note that explicit invocation of the static initializer via reflection is not
    necessary.
    """

    class_: typing.ClassVar[java.lang.Class]
    CONSTRUCTOR_TYPE: typing.Final[java.lang.invoke.MethodType]
    """
    The constructor signature: ``Passage$at_[entry](JitPcodeThread)``
    """


    def __init__(self, lookup: java.lang.invoke.MethodHandles.Lookup, cls: java.lang.Class[JitCompiledPassage], constructor: java.lang.invoke.MethodHandle):
        ...

    def cls(self) -> java.lang.Class[JitCompiledPassage]:
        ...

    def constructor(self) -> java.lang.invoke.MethodHandle:
        ...

    def createInstance(self, thread: ghidra.pcode.emu.jit.JitPcodeThread) -> JitCompiledPassage:
        """
        Create an instance bound to the given thread
        
        :param ghidra.pcode.emu.jit.JitPcodeThread thread: the thread
        :return: the instance, prepared to execute on the given thread
        :rtype: JitCompiledPassage
        """

    def equals(self, o: java.lang.Object) -> bool:
        ...

    def getBlockEntries(self) -> java.util.Map[ghidra.pcode.emu.jit.JitPassage.AddrCtx, JitCompiledPassage.EntryPointPrototype]:
        """
        Get the entry points for this compiled passage
         
         
        
        This processes the ``ENTRIES`` field, which is just a list of targets. The position of
        each target in the list corresponds to the block id accepted by the generated
        :meth:`JitCompiledPassage.run(int) <JitCompiledPassage.run>` method.
        
        :return: the map of targets to their corresponding entry point prototypes
        :rtype: java.util.Map[ghidra.pcode.emu.jit.JitPassage.AddrCtx, JitCompiledPassage.EntryPointPrototype]
        """

    def hashCode(self) -> int:
        ...

    @staticmethod
    def load(lookup: java.lang.invoke.MethodHandles.Lookup, bytes: jpype.JArray[jpype.JByte]) -> JitCompiledPassageClass:
        """
        Load the generated class from the given bytes
         
         
        
        The bytes must define a class that implements :obj:`JitCompiledPassage`. It must define a
        constructor having the signature :obj:`.CONSTRUCTOR_TYPE`, and it must define a static field
        ``List<AddrCtx> ENTRIES``.
        
        :param java.lang.invoke.MethodHandles.Lookup lookup: a lookup that can see all the elements the generated class needs. Likely, this
                    should be from the emulator implementation, which may be an extension in a script.
        :param jpype.JArray[jpype.JByte] bytes: the classfile bytes
        :return: the wrapped class
        :rtype: JitCompiledPassageClass
        """

    def lookup(self) -> java.lang.invoke.MethodHandles.Lookup:
        ...

    def toString(self) -> str:
        ...

    @property
    def blockEntries(self) -> java.util.Map[ghidra.pcode.emu.jit.JitPassage.AddrCtx, JitCompiledPassage.EntryPointPrototype]:
        ...


class JitCompiledPassage(java.lang.Object):
    """
    The interface implemented by classfiles generated by :obj:`JitCompiler`.
     
     
    
    This also serves as a run-time library of routines that implement p-code ops not trivially
    implemented by the JVM or its run-time library. In theory, they can be inlined by the JVM's JIT
    at its discretion.
    """

    class EntryPointPrototype(java.lang.Object):
        """
        An entry point that is not yet bound to a specific thread
        
        
        .. admonition:: Implementation Note
        
            This would be a ``record`` except that it maintains the cache of instances per
            thread
        """

        class_: typing.ClassVar[java.lang.Class]

        def __init__(self, cls: JitCompiledPassageClass, blockId: typing.Union[jpype.JInt, int]):
            """
            Construct an entry prototype
            
            :param JitCompiledPassageClass cls: the compiled passage class (i.e., passage not yet bound to a specific thread)
            :param jpype.JInt or int blockId: the block at which to enter the passage
            """

        def createInstance(self, thread: ghidra.pcode.emu.jit.JitPcodeThread) -> JitCompiledPassage.EntryPoint:
            """
            Create (or get) the entry point for the given thread
            
            :param ghidra.pcode.emu.jit.JitPcodeThread thread: the thread to bind to the entry point
            :return: the resulting entry point
            :rtype: JitCompiledPassage.EntryPoint
            
            .. seealso::
            
                | :obj:`JitPcodeThread.getEntry(AddrCtx)`
            """


    class EntryPoint(java.lang.Record):
        """
        An entry point into a translated passage
         
         
        
        This represents a translated passage and an index into its list of entry points. For an
        overview of how this fits into the JIT-accelerated execution loop, see
        :obj:`JitPcodeThread`, especially the **Translate** and **Execute** sections. For
        details of how the entry points and their metadata are exported, see
        :obj:`JitCodeGenerator`, especially the **Entry Point Dispatch** section.
        """

        class_: typing.ClassVar[java.lang.Class]

        def __init__(self, prototype: JitCompiledPassage.EntryPointPrototype, passage: JitCompiledPassage, blockId: typing.Union[jpype.JInt, int]):
            ...

        def blockId(self) -> int:
            ...

        def equals(self, o: java.lang.Object) -> bool:
            ...

        def hashCode(self) -> int:
            ...

        def passage(self) -> JitCompiledPassage:
            ...

        def prototype(self) -> JitCompiledPassage.EntryPointPrototype:
            ...

        def run(self) -> JitCompiledPassage.EntryPoint:
            """
            Start/resume execution of the bound thread at this entry point.
             
             
            
            The associated passage is invoked, starting at the given block via
            :meth:`JitCompiledPassage.run(int) <JitCompiledPassage.run>`, which was generated by :obj:`JitCodeGenerator`.
            
            :return: as in :meth:`JitCompiledPassage.run(int) <JitCompiledPassage.run>`
            :rtype: JitCompiledPassage.EntryPoint
            """

        def toString(self) -> str:
            ...


    class ExitSlot(java.lang.Object):
        """
        A cache slot for a chained entry point
         
         
        
        One of these is constructed for each target of a direct branch that exits the passage,
        including those of synthetic :obj:`exit <ExitPcodeOp>` ops. For each such branch, the
        :obj:`JitCodeGenerator` emits code to invoke :meth:`getChained() <.getChained>` on the target's exit slot
        and to return the resulting entry point.
        """

        class_: typing.ClassVar[java.lang.Class]

        def __init__(self, thread: ghidra.pcode.emu.jit.JitPcodeThread, target: typing.Union[jpype.JLong, int], ctx: ghidra.program.model.lang.RegisterValue):
            """
            Construct an exit slot for the given target and bound thread
            
            :param ghidra.pcode.emu.jit.JitPcodeThread thread: the bound thread for the passage constructing this slot
            :param jpype.JLong or int target: the offset of the target address
            :param ghidra.program.model.lang.RegisterValue ctx: the target decode context
            """

        def getChained(self) -> JitCompiledPassage.EntryPoint:
            """
            Get the entry point for this target
             
             
            
            This may cause the emulator to translate a new passage.
            
            :return: the entry point
            :rtype: JitCompiledPassage.EntryPoint
            
            .. admonition:: Implementation Note
            
                This will always return a non-null entry point, even if the branch target is
                invalid. In that case, the "passage" will consist of a single
                :obj:`DecodeErrorInstruction`, which will ensure the emulator crashes upon
                trying to execute at the target address.
            """

        @property
        def chained(self) -> JitCompiledPassage.EntryPoint:
            ...


    class MpShiftPrivate(java.lang.Enum[JitCompiledPassage.MpShiftPrivate]):

        class_: typing.ClassVar[java.lang.Class]

        @staticmethod
        def valueOf(name: typing.Union[java.lang.String, str]) -> JitCompiledPassage.MpShiftPrivate:
            ...

        @staticmethod
        def values() -> jpype.JArray[JitCompiledPassage.MpShiftPrivate]:
            ...


    class MpDivPrivate(java.lang.Enum[JitCompiledPassage.MpDivPrivate]):

        class_: typing.ClassVar[java.lang.Class]

        @staticmethod
        def valueOf(name: typing.Union[java.lang.String, str]) -> JitCompiledPassage.MpDivPrivate:
            ...

        @staticmethod
        def values() -> jpype.JArray[JitCompiledPassage.MpDivPrivate]:
            ...


    class_: typing.ClassVar[java.lang.Class]
    MASK_I2UL: typing.Final = 4294967295

    @staticmethod
    def conv2IntToLong(msl: typing.Union[jpype.JInt, int], lsl: typing.Union[jpype.JInt, int]) -> int:
        """
        Convert two integers into a single long
         
         
        
        In terms of the JVM stack, this simply converts the top two ints to an equivalent long.
        **TODO**: This no longer appears to be used, but may be in anticipation of multi-precision
        integer support.
        
        :param jpype.JInt or int msl: the more significant leg
        :param jpype.JInt or int lsl: the less significant leg
        :return: the long
        :rtype: int
        """

    def count(self, instructions: typing.Union[jpype.JInt, int], trailingOps: typing.Union[jpype.JInt, int]):
        """
        Invoke :meth:`JitPcodeThread.count(int, int) <JitPcodeThread.count>` for the bound thread
        
        :param jpype.JInt or int instructions: as in :meth:`JitPcodeThread.count(int, int) <JitPcodeThread.count>`
        :param jpype.JInt or int trailingOps: as in :meth:`JitPcodeThread.count(int, int) <JitPcodeThread.count>`
        """

    @staticmethod
    def createContext(language: ghidra.program.model.lang.Language, value: typing.Union[java.lang.String, str]) -> ghidra.program.model.lang.RegisterValue:
        """
        Construct a contextreg value from the given language and hex value
         
         
        
        This is called by generated static initializers to pre-construct context values.
        
        :param ghidra.program.model.lang.Language language: the language
        :param java.lang.String or str value: the value as a string of hexadecimal digits
        :return: the value
        :rtype: ghidra.program.model.lang.RegisterValue
        """

    def createDecodeError(self, message: typing.Union[java.lang.String, str], counter: typing.Union[jpype.JLong, int]) -> ghidra.pcode.exec_.DecodePcodeExecutionException:
        """
        Construct an exception when attempting to execute an "instruction" that could not be decoded.
         
         
        
        When the decoder encounters an error, instead of crashing immediately, it must consider that
        execution may not actually reach the error, so it instead emits pseudo-instructions
        describing the error. The translator then emits code that will invoke this method and throw
        the result. Thus, we only crash if the erroneous condition is actually met.
        
        :param java.lang.String or str message: the human-readable message
        :param jpype.JLong or int counter: the program counter where the decode error was encountered
        :return: the exception, which should be thrown immediately
        :rtype: ghidra.pcode.exec_.DecodePcodeExecutionException
        """

    def createExitSlot(self, target: typing.Union[jpype.JLong, int], ctx: ghidra.program.model.lang.RegisterValue) -> JitCompiledPassage.ExitSlot:
        """
        Construct an exit slot for the given branch target
         
         
        
        This is invoked by generated constructors for each branch target that exits the passage. Each
        is saved as a field and will be filled lazily with its chained entry point the first time the
        branch is taken.
        
        :param jpype.JLong or int target: the target program counter
        :param ghidra.program.model.lang.RegisterValue ctx: the target decode context
        :return: the exit slot
        :rtype: JitCompiledPassage.ExitSlot
        """

    @staticmethod
    def createVarnode(factory: ghidra.program.model.address.AddressFactory, space: typing.Union[java.lang.String, str], offset: typing.Union[jpype.JLong, int], size: typing.Union[jpype.JInt, int]) -> ghidra.program.model.pcode.Varnode:
        """
        Construct a varnode
         
         
        
        This is called by generated static initializers to pre-construct any varnodes it needs to
        re-create, mostly for invoking userops with the Standard strategy.
        
        :param ghidra.program.model.address.AddressFactory factory: the language's address factory
        :param java.lang.String or str space: the name of the space
        :param jpype.JLong or int offset: the byte offset
        :param jpype.JInt or int size: the size (in bytes)
        :return: the varnode
        :rtype: ghidra.program.model.pcode.Varnode
        """

    @staticmethod
    def getChained(slot: JitCompiledPassage.ExitSlot) -> JitCompiledPassage.EntryPoint:
        """
        Get the chained entry point for the given exit point's target
         
         
        
        This is invoked by generated code in :meth:`JitCompiledPassage.run(int) <JitCompiledPassage.run>` to take a branch
        exiting the passage. The first time, the exit slot is lazily filled, possibly requiring
        further JIT translation.
        
        :param JitCompiledPassage.ExitSlot slot: the slot for the target of the branch we're taking
        :return: the chained entry point
        :rtype: JitCompiledPassage.EntryPoint
        """

    @staticmethod
    def getLanguage(languageID: typing.Union[java.lang.String, str]) -> ghidra.program.model.lang.Language:
        """
        Get the language for the given string language ID
         
         
        
        This is called by generated static initializers.
        
        :param java.lang.String or str languageID: the language ID
        :return: the language
        :rtype: ghidra.program.model.lang.Language
        :raises LanguageNotFoundException: if the language is not found
        """

    def getUseropDefinition(self, name: typing.Union[java.lang.String, str]) -> ghidra.pcode.exec_.PcodeUseropLibrary.PcodeUseropDefinition[jpype.JArray[jpype.JByte]]:
        """
        Retrieve a userop definition from the bound thread.
         
         
        
        This is invoked by generated constructors to retain a userop reference for later invocation.
        Note that it is the userop as defined by the user or emulator, not any wrapper used during
        decode or translation. Depending on the invocation strategy, this reference may be saved and
        later used with :meth:`invokeUserop(PcodeUseropDefinition, Varnode, Varnode[]) <.invokeUserop>`, or its
        method and instance may be extracted and saved for Direct invocation later.
        
        :param java.lang.String or str name: the name of the userop
        :return: the userop or ``null``
        :rtype: ghidra.pcode.exec_.PcodeUseropLibrary.PcodeUseropDefinition[jpype.JArray[jpype.JByte]]
        
        .. seealso::
        
            | :obj:`JitDataFlowUseropLibrary`
        """

    @staticmethod
    @typing.overload
    def intLeft(out: jpype.JArray[jpype.JInt], outBytes: typing.Union[jpype.JInt, int], val: jpype.JArray[jpype.JInt], amt: jpype.JArray[jpype.JInt]):
        """
        The implementation of :obj:`int_left <PcodeOp.INT_LEFT>` on multi-precision ints.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`ishl <Opcodes.ISHL>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.
        
        :param jpype.JArray[jpype.JInt] out: the array to receive the output, in little-endian order
        :param jpype.JInt or int outBytes: the actual size in bytes of the output operand
        :param jpype.JArray[jpype.JInt] val: the value as in ``val << amt``, in little-endian order
        :param jpype.JArray[jpype.JInt] amt: the amt as in ``val << amt``, in little-endian order
        """

    @staticmethod
    @typing.overload
    def intLeft(out: jpype.JArray[jpype.JInt], outBytes: typing.Union[jpype.JInt, int], val: jpype.JArray[jpype.JInt], amt: typing.Union[jpype.JLong, int]):
        """
        The implementation of :obj:`int_left <PcodeOp.INT_LEFT>` on an mp-int with a JVM long shift
        amount.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`ishl <Opcodes.ISHL>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.
        
        :param jpype.JArray[jpype.JInt] out: the array to receive the output, in little-endian order
        :param jpype.JInt or int outBytes: the actual size in bytes of the output operand
        :param jpype.JArray[jpype.JInt] val: the value as in ``val << amt``, in little-endian order
        :param jpype.JLong or int amt: the amt as in ``val << amt``
        """

    @staticmethod
    @typing.overload
    def intLeft(out: jpype.JArray[jpype.JInt], outBytes: typing.Union[jpype.JInt, int], val: jpype.JArray[jpype.JInt], amt: typing.Union[jpype.JInt, int]):
        """
        The implementation of :obj:`int_left <PcodeOp.INT_LEFT>` on an mp-int with a JVM int shift
        amount.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`ishl <Opcodes.ISHL>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.
        
        :param jpype.JArray[jpype.JInt] out: the array to receive the output, in little-endian order
        :param jpype.JInt or int outBytes: the actual size in bytes of the output operand
        :param jpype.JArray[jpype.JInt] val: the value as in ``val << amt``, in little-endian order
        :param jpype.JInt or int amt: the amt as in ``val << amt``
        """

    @staticmethod
    @typing.overload
    def intLeft(val: typing.Union[jpype.JLong, int], amt: jpype.JArray[jpype.JInt]) -> int:
        """
        The implementation of :obj:`int_left <PcodeOp.INT_LEFT>` on a JVM long with an mp-int shift
        amount.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`ishl <Opcodes.ISHL>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.
        
        :param jpype.JLong or int val: the value as in ``val << amt``
        :param jpype.JArray[jpype.JInt] amt: the amt as in ``val << amt``, in little-endian order
        :return: the value
        :rtype: int
        """

    @staticmethod
    @typing.overload
    def intLeft(val: typing.Union[jpype.JLong, int], amt: typing.Union[jpype.JLong, int]) -> int:
        """
        The implementation of :obj:`int_left <PcodeOp.INT_LEFT>` on JVM longs.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`ishl <Opcodes.ISHL>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.
        
        :param jpype.JLong or int val: the value as in ``val << amt``
        :param jpype.JLong or int amt: the amt as in ``val << amt``
        :return: the value
        :rtype: int
        """

    @staticmethod
    @typing.overload
    def intLeft(val: typing.Union[jpype.JLong, int], amt: typing.Union[jpype.JInt, int]) -> int:
        """
        The implementation of :obj:`int_left <PcodeOp.INT_LEFT>` on JVM long with int amt.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`ishl <Opcodes.ISHL>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.
        
        :param jpype.JLong or int val: the value as in ``val << amt``
        :param jpype.JInt or int amt: the amt as in ``val << amt``
        :return: the value
        :rtype: int
        """

    @staticmethod
    @typing.overload
    def intLeft(val: typing.Union[jpype.JInt, int], amt: jpype.JArray[jpype.JInt]) -> int:
        """
        The implementation of :obj:`int_left <PcodeOp.INT_LEFT>` on a JVM int with an mp-int shift
        amount.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`ishl <Opcodes.ISHL>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.
        
        :param jpype.JInt or int val: the value as in ``val << amt``
        :param jpype.JArray[jpype.JInt] amt: the amt as in ``val << amt``, in little-endian order
        :return: the value
        :rtype: int
        """

    @staticmethod
    @typing.overload
    def intLeft(val: typing.Union[jpype.JInt, int], amt: typing.Union[jpype.JLong, int]) -> int:
        """
        The implementation of :obj:`int_left <PcodeOp.INT_LEFT>` on JVM int with long amt.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`ishl <Opcodes.ISHL>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.
        
        :param jpype.JInt or int val: the value as in ``val << amt``
        :param jpype.JLong or int amt: the amt as in ``val << amt``
        :return: the value
        :rtype: int
        """

    @staticmethod
    @typing.overload
    def intLeft(val: typing.Union[jpype.JInt, int], amt: typing.Union[jpype.JInt, int]) -> int:
        """
        The implementation of :obj:`int_left <PcodeOp.INT_LEFT>` on JVM ints.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`ishl <Opcodes.ISHL>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.
        
        :param jpype.JInt or int val: the value as in ``val << amt``
        :param jpype.JInt or int amt: the amt as in ``val << amt``
        :return: the value
        :rtype: int
        """

    @staticmethod
    @typing.overload
    def intRight(out: jpype.JArray[jpype.JInt], outBytes: typing.Union[jpype.JInt, int], val: jpype.JArray[jpype.JInt], amt: jpype.JArray[jpype.JInt]):
        """
        The implementation of :obj:`int_right <PcodeOp.INT_RIGHT>` on multi-precision ints.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`iushr <Opcodes.IUSHR>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.
        
        :param jpype.JArray[jpype.JInt] out: the array to receive the output, in little-endian order
        :param jpype.JInt or int outBytes: the actual size in bytes of the output operand
        :param jpype.JArray[jpype.JInt] val: the value as in ``val >> amt``, in little-endian order
        :param jpype.JArray[jpype.JInt] amt: the amt as in ``val >> amt``, in little-endian order
        """

    @staticmethod
    @typing.overload
    def intRight(out: jpype.JArray[jpype.JInt], outBytes: typing.Union[jpype.JInt, int], val: jpype.JArray[jpype.JInt], amt: typing.Union[jpype.JLong, int]):
        """
        The implementation of :obj:`int_right <PcodeOp.INT_RIGHT>` on an mp-int with a JVM long shift
        amount.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`iushr <Opcodes.IUSHR>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.
        
        :param jpype.JArray[jpype.JInt] out: the array to receive the output, in little-endian order
        :param jpype.JInt or int outBytes: the actual size in bytes of the output operand
        :param jpype.JArray[jpype.JInt] val: the value as in ``val >> amt``, in little-endian order
        :param jpype.JLong or int amt: the amt as in ``val >> amt``
        """

    @staticmethod
    @typing.overload
    def intRight(out: jpype.JArray[jpype.JInt], outBytes: typing.Union[jpype.JInt, int], val: jpype.JArray[jpype.JInt], amt: typing.Union[jpype.JInt, int]):
        """
        The implementation of :obj:`int_right <PcodeOp.INT_RIGHT>` on an mp-int with a JVM int shift
        amount.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`iushr <Opcodes.IUSHR>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.
        
        :param jpype.JArray[jpype.JInt] out: the array to receive the output, in little-endian order
        :param jpype.JInt or int outBytes: the actual size in bytes of the output operand
        :param jpype.JArray[jpype.JInt] val: the value as in ``val >> amt``, in little-endian order
        :param jpype.JInt or int amt: the amt as in ``val >> amt``
        """

    @staticmethod
    @typing.overload
    def intRight(val: typing.Union[jpype.JLong, int], amt: jpype.JArray[jpype.JInt]) -> int:
        """
        The implementation of :obj:`int_right <PcodeOp.INT_RIGHT>` on a JVM long with an mp-int shift
        amount.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`iushr <Opcodes.IUSHR>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.
        
        :param jpype.JLong or int val: the value as in ``val >> amt``
        :param jpype.JArray[jpype.JInt] amt: the amt as in ``val >> amt``, in little-endian order
        :return: the value
        :rtype: int
        """

    @staticmethod
    @typing.overload
    def intRight(val: typing.Union[jpype.JLong, int], amt: typing.Union[jpype.JLong, int]) -> int:
        """
        The implementation of :obj:`int_right <PcodeOp.INT_RIGHT>` on JVM longs.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`iushr <Opcodes.IUSHR>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.
        
        :param jpype.JLong or int val: the value as in ``val >> amt``
        :param jpype.JLong or int amt: the amt as in ``val >> amt``
        :return: the value
        :rtype: int
        """

    @staticmethod
    @typing.overload
    def intRight(val: typing.Union[jpype.JLong, int], amt: typing.Union[jpype.JInt, int]) -> int:
        """
        The implementation of :obj:`int_right <PcodeOp.INT_RIGHT>` on JVM long with int amt.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`iushr <Opcodes.IUSHR>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.
        
        :param jpype.JLong or int val: the value as in ``val >> amt``
        :param jpype.JInt or int amt: the amt as in ``val >> amt``
        :return: the value
        :rtype: int
        """

    @staticmethod
    @typing.overload
    def intRight(val: typing.Union[jpype.JInt, int], amt: jpype.JArray[jpype.JInt]) -> int:
        """
        The implementation of :obj:`int_right <PcodeOp.INT_RIGHT>` on a JVM int with an mp-int shift
        amount.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`iushr <Opcodes.IUSHR>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.
        
        :param jpype.JInt or int val: the value as in ``val >> amt``
        :param jpype.JArray[jpype.JInt] amt: the amt as in ``val >> amt``, in little-endian order
        :return: the value
        :rtype: int
        """

    @staticmethod
    @typing.overload
    def intRight(val: typing.Union[jpype.JInt, int], amt: typing.Union[jpype.JLong, int]) -> int:
        """
        The implementation of :obj:`int_right <PcodeOp.INT_RIGHT>` on JVM int with long amt.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`iushr <Opcodes.IUSHR>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.
        
        :param jpype.JInt or int val: the value as in ``val >> amt``
        :param jpype.JLong or int amt: the amt as in ``val >> amt``
        :return: the value
        :rtype: int
        """

    @staticmethod
    @typing.overload
    def intRight(val: typing.Union[jpype.JInt, int], amt: typing.Union[jpype.JInt, int]) -> int:
        """
        The implementation of :obj:`int_right <PcodeOp.INT_RIGHT>` on JVM ints.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`iushr <Opcodes.IUSHR>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.
        
        :param jpype.JInt or int val: the value as in ``val >> amt``
        :param jpype.JInt or int amt: the amt as in ``val >> amt``
        :return: the value
        :rtype: int
        """

    @staticmethod
    @typing.overload
    def intSRight(out: jpype.JArray[jpype.JInt], outBytes: typing.Union[jpype.JInt, int], val: jpype.JArray[jpype.JInt], amt: jpype.JArray[jpype.JInt]):
        """
        The implementation of :obj:`int_sright <PcodeOp.INT_RIGHT>` on multi-precision ints.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`ishr <Opcodes.ISHR>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size fill the register with
        the sign bit.
        
        :param jpype.JArray[jpype.JInt] out: the array to receive the output, in little-endian order
        :param jpype.JInt or int outBytes: the actual size in bytes of the output operand
        :param jpype.JArray[jpype.JInt] val: the value as in ``val s>> amt``, in little-endian order
        :param jpype.JArray[jpype.JInt] amt: the amt as in ``val s>> amt``, in little-endian order
        """

    @staticmethod
    @typing.overload
    def intSRight(val: typing.Union[jpype.JLong, int], amt: typing.Union[jpype.JLong, int]) -> int:
        """
        The implementation of :obj:`int_sright <PcodeOp.INT_SRIGHT>` on JVM longs.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`ishr <Opcodes.ISHR>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size fill the register with
        the sign bit.
        
        :param jpype.JLong or int val: the value as in ``val s>> amt``
        :param jpype.JLong or int amt: the amt as in ``val s>> amt``
        :return: the value
        :rtype: int
        """

    @staticmethod
    @typing.overload
    def intSRight(val: typing.Union[jpype.JLong, int], amt: typing.Union[jpype.JInt, int]) -> int:
        """
        The implementation of :obj:`int_sright <PcodeOp.INT_SRIGHT>` on JVM long with int amt.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`ishr <Opcodes.ISHR>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size fill the register with
        the sign bit.
        
        :param jpype.JLong or int val: the value as in ``val s>> amt``
        :param jpype.JInt or int amt: the amt as in ``val s>> amt``
        :return: the value
        :rtype: int
        """

    @staticmethod
    @typing.overload
    def intSRight(val: typing.Union[jpype.JInt, int], amt: typing.Union[jpype.JLong, int]) -> int:
        """
        The implementation of :obj:`int_sright <PcodeOp.INT_SRIGHT>` on JVM int with long amt.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`ishr <Opcodes.ISHR>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size fill the register with
        the sign bit.
        
        :param jpype.JInt or int val: the value as in ``val s>> amt``
        :param jpype.JLong or int amt: the amt as in ``val s>> amt``
        :return: the value
        :rtype: int
        """

    @staticmethod
    @typing.overload
    def intSRight(val: typing.Union[jpype.JInt, int], amt: typing.Union[jpype.JInt, int]) -> int:
        """
        The implementation of :obj:`int_sright <PcodeOp.INT_SRIGHT>` on JVM ints.
         
         
        
        The semantics here are subtly different than the JVM's :obj:`ishr <Opcodes.ISHR>`: 1) The
        amount must be treated as unsigned. 2) Shifts in excess of val's size fill the register with
        the sign bit.
        
        :param jpype.JInt or int val: the value as in ``val s>> amt``
        :param jpype.JInt or int amt: the amt as in ``val s>> amt``
        :return: the value
        :rtype: int
        """

    def invokeUserop(self, userop: ghidra.pcode.exec_.PcodeUseropLibrary.PcodeUseropDefinition[jpype.JArray[jpype.JByte]], output: ghidra.program.model.pcode.Varnode, inputs: jpype.JArray[ghidra.program.model.pcode.Varnode]):
        """
        Invoke the given userop on the bound thread with the given operands
         
         
        
        This is invoked by generated code in :meth:`JitCompiledPassage.run(int) <JitCompiledPassage.run>` to invoke a userop
        via the Standard strategy.
        
        :param ghidra.pcode.exec_.PcodeUseropLibrary.PcodeUseropDefinition[jpype.JArray[jpype.JByte]] userop: the userop definition
        :param ghidra.program.model.pcode.Varnode output: an optional output operand
        :param jpype.JArray[ghidra.program.model.pcode.Varnode] inputs: the input operands
        
        .. seealso::
        
            | :obj:`JitDataFlowUseropLibrary`
        
            | :obj:`PcodeUseropDefinition.execute(PcodeExecutor, PcodeUseropLibrary, Varnode, List)`
        """

    @staticmethod
    def mpIntDivide(out: jpype.JArray[jpype.JInt], inL: jpype.JArray[jpype.JInt], inR: jpype.JArray[jpype.JInt]):
        """
        The implementation of :obj:`PcodeOp.INT_DIV` on mp-ints.
         
        
        All arrays are in little-endian order. While this directly implements
        :obj:`PcodeOp.INT_DIV`, it is also used for :obj:`PcodeOp.INT_REM`,
        :obj:`PcodeOp.INT_SDIV`, and :obj:`PcodeOp.INT_SREM`.
        
        :param jpype.JArray[jpype.JInt] out: the array allocated to receive the quotient
        :param jpype.JArray[jpype.JInt] inL: the array of dividend input legs, over-provisioned by 1, which will also receive
                    the remainder
        :param jpype.JArray[jpype.JInt] inR: the array of divisor input legs
        """

    @staticmethod
    def mpIntMultiply(out: jpype.JArray[jpype.JInt], inL: jpype.JArray[jpype.JInt], inR: jpype.JArray[jpype.JInt]):
        """
        The implementation of :obj:`PcodeOp.INT_MULT` on mp-ints.
         
        
        All arrays are in little-endian order
        
        :param jpype.JArray[jpype.JInt] out: the array allocated to receive the output
        :param jpype.JArray[jpype.JInt] inL: the array of left input legs
        :param jpype.JArray[jpype.JInt] inR: the array of right input legs
        """

    @staticmethod
    def mpIntSignedDivide(out: jpype.JArray[jpype.JInt], inL: jpype.JArray[jpype.JInt], inR: jpype.JArray[jpype.JInt]):
        """
        The implementation of :obj:`PcodeOp.INT_SDIV` on mp-ints.
         
        
        All arrays are in little-endian order. While this directly implements
        :obj:`PcodeOp.INT_SDIV`, it is also used for :obj:`PcodeOp.INT_SREM`.
        
        :param jpype.JArray[jpype.JInt] out: the array allocated to receive the quotient
        :param jpype.JArray[jpype.JInt] inL: the array of dividend input legs, over-provisioned by 1, which will also receive
                    the remainder
        :param jpype.JArray[jpype.JInt] inR: the array of divisor input legs
        """

    @staticmethod
    def mpToString(legs: jpype.JArray[jpype.JInt]) -> str:
        ...

    @staticmethod
    def readInt1(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int1 <IntJitType.I1>` from the given array at the given offset
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM int
        :rtype: int
        """

    @staticmethod
    def readIntBE2(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int2 <IntJitType.I2>` from the given array at the given offset in big endian
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM int
        :rtype: int
        """

    @staticmethod
    def readIntBE3(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int3 <IntJitType.I3>` from the given array at the given offset in big endian
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM int
        :rtype: int
        """

    @staticmethod
    def readIntBE4(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int4 <IntJitType.I4>` from the given array at the given offset in big endian
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM int
        :rtype: int
        """

    @staticmethod
    def readIntLE2(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int2 <IntJitType.I2>` from the given array at the given offset in little endian
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM int
        :rtype: int
        """

    @staticmethod
    def readIntLE3(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int3 <IntJitType.I3>` from the given array at the given offset in little endian
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM int
        :rtype: int
        """

    @staticmethod
    def readIntLE4(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int4 <IntJitType.I4>` from the given array at the given offset in little endian
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM int
        :rtype: int
        """

    @staticmethod
    def readLong1(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int1 <IntJitType.I1>` from the given array at the given offset.
         
         
        
        This is invoked by dynamically generated code. While an :obj:`int1 <IntJitType.I1>` can fit in
        a JVM int, this method is used when reading 1 byte of a :obj:`larger int <LongJitType>` that
        spans a page boundary.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM long
        :rtype: int
        """

    @staticmethod
    def readLongBE2(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int2 <IntJitType.I2>` from the given array at the given offset in big endian.
         
         
        
        This is invoked by dynamically generated code. While an :obj:`int2 <IntJitType.I2>` can fit in
        a JVM int, this method is used when reading 2 bytes of a :obj:`larger int <LongJitType>` that
        spans a page boundary.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM long
        :rtype: int
        """

    @staticmethod
    def readLongBE3(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int3 <IntJitType.I3>` from the given array at the given offset in big endian.
         
         
        
        This is invoked by dynamically generated code. While an :obj:`int3 <IntJitType.I3>` can fit in
        a JVM int, this method is used when reading 3 bytes of a :obj:`larger int <LongJitType>` that
        spans a page boundary.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM long
        :rtype: int
        """

    @staticmethod
    def readLongBE4(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int4 <IntJitType.I4>` from the given array at the given offset in big endian.
         
         
        
        This is invoked by dynamically generated code. While an :obj:`int4 <IntJitType.I4>` can fit in
        a JVM int, this method is used when reading 4 bytes of a :obj:`larger int <LongJitType>` that
        spans a page boundary.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM long
        :rtype: int
        """

    @staticmethod
    def readLongBE5(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int5 <LongJitType.I5>` from the given array at the given offset in big endian.
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM long
        :rtype: int
        """

    @staticmethod
    def readLongBE6(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int6 <LongJitType.I6>` from the given array at the given offset in big endian.
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM long
        :rtype: int
        """

    @staticmethod
    def readLongBE7(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int7 <LongJitType.I7>` from the given array at the given offset in big endian.
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM long
        :rtype: int
        """

    @staticmethod
    def readLongBE8(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int8 <LongJitType.I8>` from the given array at the given offset in big endian.
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM long
        :rtype: int
        """

    @staticmethod
    def readLongLE2(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int2 <IntJitType.I2>` from the given array at the given offset in little endian.
         
         
        
        This is invoked by dynamically generated code. While an :obj:`int2 <IntJitType.I2>` can fit in
        a JVM int, this method is used when reading 2 bytes of a :obj:`larger int <LongJitType>` that
        spans a page boundary.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM long
        :rtype: int
        """

    @staticmethod
    def readLongLE3(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int3 <IntJitType.I3>` from the given array at the given offset in little endian.
         
         
        
        This is invoked by dynamically generated code. While an :obj:`int3 <IntJitType.I3>` can fit in
        a JVM int, this method is used when reading 3 bytes of a :obj:`larger int <LongJitType>` that
        spans a page boundary.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM long
        :rtype: int
        """

    @staticmethod
    def readLongLE4(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int4 <IntJitType.I4>` from the given array at the given offset in little endian.
         
         
        
        This is invoked by dynamically generated code. While an :obj:`int4 <IntJitType.I4>` can fit in
        a JVM int, this method is used when reading 4 bytes of a :obj:`larger int <LongJitType>` that
        spans a page boundary.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM long
        :rtype: int
        """

    @staticmethod
    def readLongLE5(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int5 <LongJitType.I5>` from the given array at the given offset in little
        endian.
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM long
        :rtype: int
        """

    @staticmethod
    def readLongLE6(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int6 <LongJitType.I6>` from the given array at the given offset in little
        endian.
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM long
        :rtype: int
        """

    @staticmethod
    def readLongLE7(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int7 <LongJitType.I7>` from the given array at the given offset in little
        endian.
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM long
        :rtype: int
        """

    @staticmethod
    def readLongLE8(arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]) -> int:
        """
        Read an :obj:`int8 <LongJitType.I8>` from the given array at the given offset in little
        endian.
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        :return: the value as a JVM long
        :rtype: int
        """

    def run(self, blockId: typing.Union[jpype.JInt, int]) -> JitCompiledPassage.EntryPoint:
        """
        Run the compiled passage of code
         
         
        
        Except during testing, this is ordinarily called by :meth:`EntryPoint.run() <EntryPoint.run>`. Too see how
        this fits into the overall JIT-accelerated execution loop, see :obj:`JitPcodeThread`. All
        implementations of this interface are generated dynamically. To understand that process and
        how the entry points are generated and exported, see :obj:`JitCompiler`.
         
         
        
        This method may or may not return a chained entry point. Each passage caches a chained entry
        point for each of its direct branch targets. This averts a map lookup on subsequent exits via
        the same branch. If a chained entry point is returned, the thread ought to execute it
        immediately, unless it has become suspended. Otherwise, the thread must repeat its execution
        loop at the **Fetch** step.
        
        :param jpype.JInt or int blockId: an index identifying the target address and contextreg where execution should
                    enter
        :return: a chained entry point, or ``null``
        :rtype: JitCompiledPassage.EntryPoint
        """

    @staticmethod
    def sBorrowIntRaw(a: typing.Union[jpype.JInt, int], b: typing.Union[jpype.JInt, int]) -> int:
        """
        The implementation of :obj:`int_sborrow <PcodeOp.INT_SBORROW>` on JVM ints.
         
         
        
        This actually computes all the borrow bits. To extract a specific one, the generator should
        emit a shift and mask.
        
        :param jpype.JInt or int a: the first operand as in ``a - b``
        :param jpype.JInt or int b: the second operand as in ``a - b``
        :return: the register of borrow bits
        :rtype: int
        """

    @staticmethod
    def sBorrowLongRaw(a: typing.Union[jpype.JLong, int], b: typing.Union[jpype.JLong, int]) -> int:
        """
        The implementation of :obj:`int_sborrow <PcodeOp.INT_SBORROW>` on JVM longs.
         
         
        
        This actually computes all the borrow bits. To extract a specific one, the generator should
        emit a shift and mask.
        
        :param jpype.JLong or int a: the first operand as in ``a - b``
        :param jpype.JLong or int b: the second operand as in ``a - b``
        :return: the register of borrow bits
        :rtype: int
        """

    @staticmethod
    def sBorrowMpInt(a: jpype.JArray[jpype.JInt], b: jpype.JArray[jpype.JInt], shift: typing.Union[jpype.JInt, int]) -> int:
        """
        The implementation of :obj:`int_sborrow <PcodeOp.INT_SCARRY>` on multi-precision ints.
        
        :param jpype.JArray[jpype.JInt] a: the first operand as in ``a - b``
        :param jpype.JArray[jpype.JInt] b: the second operand as in ``a - b``
        :param jpype.JInt or int shift: one less than the number of bits in each most-significant leg, i.e., the number
                    of bits to shift right such that the most-significant bit of the most-significant
                    leg becomes the least-significant bit of the *most*-significant leg.
        :return: the one carry bit
        :rtype: int
        """

    @staticmethod
    def sCarryIntRaw(a: typing.Union[jpype.JInt, int], b: typing.Union[jpype.JInt, int]) -> int:
        """
        The implementation of :obj:`int_scarry <PcodeOp.INT_SCARRY>` on JVM ints.
         
         
        
        This actually computes all the carry bits. To extract a specific one, the generator should
        emit a shift and mask.
        
        :param jpype.JInt or int a: the first operand as in ``a + b``
        :param jpype.JInt or int b: the second operand as in ``a + b``
        :return: the register of carry bits
        :rtype: int
        """

    @staticmethod
    def sCarryLongRaw(a: typing.Union[jpype.JLong, int], b: typing.Union[jpype.JLong, int]) -> int:
        """
        The implementation of :obj:`int_scarry <PcodeOp.INT_SCARRY>` on JVM longs.
         
         
        
        This actually computes all the carry bits. To extract a specific one, the generator should
        emit a shift and mask.
        
        :param jpype.JLong or int a: the first operand as in ``a + b``
        :param jpype.JLong or int b: the second operand as in ``a + b``
        :return: the register of carry bits
        :rtype: int
        """

    @staticmethod
    def sCarryMpInt(a: jpype.JArray[jpype.JInt], b: jpype.JArray[jpype.JInt], shift: typing.Union[jpype.JInt, int]) -> int:
        """
        The implementation of :obj:`int_scarry <PcodeOp.INT_SCARRY>` on multi-precision ints.
        
        :param jpype.JArray[jpype.JInt] a: the first operand as in ``a + b``
        :param jpype.JArray[jpype.JInt] b: the second operand as in ``a + b``
        :param jpype.JInt or int shift: one less than the number of bits in each most-significant leg, i.e., the number
                    of bits to shift right such that the most-significant bit of the most-significant
                    leg becomes the least-significant bit of the *most*-significant leg.
        :return: the one carry bit
        :rtype: int
        """

    def setCounterAndContext(self, counter: typing.Union[jpype.JLong, int], context: ghidra.program.model.lang.RegisterValue):
        """
        Set the bound thread's program counter and decode context, without writing it to the machine
        state.
         
         
        
        This is called during retirement upon entering a hazard. This just converts things to the
        right type and invokes :meth:`JitPcodeThread.setCounterAndContext(Address, RegisterValue) <JitPcodeThread.setCounterAndContext>`.
        
        :param jpype.JLong or int counter: the offset of the next instruction to execute
        :param ghidra.program.model.lang.RegisterValue context: the decode context for the next instruction
        """

    def thread(self) -> ghidra.pcode.emu.jit.JitPcodeThread:
        """
        Get this instance's bound thread.
         
         
        
        The generator implements a standard getter. This is frequently used by other default methods
        of this interface, which are in turn invoked by generated code.
        
        :return: the thread
        :rtype: ghidra.pcode.emu.jit.JitPcodeThread
        """

    def writeCounterAndContext(self, counter: typing.Union[jpype.JLong, int], context: ghidra.program.model.lang.RegisterValue):
        """
        Set the bound thread's program counter and decode context.
         
         
        
        This is called during retirement, i.e., upon exiting a passage. This just converts things to
        the right type and invokes
        :meth:`JitPcodeThread.writeCounterAndContext(Address, RegisterValue) <JitPcodeThread.writeCounterAndContext>`.
        
        :param jpype.JLong or int counter: the offset of the next instruction to execute
        :param ghidra.program.model.lang.RegisterValue context: the decode context for the next instruction
        """

    @staticmethod
    def writeInt1(value: typing.Union[jpype.JInt, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int1 <IntJitType.I1>` into the given array at the given offset
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JInt or int value: the value as a JVM int
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeIntBE2(value: typing.Union[jpype.JInt, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int2 <IntJitType.I2>` into the given array at the given offset in big endian
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JInt or int value: the value as a JVM int
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeIntBE3(value: typing.Union[jpype.JInt, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int3 <IntJitType.I3>` into the given array at the given offset in big endian
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JInt or int value: the value as a JVM int
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeIntBE4(value: typing.Union[jpype.JInt, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int4 <IntJitType.I4>` into the given array at the given offset in big endian
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JInt or int value: the value as a JVM int
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeIntLE2(value: typing.Union[jpype.JInt, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int2 <IntJitType.I2>` into the given array at the given offset in litte endian
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JInt or int value: the value as a JVM int
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeIntLE3(value: typing.Union[jpype.JInt, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int3 <IntJitType.I3>` into the given array at the given offset in litte endian
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JInt or int value: the value as a JVM int
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeIntLE4(value: typing.Union[jpype.JInt, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int4 <IntJitType.I4>` into the given array at the given offset in litte endian
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JInt or int value: the value as a JVM int
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeLong1(value: typing.Union[jpype.JLong, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int1 <IntJitType.I1>` into the given array at the given offset.
         
         
        
        This is invoked by dynamically generated code. While an :obj:`int1 <IntJitType.I1>` can fit in
        a JVM int, this method is used when writing 1 byte of a :obj:`larger int <LongJitType>` that
        spans a page boundary.
        
        :param jpype.JLong or int value: the value as a JVM long
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeLongBE2(value: typing.Union[jpype.JLong, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int2 <IntJitType.I2>` into the given array at the given offset in big endian.
         
         
        
        This is invoked by dynamically generated code. While an :obj:`int2 <IntJitType.I2>` can fit in
        a JVM int, this method is used when writing 2 bytes of a :obj:`larger int <LongJitType>` that
        spans a page boundary.
        
        :param jpype.JLong or int value: the value as a JVM long
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeLongBE3(value: typing.Union[jpype.JLong, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int3 <IntJitType.I3>` into the given array at the given offset in big endian.
         
         
        
        This is invoked by dynamically generated code. While an :obj:`int3 <IntJitType.I3>` can fit in
        a JVM int, this method is used when writing 3 bytes of a :obj:`larger int <LongJitType>` that
        spans a page boundary.
        
        :param jpype.JLong or int value: the value as a JVM long
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeLongBE4(value: typing.Union[jpype.JLong, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int4 <IntJitType.I4>` into the given array at the given offset in big endian.
         
         
        
        This is invoked by dynamically generated code. While an :obj:`int4 <IntJitType.I4>` can fit in
        a JVM int, this method is used when writing 4 bytes of a :obj:`larger int <LongJitType>` that
        spans a page boundary.
        
        :param jpype.JLong or int value: the value as a JVM long
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeLongBE5(value: typing.Union[jpype.JLong, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int5 <LongJitType.I5>` into the given array at the given offset in big endian.
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JLong or int value: the value as a JVM long
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeLongBE6(value: typing.Union[jpype.JLong, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int6 <LongJitType.I6>` into the given array at the given offset in big endian.
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JLong or int value: the value as a JVM long
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeLongBE7(value: typing.Union[jpype.JLong, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int7 <LongJitType.I7>` into the given array at the given offset in big endian.
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JLong or int value: the value as a JVM long
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeLongBE8(value: typing.Union[jpype.JLong, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int8 <LongJitType.I8>` into the given array at the given offset in big endian.
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JLong or int value: the value as a JVM long
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeLongLE2(value: typing.Union[jpype.JLong, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int2 <IntJitType.I2>` into the given array at the given offset in little
        endian.
         
         
        
        This is invoked by dynamically generated code. While an :obj:`int2 <IntJitType.I2>` can fit in
        a JVM int, this method is used when writing 2 bytes of a :obj:`larger int <LongJitType>` that
        spans a page boundary.
        
        :param jpype.JLong or int value: the value as a JVM long
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeLongLE3(value: typing.Union[jpype.JLong, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int3 <IntJitType.I3>` into the given array at the given offset in little
        endian.
         
         
        
        This is invoked by dynamically generated code. While an :obj:`int3 <IntJitType.I3>` can fit in
        a JVM int, this method is used when writing 3 bytes of a :obj:`larger int <LongJitType>` that
        spans a page boundary.
        
        :param jpype.JLong or int value: the value as a JVM long
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeLongLE4(value: typing.Union[jpype.JLong, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int4 <IntJitType.I4>` into the given array at the given offset in little
        endian.
         
         
        
        This is invoked by dynamically generated code. While an :obj:`int4 <IntJitType.I4>` can fit in
        a JVM int, this method is used when writing 4 bytes of a :obj:`larger int <LongJitType>` that
        spans a page boundary.
        
        :param jpype.JLong or int value: the value as a JVM long
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeLongLE5(value: typing.Union[jpype.JLong, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int5 <LongJitType.I5>` into the given array at the given offset in little
        endian.
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JLong or int value: the value as a JVM long
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeLongLE6(value: typing.Union[jpype.JLong, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int6 <LongJitType.I6>` into the given array at the given offset in little
        endian.
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JLong or int value: the value as a JVM long
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeLongLE7(value: typing.Union[jpype.JLong, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int7 <LongJitType.I7>` into the given array at the given offset in little
        endian.
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JLong or int value: the value as a JVM long
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @staticmethod
    def writeLongLE8(value: typing.Union[jpype.JLong, int], arr: jpype.JArray[jpype.JByte], offset: typing.Union[jpype.JInt, int]):
        """
        Write an :obj:`int8 <LongJitType.I8>` into the given array at the given offset in little
        endian.
         
         
        
        This is invoked by dynamically generated code.
        
        :param jpype.JLong or int value: the value as a JVM long
        :param jpype.JArray[jpype.JByte] arr: the array
        :param jpype.JInt or int offset: the offset
        """

    @property
    def useropDefinition(self) -> ghidra.pcode.exec_.PcodeUseropLibrary.PcodeUseropDefinition[jpype.JArray[jpype.JByte]]:
        ...



__all__ = ["JitCompiledPassageClass", "JitCompiledPassage"]
