Package ghidra.pcode.emu.jit.gen.tgt

# Interface JitCompiledPassage

public interface JitCompiledPassage
The interface implemented by classfiles generated by `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.

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Interface
  Description
  `static final record`
  `JitCompiledPassage.EntryPoint`
  An entry point into a translated passage
  `static class`
  `JitCompiledPassage.EntryPointPrototype`
  An entry point that is not yet bound to a specific thread
  `static class`
  `JitCompiledPassage.ExitSlot`
  A cache slot for a chained entry point
  `static enum`
  `JitCompiledPassage.MpDivPrivate`
  `static enum`
  `JitCompiledPassage.MpShiftPrivate`

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `static final long`
  `MASK_I2UL`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static long`
  `conv2IntToLong(int msl, int lsl)`
  Convert two integers into a single long
  `default void`
  `count(int instructions, int trailingOps)`
  Invoke `JitPcodeThread.count(int, int)` for the bound thread
  `static RegisterValue`
  `createContext(Language language, String value)`
  Construct a contextreg value from the given language and hex value
  `default DecodePcodeExecutionException`
  `createDecodeError(String message, long counter)`
  Construct an exception when attempting to execute an "instruction" that could not be decoded.
  `default JitCompiledPassage.ExitSlot`
  `createExitSlot(long target, RegisterValue ctx)`
  Construct an exit slot for the given branch target
  `static Varnode`
  `createVarnode(AddressFactory factory, String space, long offset, int size)`
  Construct a varnode
  `static JitCompiledPassage.EntryPoint`
  `getChained(JitCompiledPassage.ExitSlot slot)`
  Get the chained entry point for the given exit point's target
  `static Language`
  `getLanguage(String languageID)`
  Get the language for the given string language ID
  `default PcodeUseropLibrary.PcodeUseropDefinition<byte[]>`
  `getUseropDefinition(String name)`
  Retrieve a userop definition from the bound thread.
  `static void`
  `intLeft(int[] out, int outBytes, int[] val, int amt)`
  The implementation of `int_left` on an mp-int with a JVM int shift amount.
  `static void`
  `intLeft(int[] out, int outBytes, int[] val, int[] amt)`
  The implementation of `int_left` on multi-precision ints.
  `static void`
  `intLeft(int[] out, int outBytes, int[] val, long amt)`
  The implementation of `int_left` on an mp-int with a JVM long shift amount.
  `static int`
  `intLeft(int val, int amt)`
  The implementation of `int_left` on JVM ints.
  `static long`
  `intLeft(int val, int[] amt)`
  The implementation of `int_left` on a JVM int with an mp-int shift amount.
  `static int`
  `intLeft(int val, long amt)`
  The implementation of `int_left` on JVM int with long amt.
  `static long`
  `intLeft(long val, int amt)`
  The implementation of `int_left` on JVM long with int amt.
  `static long`
  `intLeft(long val, int[] amt)`
  The implementation of `int_left` on a JVM long with an mp-int shift amount.
  `static long`
  `intLeft(long val, long amt)`
  The implementation of `int_left` on JVM longs.
  `static void`
  `intRight(int[] out, int outBytes, int[] val, int amt)`
  The implementation of `int_right` on an mp-int with a JVM int shift amount.
  `static void`
  `intRight(int[] out, int outBytes, int[] val, int[] amt)`
  The implementation of `int_right` on multi-precision ints.
  `static void`
  `intRight(int[] out, int outBytes, int[] val, long amt)`
  The implementation of `int_right` on an mp-int with a JVM long shift amount.
  `static int`
  `intRight(int val, int amt)`
  The implementation of `int_right` on JVM ints.
  `static long`
  `intRight(int val, int[] amt)`
  The implementation of `int_right` on a JVM int with an mp-int shift amount.
  `static int`
  `intRight(int val, long amt)`
  The implementation of `int_right` on JVM int with long amt.
  `static long`
  `intRight(long val, int amt)`
  The implementation of `int_right` on JVM long with int amt.
  `static long`
  `intRight(long val, int[] amt)`
  The implementation of `int_right` on a JVM long with an mp-int shift amount.
  `static long`
  `intRight(long val, long amt)`
  The implementation of `int_right` on JVM longs.
  `static void`
  `intSRight(int[] out, int outBytes, int[] val, int[] amt)`
  The implementation of `int_sright` on multi-precision ints.
  `static int`
  `intSRight(int val, int amt)`
  The implementation of `int_sright` on JVM ints.
  `static int`
  `intSRight(int val, long amt)`
  The implementation of `int_sright` on JVM int with long amt.
  `static long`
  `intSRight(long val, int amt)`
  The implementation of `int_sright` on JVM long with int amt.
  `static long`
  `intSRight(long val, long amt)`
  The implementation of `int_sright` on JVM longs.
  `default void`
  `invokeUserop(PcodeUseropLibrary.PcodeUseropDefinition<byte[]> userop, Varnode output, Varnode[] inputs)`
  Invoke the given userop on the bound thread with the given operands
  `static void`
  `mpIntDivide(int[] out, int[] inL, int[] inR)`
  The implementation of `PcodeOp.INT_DIV` on mp-ints.
  `static void`
  `mpIntMultiply(int[] out, int[] inL, int[] inR)`
  The implementation of `PcodeOp.INT_MULT` on mp-ints.
  `static void`
  `mpIntSignedDivide(int[] out, int[] inL, int[] inR)`
  The implementation of `PcodeOp.INT_SDIV` on mp-ints.
  `static String`
  `mpToString(int[] legs)`
  `static int`
  `readInt1(byte[] arr, int offset)`
  Read an `int1` from the given array at the given offset
  `static int`
  `readIntBE2(byte[] arr, int offset)`
  Read an `int2` from the given array at the given offset in big endian
  `static int`
  `readIntBE3(byte[] arr, int offset)`
  Read an `int3` from the given array at the given offset in big endian
  `static int`
  `readIntBE4(byte[] arr, int offset)`
  Read an `int4` from the given array at the given offset in big endian
  `static int`
  `readIntLE2(byte[] arr, int offset)`
  Read an `int2` from the given array at the given offset in little endian
  `static int`
  `readIntLE3(byte[] arr, int offset)`
  Read an `int3` from the given array at the given offset in little endian
  `static int`
  `readIntLE4(byte[] arr, int offset)`
  Read an `int4` from the given array at the given offset in little endian
  `static long`
  `readLong1(byte[] arr, int offset)`
  Read an `int1` from the given array at the given offset.
  `static long`
  `readLongBE2(byte[] arr, int offset)`
  Read an `int2` from the given array at the given offset in big endian.
  `static long`
  `readLongBE3(byte[] arr, int offset)`
  Read an `int3` from the given array at the given offset in big endian.
  `static long`
  `readLongBE4(byte[] arr, int offset)`
  Read an `int4` from the given array at the given offset in big endian.
  `static long`
  `readLongBE5(byte[] arr, int offset)`
  Read an `int5` from the given array at the given offset in big endian.
  `static long`
  `readLongBE6(byte[] arr, int offset)`
  Read an `int6` from the given array at the given offset in big endian.
  `static long`
  `readLongBE7(byte[] arr, int offset)`
  Read an `int7` from the given array at the given offset in big endian.
  `static long`
  `readLongBE8(byte[] arr, int offset)`
  Read an `int8` from the given array at the given offset in big endian.
  `static long`
  `readLongLE2(byte[] arr, int offset)`
  Read an `int2` from the given array at the given offset in little endian.
  `static long`
  `readLongLE3(byte[] arr, int offset)`
  Read an `int3` from the given array at the given offset in little endian.
  `static long`
  `readLongLE4(byte[] arr, int offset)`
  Read an `int4` from the given array at the given offset in little endian.
  `static long`
  `readLongLE5(byte[] arr, int offset)`
  Read an `int5` from the given array at the given offset in little endian.
  `static long`
  `readLongLE6(byte[] arr, int offset)`
  Read an `int6` from the given array at the given offset in little endian.
  `static long`
  `readLongLE7(byte[] arr, int offset)`
  Read an `int7` from the given array at the given offset in little endian.
  `static long`
  `readLongLE8(byte[] arr, int offset)`
  Read an `int8` from the given array at the given offset in little endian.
  `JitCompiledPassage.EntryPoint`
  `run(int blockId)`
  Run the compiled passage of code
  `static int`
  `sBorrowIntRaw(int a, int b)`
  The implementation of `int_sborrow` on JVM ints.
  `static long`
  `sBorrowLongRaw(long a, long b)`
  The implementation of `int_sborrow` on JVM longs.
  `static int`
  `sBorrowMpInt(int[] a, int[] b, int shift)`
  The implementation of `int_sborrow` on multi-precision ints.
  `static int`
  `sCarryIntRaw(int a, int b)`
  The implementation of `int_scarry` on JVM ints.
  `static long`
  `sCarryLongRaw(long a, long b)`
  The implementation of `int_scarry` on JVM longs.
  `static int`
  `sCarryMpInt(int[] a, int[] b, int shift)`
  The implementation of `int_scarry` on multi-precision ints.
  `default void`
  `setCounterAndContext(long counter, RegisterValue context)`
  Set the bound thread's program counter and decode context, without writing it to the machine state.
  `JitPcodeThread`
  `thread()`
  Get this instance's bound thread.
  `default void`
  `writeCounterAndContext(long counter, RegisterValue context)`
  Set the bound thread's program counter and decode context.
  `static void`
  `writeInt1(int value, byte[] arr, int offset)`
  Write an `int1` into the given array at the given offset
  `static void`
  `writeIntBE2(int value, byte[] arr, int offset)`
  Write an `int2` into the given array at the given offset in big endian
  `static void`
  `writeIntBE3(int value, byte[] arr, int offset)`
  Write an `int3` into the given array at the given offset in big endian
  `static void`
  `writeIntBE4(int value, byte[] arr, int offset)`
  Write an `int4` into the given array at the given offset in big endian
  `static void`
  `writeIntLE2(int value, byte[] arr, int offset)`
  Write an `int2` into the given array at the given offset in litte endian
  `static void`
  `writeIntLE3(int value, byte[] arr, int offset)`
  Write an `int3` into the given array at the given offset in litte endian
  `static void`
  `writeIntLE4(int value, byte[] arr, int offset)`
  Write an `int4` into the given array at the given offset in litte endian
  `static void`
  `writeLong1(long value, byte[] arr, int offset)`
  Write an `int1` into the given array at the given offset.
  `static void`
  `writeLongBE2(long value, byte[] arr, int offset)`
  Write an `int2` into the given array at the given offset in big endian.
  `static void`
  `writeLongBE3(long value, byte[] arr, int offset)`
  Write an `int3` into the given array at the given offset in big endian.
  `static void`
  `writeLongBE4(long value, byte[] arr, int offset)`
  Write an `int4` into the given array at the given offset in big endian.
  `static void`
  `writeLongBE5(long value, byte[] arr, int offset)`
  Write an `int5` into the given array at the given offset in big endian.
  `static void`
  `writeLongBE6(long value, byte[] arr, int offset)`
  Write an `int6` into the given array at the given offset in big endian.
  `static void`
  `writeLongBE7(long value, byte[] arr, int offset)`
  Write an `int7` into the given array at the given offset in big endian.
  `static void`
  `writeLongBE8(long value, byte[] arr, int offset)`
  Write an `int8` into the given array at the given offset in big endian.
  `static void`
  `writeLongLE2(long value, byte[] arr, int offset)`
  Write an `int2` into the given array at the given offset in little endian.
  `static void`
  `writeLongLE3(long value, byte[] arr, int offset)`
  Write an `int3` into the given array at the given offset in little endian.
  `static void`
  `writeLongLE4(long value, byte[] arr, int offset)`
  Write an `int4` into the given array at the given offset in little endian.
  `static void`
  `writeLongLE5(long value, byte[] arr, int offset)`
  Write an `int5` into the given array at the given offset in little endian.
  `static void`
  `writeLongLE6(long value, byte[] arr, int offset)`
  Write an `int6` into the given array at the given offset in little endian.
  `static void`
  `writeLongLE7(long value, byte[] arr, int offset)`
  Write an `int7` into the given array at the given offset in little endian.
  `static void`
  `writeLongLE8(long value, byte[] arr, int offset)`
  Write an `int8` into the given array at the given offset in little endian.

