Interface SimpleOpnd<T extends Types.BPrim<?>,JT extends JitType.SimpleJitType<T,JT>>

Type Parameters:
T - the JVM type
JT - the p-code type
All Superinterfaces:
Opnd<JT>
All Known Implementing Classes:
IntConstOpnd

public interface SimpleOpnd<T extends Types.BPrim<?>,JT extends JitType.SimpleJitType<T,JT>> extends Opnd<JT>
An operand stored in a single JVM local variable
  • Method Details

    • of

      static <T extends Types.BPrim<?>, JT extends JitType.SimpleJitType<T, JT>> SimpleOpnd<T,JT> of(JT type, Local<T> local)
      Create a simple local operand
      Type Parameters:
      T - the JVM type
      JT - the p-code type
      Parameters:
      type - the p-code type
      local - the JVM local
      Returns:
      the operand
    • ofIntReadOnly

      Create a read-only int local operand

      Multi-precision integer operators work by composing several locals into a single p-code variable. Some of these operators need temporary variables. To avoid generating tons of those, we generally allow the temporary locals to be mutated. However, the local variables allocated to hold p-code variables cannot be mutated until the full output value has been successfully computed. Furthermore, we certainly cannot mutate any input operand by mistake. Using a read-only local for input operands ensures this does not happen. An attempt to write to one of these will instead generate a new temporary local, assign the value to it, and return the new operand. An attempt to write directly to this operand will result in an exception being thrown at generation time.

      Parameters:
      type - the p-code type
      local - the local handle
      Returns:
      the read-only operand
    • read

      <N extends Emitter.Next> Emitter<Emitter.Ent<N,T>> read(Emitter<N> em)
      Emit code to read the operand onto the stack
      Type Parameters:
      N - the tail of the stack (...)
      Parameters:
      em - the emitter
      Returns:
      the emitter with ..., value
    • write

      default <N1 extends Emitter.Next, N0 extends Emitter.Ent<N1, T>> SimpleOpnd.SimpleOpndEm<T,JT,N1> write(Emitter<N0> em, Scope scope)
      Emit code to write the operand from the stack

      This will generate a new operand if this operand is read-only. Callers must therefore be prepared to take the result in place of this operand.

      Type Parameters:
      N1 - the tail of the stack (...)
      N0 - ..., value
      Parameters:
      em - the emitter
      scope - a scope for generated temporary variables
      Returns:
      the resulting operand and emitter with ...
    • writeDirect

      <N1 extends Emitter.Next, N0 extends Emitter.Ent<N1, T>> Emitter<N1> writeDirect(Emitter<N0> em)
      Emit code to write the operand, without generating a new operand

      This will throw an exception during generation if this operand is read-only. This should only be used when the caller is certain the operand can be written and when a scope is not available.

      Type Parameters:
      N1 - the tail of the stack (...)
      N0 - ..., value
      Parameters:
      em - the emitter
      Returns:
      the emitter with ...
    • legsLE

      default List<? extends SimpleOpnd<?,?>> legsLE()
      Description copied from interface: Opnd
      Returns the legs in little-endian order.

      For non-legged types, this returns the singleton list containing only this operand

      Specified by:
      legsLE in interface Opnd<T extends Types.BPrim<?>>
      Returns:
      the legs in little-endian order