- ## Field Details

  - ### MASK_I2UL

    static final long MASK_I2UL
    See Also:
      - Constant Field Values

- ## Method Details

  - ### run

    JitCompiledPassage.EntryPoint run(int blockId)
    Run the compiled passage of code

    Except during testing, this is ordinarily called by `JitCompiledPassage.EntryPoint.run()`. Too see how this fits into the overall JIT-accelerated execution loop, see `JitPcodeThread`. All implementations of this interface are generated dynamically. To understand that process and how the entry points are generated and exported, see `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.

    Parameters:
      `blockId` - an index identifying the target address and contextreg where execution should enter
    Returns:
      a chained entry point, or `null`

  - ### readInt1

    static int readInt1(byte[] arr, int offset)
    Read an `int1` from the given array at the given offset

    This is invoked by dynamically generated code.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM int

  - ### readIntBE2

    static int readIntBE2(byte[] arr, int offset)
    Read an `int2` from the given array at the given offset in big endian

    This is invoked by dynamically generated code.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM int

  - ### readIntBE3

    static int readIntBE3(byte[] arr, int offset)
    Read an `int3` from the given array at the given offset in big endian

    This is invoked by dynamically generated code.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM int

  - ### readIntBE4

    static int readIntBE4(byte[] arr, int offset)
    Read an `int4` from the given array at the given offset in big endian

    This is invoked by dynamically generated code.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM int

  - ### readIntLE2

    static int readIntLE2(byte[] arr, int offset)
    Read an `int2` from the given array at the given offset in little endian

    This is invoked by dynamically generated code.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM int

  - ### readIntLE3

    static int readIntLE3(byte[] arr, int offset)
    Read an `int3` from the given array at the given offset in little endian

    This is invoked by dynamically generated code.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM int

  - ### readIntLE4

    static int readIntLE4(byte[] arr, int offset)
    Read an `int4` from the given array at the given offset in little endian

    This is invoked by dynamically generated code.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM int

  - ### writeInt1

    static void writeInt1(int value, byte[] arr, int offset)
    Write an `int1` into the given array at the given offset

    This is invoked by dynamically generated code.

    Parameters:
      `value` - the value as a JVM int
      `arr` - the array
      `offset` - the offset

  - ### writeIntBE2

    static void writeIntBE2(int value, byte[] arr, int offset)
    Write an `int2` into the given array at the given offset in big endian

    This is invoked by dynamically generated code.

    Parameters:
      `value` - the value as a JVM int
      `arr` - the array
      `offset` - the offset

  - ### writeIntBE3

    static void writeIntBE3(int value, byte[] arr, int offset)
    Write an `int3` into the given array at the given offset in big endian

    This is invoked by dynamically generated code.

    Parameters:
      `value` - the value as a JVM int
      `arr` - the array
      `offset` - the offset

  - ### writeIntBE4

    static void writeIntBE4(int value, byte[] arr, int offset)
    Write an `int4` into the given array at the given offset in big endian

    This is invoked by dynamically generated code.

    Parameters:
      `value` - the value as a JVM int
      `arr` - the array
      `offset` - the offset

  - ### writeIntLE2

    static void writeIntLE2(int value, byte[] arr, int offset)
    Write an `int2` into the given array at the given offset in litte endian

    This is invoked by dynamically generated code.

    Parameters:
      `value` - the value as a JVM int
      `arr` - the array
      `offset` - the offset

  - ### writeIntLE3

    static void writeIntLE3(int value, byte[] arr, int offset)
    Write an `int3` into the given array at the given offset in litte endian

    This is invoked by dynamically generated code.

    Parameters:
      `value` - the value as a JVM int
      `arr` - the array
      `offset` - the offset

  - ### writeIntLE4

    static void writeIntLE4(int value, byte[] arr, int offset)
    Write an `int4` into the given array at the given offset in litte endian

    This is invoked by dynamically generated code.

    Parameters:
      `value` - the value as a JVM int
      `arr` - the array
      `offset` - the offset

  - ### readLong1

    static long readLong1(byte[] arr, int offset)
    Read an `int1` from the given array at the given offset.

    This is invoked by dynamically generated code. While an `int1` can fit in a JVM int, this method is used when reading 1 byte of a `larger int` that spans a page boundary.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM long

  - ### readLongBE2

    static long readLongBE2(byte[] arr, int offset)
    Read an `int2` from the given array at the given offset in big endian.

    This is invoked by dynamically generated code. While an `int2` can fit in a JVM int, this method is used when reading 2 bytes of a `larger int` that spans a page boundary.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM long

  - ### readLongBE3

    static long readLongBE3(byte[] arr, int offset)
    Read an `int3` from the given array at the given offset in big endian.

    This is invoked by dynamically generated code. While an `int3` can fit in a JVM int, this method is used when reading 3 bytes of a `larger int` that spans a page boundary.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM long

  - ### readLongBE4

    static long readLongBE4(byte[] arr, int offset)
    Read an `int4` from the given array at the given offset in big endian.

    This is invoked by dynamically generated code. While an `int4` can fit in a JVM int, this method is used when reading 4 bytes of a `larger int` that spans a page boundary.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM long

  - ### readLongBE5

    static long readLongBE5(byte[] arr, int offset)
    Read an `int5` from the given array at the given offset in big endian.

    This is invoked by dynamically generated code.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM long

  - ### readLongBE6

    static long readLongBE6(byte[] arr, int offset)
    Read an `int6` from the given array at the given offset in big endian.

    This is invoked by dynamically generated code.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM long

  - ### readLongBE7

    static long readLongBE7(byte[] arr, int offset)
    Read an `int7` from the given array at the given offset in big endian.

    This is invoked by dynamically generated code.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM long

  - ### readLongBE8

    static long readLongBE8(byte[] arr, int offset)
    Read an `int8` from the given array at the given offset in big endian.

    This is invoked by dynamically generated code.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM long

  - ### readLongLE2

    static long readLongLE2(byte[] arr, int offset)
    Read an `int2` from the given array at the given offset in little endian.

    This is invoked by dynamically generated code. While an `int2` can fit in a JVM int, this method is used when reading 2 bytes of a `larger int` that spans a page boundary.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM long

  - ### readLongLE3

    static long readLongLE3(byte[] arr, int offset)
    Read an `int3` from the given array at the given offset in little endian.

    This is invoked by dynamically generated code. While an `int3` can fit in a JVM int, this method is used when reading 3 bytes of a `larger int` that spans a page boundary.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM long

  - ### readLongLE4

    static long readLongLE4(byte[] arr, int offset)
    Read an `int4` from the given array at the given offset in little endian.

    This is invoked by dynamically generated code. While an `int4` can fit in a JVM int, this method is used when reading 4 bytes of a `larger int` that spans a page boundary.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM long

  - ### readLongLE5

    static long readLongLE5(byte[] arr, int offset)
    Read an `int5` from the given array at the given offset in little endian.

    This is invoked by dynamically generated code.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM long

  - ### readLongLE6

    static long readLongLE6(byte[] arr, int offset)
    Read an `int6` from the given array at the given offset in little endian.

    This is invoked by dynamically generated code.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM long

  - ### readLongLE7

    static long readLongLE7(byte[] arr, int offset)
    Read an `int7` from the given array at the given offset in little endian.

    This is invoked by dynamically generated code.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM long

  - ### readLongLE8

    static long readLongLE8(byte[] arr, int offset)
    Read an `int8` from the given array at the given offset in little endian.

    This is invoked by dynamically generated code.

    Parameters:
      `arr` - the array
      `offset` - the offset
    Returns:
      the value as a JVM long

  - ### writeLong1

    static void writeLong1(long value, byte[] arr, int offset)
    Write an `int1` into the given array at the given offset.

    This is invoked by dynamically generated code. While an `int1` can fit in a JVM int, this method is used when writing 1 byte of a `larger int` that spans a page boundary.

    Parameters:
      `value` - the value as a JVM long
      `arr` - the array
      `offset` - the offset

  - ### writeLongBE2

    static void writeLongBE2(long value, byte[] arr, int offset)
    Write an `int2` into the given array at the given offset in big endian.

    This is invoked by dynamically generated code. While an `int2` can fit in a JVM int, this method is used when writing 2 bytes of a `larger int` that spans a page boundary.

    Parameters:
      `value` - the value as a JVM long
      `arr` - the array
      `offset` - the offset

  - ### writeLongBE3

    static void writeLongBE3(long value, byte[] arr, int offset)
    Write an `int3` into the given array at the given offset in big endian.

    This is invoked by dynamically generated code. While an `int3` can fit in a JVM int, this method is used when writing 3 bytes of a `larger int` that spans a page boundary.

    Parameters:
      `value` - the value as a JVM long
      `arr` - the array
      `offset` - the offset

  - ### writeLongBE4

    static void writeLongBE4(long value, byte[] arr, int offset)
    Write an `int4` into the given array at the given offset in big endian.

    This is invoked by dynamically generated code. While an `int4` can fit in a JVM int, this method is used when writing 4 bytes of a `larger int` that spans a page boundary.

    Parameters:
      `value` - the value as a JVM long
      `arr` - the array
      `offset` - the offset

  - ### writeLongBE5

    static void writeLongBE5(long value, byte[] arr, int offset)
    Write an `int5` into the given array at the given offset in big endian.

    This is invoked by dynamically generated code.

    Parameters:
      `value` - the value as a JVM long
      `arr` - the array
      `offset` - the offset

  - ### writeLongBE6

    static void writeLongBE6(long value, byte[] arr, int offset)
    Write an `int6` into the given array at the given offset in big endian.

    This is invoked by dynamically generated code.

    Parameters:
      `value` - the value as a JVM long
      `arr` - the array
      `offset` - the offset

  - ### writeLongBE7

    static void writeLongBE7(long value, byte[] arr, int offset)
    Write an `int7` into the given array at the given offset in big endian.

    This is invoked by dynamically generated code.

    Parameters:
      `value` - the value as a JVM long
      `arr` - the array
      `offset` - the offset

  - ### writeLongBE8

    static void writeLongBE8(long value, byte[] arr, int offset)
    Write an `int8` into the given array at the given offset in big endian.

    This is invoked by dynamically generated code.

    Parameters:
      `value` - the value as a JVM long
      `arr` - the array
      `offset` - the offset

  - ### writeLongLE2

    static void writeLongLE2(long value, byte[] arr, int offset)
    Write an `int2` into the given array at the given offset in little endian.

    This is invoked by dynamically generated code. While an `int2` can fit in a JVM int, this method is used when writing 2 bytes of a `larger int` that spans a page boundary.

    Parameters:
      `value` - the value as a JVM long
      `arr` - the array
      `offset` - the offset

  - ### writeLongLE3

    static void writeLongLE3(long value, byte[] arr, int offset)
    Write an `int3` into the given array at the given offset in little endian.

    This is invoked by dynamically generated code. While an `int3` can fit in a JVM int, this method is used when writing 3 bytes of a `larger int` that spans a page boundary.

    Parameters:
      `value` - the value as a JVM long
      `arr` - the array
      `offset` - the offset

  - ### writeLongLE4

    static void writeLongLE4(long value, byte[] arr, int offset)
    Write an `int4` into the given array at the given offset in little endian.

    This is invoked by dynamically generated code. While an `int4` can fit in a JVM int, this method is used when writing 4 bytes of a `larger int` that spans a page boundary.

    Parameters:
      `value` - the value as a JVM long
      `arr` - the array
      `offset` - the offset

  - ### writeLongLE5

    static void writeLongLE5(long value, byte[] arr, int offset)
    Write an `int5` into the given array at the given offset in little endian.

    This is invoked by dynamically generated code.

    Parameters:
      `value` - the value as a JVM long
      `arr` - the array
      `offset` - the offset

  - ### writeLongLE6

    static void writeLongLE6(long value, byte[] arr, int offset)
    Write an `int6` into the given array at the given offset in little endian.

    This is invoked by dynamically generated code.

    Parameters:
      `value` - the value as a JVM long
      `arr` - the array
      `offset` - the offset

  - ### writeLongLE7

    static void writeLongLE7(long value, byte[] arr, int offset)
    Write an `int7` into the given array at the given offset in little endian.

    This is invoked by dynamically generated code.

    Parameters:
      `value` - the value as a JVM long
      `arr` - the array
      `offset` - the offset

  - ### writeLongLE8

    static void writeLongLE8(long value, byte[] arr, int offset)
    Write an `int8` into the given array at the given offset in little endian.

    This is invoked by dynamically generated code.

    Parameters:
      `value` - the value as a JVM long
      `arr` - the array
      `offset` - the offset

  - ### conv2IntToLong

    static long conv2IntToLong(int msl, int lsl)
    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.

    Parameters:
      `msl` - the more significant leg
      `lsl` - the less significant leg
    Returns:
      the long

  - ### sBorrowIntRaw

    static int sBorrowIntRaw(int a, int b)
    The implementation of `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.

    Parameters:
      `a` - the first operand as in `a - b`
      `b` - the second operand as in `a - b`
    Returns:
      the register of borrow bits

  - ### sBorrowLongRaw

    static long sBorrowLongRaw(long a, long b)
    The implementation of `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.

    Parameters:
      `a` - the first operand as in `a - b`
      `b` - the second operand as in `a - b`
    Returns:
      the register of borrow bits

  - ### sBorrowMpInt

    static int sBorrowMpInt(int[] a, int[] b, int shift)
    The implementation of `int_sborrow` on multi-precision ints.
    Parameters:
      `a` - the first operand as in `a - b`
      `b` - the second operand as in `a - b`
      `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.
    Returns:
      the one carry bit

  - ### sCarryIntRaw

    static int sCarryIntRaw(int a, int b)
    The implementation of `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.

    Parameters:
      `a` - the first operand as in `a + b`
      `b` - the second operand as in `a + b`
    Returns:
      the register of carry bits

  - ### sCarryLongRaw

    static long sCarryLongRaw(long a, long b)
    The implementation of `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.

    Parameters:
      `a` - the first operand as in `a + b`
      `b` - the second operand as in `a + b`
    Returns:
      the register of carry bits

  - ### sCarryMpInt

    static int sCarryMpInt(int[] a, int[] b, int shift)
    The implementation of `int_scarry` on multi-precision ints.
    Parameters:
      `a` - the first operand as in `a + b`
      `b` - the second operand as in `a + b`
      `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.
    Returns:
      the one carry bit

  - ### intLeft

    static void intLeft(int[] out, int outBytes, int[] val, int[] amt)
    The implementation of `int_left` on multi-precision ints.

    The semantics here are subtly different than the JVM's `ishl`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.

    Parameters:
      `out` - the array to receive the output, in little-endian order
      `outBytes` - the actual size in bytes of the output operand
      `val` - the value as in `val << amt`, in little-endian order
      `amt` - the amt as in `val << amt`, in little-endian order

  - ### intLeft

    static void intLeft(int[] out, int outBytes, int[] val, long amt)
    The implementation of `int_left` on an mp-int with a JVM long shift amount.

    The semantics here are subtly different than the JVM's `ishl`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.

    Parameters:
      `out` - the array to receive the output, in little-endian order
      `outBytes` - the actual size in bytes of the output operand
      `val` - the value as in `val << amt`, in little-endian order
      `amt` - the amt as in `val << amt`

  - ### intLeft

    static void intLeft(int[] out, int outBytes, int[] val, int amt)
    The implementation of `int_left` on an mp-int with a JVM int shift amount.

    The semantics here are subtly different than the JVM's `ishl`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.

    Parameters:
      `out` - the array to receive the output, in little-endian order
      `outBytes` - the actual size in bytes of the output operand
      `val` - the value as in `val << amt`, in little-endian order
      `amt` - the amt as in `val << amt`

  - ### intLeft

    static long intLeft(long val, int[] amt)
    The implementation of `int_left` on a JVM long with an mp-int shift amount.

    The semantics here are subtly different than the JVM's `ishl`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.

    Parameters:
      `val` - the value as in `val << amt`
      `amt` - the amt as in `val << amt`, in little-endian order
    Returns:
      the value

  - ### intLeft

    static long intLeft(long val, long amt)
    The implementation of `int_left` on JVM longs.

    The semantics here are subtly different than the JVM's `ishl`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.

    Parameters:
      `val` - the value as in `val << amt`
      `amt` - the amt as in `val << amt`
    Returns:
      the value

  - ### intLeft

    static long intLeft(long val, int amt)
    The implementation of `int_left` on JVM long with int amt.

    The semantics here are subtly different than the JVM's `ishl`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.

    Parameters:
      `val` - the value as in `val << amt`
      `amt` - the amt as in `val << amt`
    Returns:
      the value

  - ### intLeft

    static long intLeft(int val, int[] amt)
    The implementation of `int_left` on a JVM int with an mp-int shift amount.

    The semantics here are subtly different than the JVM's `ishl`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.

    Parameters:
      `val` - the value as in `val << amt`
      `amt` - the amt as in `val << amt`, in little-endian order
    Returns:
      the value

  - ### intLeft

    static int intLeft(int val, long amt)
    The implementation of `int_left` on JVM int with long amt.

    The semantics here are subtly different than the JVM's `ishl`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.

    Parameters:
      `val` - the value as in `val << amt`
      `amt` - the amt as in `val << amt`
    Returns:
      the value

  - ### intLeft

    static int intLeft(int val, int amt)
    The implementation of `int_left` on JVM ints.

    The semantics here are subtly different than the JVM's `ishl`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.

    Parameters:
      `val` - the value as in `val << amt`
      `amt` - the amt as in `val << amt`
    Returns:
      the value

  - ### intRight

    static void intRight(int[] out, int outBytes, int[] val, int[] amt)
    The implementation of `int_right` on multi-precision ints.

    The semantics here are subtly different than the JVM's `iushr`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.

    Parameters:
      `out` - the array to receive the output, in little-endian order
      `outBytes` - the actual size in bytes of the output operand
      `val` - the value as in `val >> amt`, in little-endian order
      `amt` - the amt as in `val >> amt`, in little-endian order

  - ### intRight

    static void intRight(int[] out, int outBytes, int[] val, long amt)
    The implementation of `int_right` on an mp-int with a JVM long shift amount.

    The semantics here are subtly different than the JVM's `iushr`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.

    Parameters:
      `out` - the array to receive the output, in little-endian order
      `outBytes` - the actual size in bytes of the output operand
      `val` - the value as in `val >> amt`, in little-endian order
      `amt` - the amt as in `val >> amt`

  - ### intRight

    static void intRight(int[] out, int outBytes, int[] val, int amt)
    The implementation of `int_right` on an mp-int with a JVM int shift amount.

    The semantics here are subtly different than the JVM's `iushr`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.

    Parameters:
      `out` - the array to receive the output, in little-endian order
      `outBytes` - the actual size in bytes of the output operand
      `val` - the value as in `val >> amt`, in little-endian order
      `amt` - the amt as in `val >> amt`

  - ### intRight

    static long intRight(long val, int[] amt)
    The implementation of `int_right` on a JVM long with an mp-int shift amount.

    The semantics here are subtly different than the JVM's `iushr`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.

    Parameters:
      `val` - the value as in `val >> amt`
      `amt` - the amt as in `val >> amt`, in little-endian order
    Returns:
      the value

  - ### intRight

    static long intRight(long val, long amt)
    The implementation of `int_right` on JVM longs.

    The semantics here are subtly different than the JVM's `iushr`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.

    Parameters:
      `val` - the value as in `val >> amt`
      `amt` - the amt as in `val >> amt`
    Returns:
      the value

  - ### intRight

    static long intRight(long val, int amt)
    The implementation of `int_right` on JVM long with int amt.

    The semantics here are subtly different than the JVM's `iushr`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.

    Parameters:
      `val` - the value as in `val >> amt`
      `amt` - the amt as in `val >> amt`
    Returns:
      the value

  - ### intRight

    static long intRight(int val, int[] amt)
    The implementation of `int_right` on a JVM int with an mp-int shift amount.

    The semantics here are subtly different than the JVM's `iushr`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.

    Parameters:
      `val` - the value as in `val >> amt`
      `amt` - the amt as in `val >> amt`, in little-endian order
    Returns:
      the value

  - ### intRight

    static int intRight(int val, long amt)
    The implementation of `int_right` on JVM int with long amt.

    The semantics here are subtly different than the JVM's `iushr`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.

    Parameters:
      `val` - the value as in `val >> amt`
      `amt` - the amt as in `val >> amt`
    Returns:
      the value

  - ### intRight

    static int intRight(int val, int amt)
    The implementation of `int_right` on JVM ints.

    The semantics here are subtly different than the JVM's `iushr`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size clear the register.

    Parameters:
      `val` - the value as in `val >> amt`
      `amt` - the amt as in `val >> amt`
    Returns:
      the value

  - ### intSRight

    static void intSRight(int[] out, int outBytes, int[] val, int[] amt)
    The implementation of `int_sright` on multi-precision ints.

    The semantics here are subtly different than the JVM's `ishr`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size fill the register with the sign bit.

    Parameters:
      `out` - the array to receive the output, in little-endian order
      `outBytes` - the actual size in bytes of the output operand
      `val` - the value as in `val s>> amt`, in little-endian order
      `amt` - the amt as in `val s>> amt`, in little-endian order

  - ### intSRight

    static long intSRight(long val, long amt)
    The implementation of `int_sright` on JVM longs.

    The semantics here are subtly different than the JVM's `ishr`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size fill the register with the sign bit.

    Parameters:
      `val` - the value as in `val s>> amt`
      `amt` - the amt as in `val s>> amt`
    Returns:
      the value

  - ### intSRight

    static long intSRight(long val, int amt)
    The implementation of `int_sright` on JVM long with int amt.

    The semantics here are subtly different than the JVM's `ishr`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size fill the register with the sign bit.

    Parameters:
      `val` - the value as in `val s>> amt`
      `amt` - the amt as in `val s>> amt`
    Returns:
      the value

  - ### intSRight

    static int intSRight(int val, long amt)
    The implementation of `int_sright` on JVM int with long amt.

    The semantics here are subtly different than the JVM's `ishr`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size fill the register with the sign bit.

    Parameters:
      `val` - the value as in `val s>> amt`
      `amt` - the amt as in `val s>> amt`
    Returns:
      the value

  - ### intSRight

    static int intSRight(int val, int amt)
    The implementation of `int_sright` on JVM ints.

    The semantics here are subtly different than the JVM's `ishr`: 1) The amount must be treated as unsigned. 2) Shifts in excess of val's size fill the register with the sign bit.

    Parameters:
      `val` - the value as in `val s>> amt`
      `amt` - the amt as in `val s>> amt`
    Returns:
      the value

  - ### mpIntMultiply

    static void mpIntMultiply(int[] out, int[] inL, int[] inR)
    The implementation of `PcodeOp.INT_MULT` on mp-ints.

    All arrays are in little-endian order

    Parameters:
      `out` - the array allocated to receive the output
      `inL` - the array of left input legs
      `inR` - the array of right input legs

  - ### mpToString

    static String mpToString(int[] legs)

  - ### mpIntDivide

    static void mpIntDivide(int[] out, int[] inL, int[] inR)
    The implementation of `PcodeOp.INT_DIV` on mp-ints.

    All arrays are in little-endian order. While this directly implements `PcodeOp.INT_DIV`, it is also used for `PcodeOp.INT_REM`, `PcodeOp.INT_SDIV`, and `PcodeOp.INT_SREM`.

    Parameters:
      `out` - the array allocated to receive the quotient
      `inL` - the array of dividend input legs, over-provisioned by 1, which will also receive the remainder
      `inR` - the array of divisor input legs

  - ### mpIntSignedDivide

    static void mpIntSignedDivide(int[] out, int[] inL, int[] inR)
    The implementation of `PcodeOp.INT_SDIV` on mp-ints.

    All arrays are in little-endian order. While this directly implements `PcodeOp.INT_SDIV`, it is also used for `PcodeOp.INT_SREM`.

    Parameters:
      `out` - the array allocated to receive the quotient
      `inL` - the array of dividend input legs, over-provisioned by 1, which will also receive the remainder
      `inR` - the array of divisor input legs

  - ### getLanguage

    static Language getLanguage(String languageID) throws LanguageNotFoundException
    Get the language for the given string language ID

    This is called by generated static initializers.

    Parameters:
      `languageID` - the language ID
    Returns:
      the language
    Throws:
      `LanguageNotFoundException` - if the language is not found

  - ### createContext

    static RegisterValue createContext(Language language, String value)
    Construct a contextreg value from the given language and hex value

    This is called by generated static initializers to pre-construct context values.

    Parameters:
      `language` - the language
      `value` - the value as a string of hexadecimal digits
    Returns:
      the value

  - ### createVarnode

    static Varnode createVarnode(AddressFactory factory, String space, long offset, int size)
    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.

    Parameters:
      `factory` - the language's address factory
      `space` - the name of the space
      `offset` - the byte offset
      `size` - the size (in bytes)
    Returns:
      the varnode

  - ### thread

    JitPcodeThread thread()
    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.

    Returns:
      the thread

  - ### writeCounterAndContext

    default void writeCounterAndContext(long counter, RegisterValue context)
    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 `JitPcodeThread.writeCounterAndContext(Address, RegisterValue)`.

    Parameters:
      `counter` - the offset of the next instruction to execute
      `context` - the decode context for the next instruction

  - ### setCounterAndContext

    default void setCounterAndContext(long counter, RegisterValue context)
    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 `JitPcodeThread.setCounterAndContext(Address, RegisterValue)`.

    Parameters:
      `counter` - the offset of the next instruction to execute
      `context` - the decode context for the next instruction

  - ### getUseropDefinition

    default PcodeUseropLibrary.PcodeUseropDefinition<byte[]> getUseropDefinition(String name)
    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 `invokeUserop(PcodeUseropDefinition, Varnode, Varnode[])`, or its method and instance may be extracted and saved for Direct invocation later.

    Parameters:
      `name` - the name of the userop
    Returns:
      the userop or `null`
    See Also:
      - `JitDataFlowUseropLibrary`

  - ### invokeUserop

    default void invokeUserop(PcodeUseropLibrary.PcodeUseropDefinition<byte[]> userop, Varnode output, Varnode[] inputs)
    Invoke the given userop on the bound thread with the given operands

    This is invoked by generated code in `run(int)` to invoke a userop via the Standard strategy.

    Parameters:
      `userop` - the userop definition
      `output` - an optional output operand
      `inputs` - the input operands
    See Also:
      - `JitDataFlowUseropLibrary`
      - `PcodeUseropLibrary.PcodeUseropDefinition.execute(PcodeExecutor, PcodeUseropLibrary, Varnode, List)`

  - ### createDecodeError

    default DecodePcodeExecutionException createDecodeError(String message, long counter)
    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.

    Parameters:
      `message` - the human-readable message
      `counter` - the program counter where the decode error was encountered
    Returns:
      the exception, which should be thrown immediately

  - ### createExitSlot

    default JitCompiledPassage.ExitSlot createExitSlot(long target, RegisterValue ctx)
    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.

    Parameters:
      `target` - the target program counter
      `ctx` - the target decode context
    Returns:
      the exit slot

  - ### getChained

    static JitCompiledPassage.EntryPoint getChained(JitCompiledPassage.ExitSlot slot)
    Get the chained entry point for the given exit point's target

    This is invoked by generated code in `run(int)` to take a branch exiting the passage. The first time, the exit slot is lazily filled, possibly requiring further JIT translation.

    Parameters:
      `slot` - the slot for the target of the branch we're taking
    Returns:
      the chained entry point

  - ### count

    default void count(int instructions, int trailingOps)
    Invoke `JitPcodeThread.count(int, int)` for the bound thread
    Parameters:
      `instructions` - as in `JitPcodeThread.count(int, int)`
      `trailingOps` - as in `JitPcodeThread.count(int, int)`