Interface Opnd<T extends JitType>

Type Parameters:
T - the p-code type
All Known Subinterfaces:
SimpleOpnd<T,JT>
All Known Implementing Classes:
IntConstOpnd, MpIntLocalOpnd

public interface Opnd<T extends JitType>
A (sometimes temporary) operand

This class is also the namespace for a number of convesion operations. Please note that "conversions" here deal entirely in bits. While a lot of machinery is needed to represent p-code values, esp., when the number of bytes exceeds a JVM long, in essence, every conversion operation, if it performs any operation at all, is merely bit truncation or extension. Otherwise, all we are doing is convincing the JVM that the operand's type has changed. In particular, an int-to-float conversion is not accomplished using i2f, as that would actually change the raw bit contents of the value. Rather, we use Float.intBitsToFloat(int).

  • Method Details

    • needsIntExt

      static boolean needsIntExt(JitType.IntJitType from, JitType.IntJitType to)
      Check if the given int-to-int conversion would require extension
      Parameters:
      from - the source p-code type
      to - the destination p-code type
      Returns:
      true if extension is needed, i.e., to is strictly larger than from
    • needsLongExt

      static boolean needsLongExt(JitType.LongJitType from, JitType.LongJitType to)
      Check if the given long-to-long conversion would require extension
      Parameters:
      from - the source p-code type
      to - the destination p-code type
      Returns:
      true if extension is needed, i.e., to is strictly larger than from
    • lextshr

      static <N2 extends Emitter.Next, N1 extends Emitter.Ent<N2, Types.TLong>, N0 extends Emitter.Ent<N1, Types.TInt>> Emitter<Emitter.Ent<N2,Types.TLong>> lextshr(Emitter<N0> em, Opnd.Ext ext)
      Emit a long left shift, selecting signed or unsigned by the given extension
      Type Parameters:
      N2 - the tail of the stack (...)
      N1 - ..., value1
      N0 - ..., value1, value2
      Parameters:
      em - the emitter
      ext - the kind of extension to apply
      Returns:
      the emitter with ..., result
    • constOf

      static SimpleOpnd<Types.TInt,JitType.IntJitType> constOf(JitType.IntJitType type, int value)
      Create a constant int operand of the given type
      Parameters:
      type - the p-code type
      value - the value
      Returns:
      the constant
    • constOf

      static SimpleOpnd<Types.TLong,JitType.LongJitType> constOf(JitType.LongJitType type, long value)
      Create a constant long operand of the given type
      Parameters:
      type - the p-code type
      value - the value
      Returns:
      the constant
    • constOf

      static SimpleOpnd<Types.TFloat,JitType.FloatJitType> constOf(JitType.FloatJitType type, float value)
      Create a constant float operand of the given type
      Parameters:
      type - the p-code type
      value - the value
      Returns:
      the constant
    • constOf

      Create a constant double operand of the given type
      Parameters:
      type - the p-code type
      value - the value
      Returns:
      the constant
    • constOf

      static Opnd<JitType.MpIntJitType> constOf(JitType.MpIntJitType type, BigInteger value)
      Create a constant mp-int operand of the given type
      Parameters:
      type - the p-code type
      value - the value
      Returns:
      the constant
    • intToBool

      static <N1 extends Emitter.Next, N0 extends Emitter.Ent<N1, Types.TInt>> Emitter<Emitter.Ent<N1,Types.TInt>> intToBool(Emitter<N0> em)
      Emit code to convert a simple int to a boolean

      This treats any non-zero value as true. Only zero is treated as false. The result is either 1 (true) or 0 (false). In other words, this converts any non-zero value to 1. Zero is left as 0.

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

      static <TT extends Types.BPrim<?>, TJT extends JitType.SimpleJitType<TT, TJT>, FT extends Types.BPrim<?>, FJT extends JitType.SimpleJitType<FT, FJT>, N1 extends Emitter.Next, N0 extends Emitter.Ent<N1, FT>> Emitter<Emitter.Ent<N1,TT>> castStack1(Emitter<N0> em, FJT from, TJT to)
      Emit nothing, but cast the emitter by asserting two given p-code types are identical

      This is often used in switch statements where the cases are specific types. Likely the switch variable has a generic type. For a given case, we know that generic type is identical to a given p-code type, but to convince the Java compiler, we need to cast. This method provides a structured mechanism for that cast to prevent mistakes. Additionally, at runtime, if assertions are enabled, this will fail when the given types are not actually identical.

      Type Parameters:
      TT - the "to" JVM type
      TJT - the "to" p-code type
      FT - the "from" JVM type
      FJT - the "from" p-code type
      N1 - the tail of the stack (...)
      N0 - ..., value
      Parameters:
      em - the emitter
      from - the p-code type
      to - the same p-code type, but with an apparently different type at compile time
      Returns:
      the emitter with ..., value (unchanged)
    • create

      static <T extends Types.BPrim<?>, JT extends JitType.SimpleJitType<T, JT>, N1 extends Emitter.Next, N0 extends Emitter.Ent<N1, T>> SimpleOpnd.SimpleOpndEm<T,JT,N1> create(Emitter<N0> em, JT type, String name, Scope scope)
      Create an operand of the given p-code type from the value on the stack
      Type Parameters:
      T - the JVM type
      JT - the p-code type
      N1 - the tail of the stack (...)
      N0 - ..., value
      Parameters:
      em - the emitter
      type - the p-code type
      name - the name of the local variable to create
      scope - a scope for the local variable
      Returns:
      the operand and emitter with ...
    • createInt

      static <N1 extends Emitter.Next, N0 extends Emitter.Ent<N1, Types.TInt>> SimpleOpnd.SimpleOpndEm<Types.TInt,JitType.IntJitType,N1> createInt(Emitter<N0> em, JitType.IntJitType type, String name, Scope scope)
      Create an int operand from the value on the stack
      Type Parameters:
      N1 - the tail of the stack (...)
      N0 - ..., value
      Parameters:
      em - the emitter
      type - the p-code type
      name - the name of the local variable to create
      scope - a scope for the local variable
      Returns:
      the operand and emitter with ...
    • createIntReadOnly

      static <N1 extends Emitter.Next, N0 extends Emitter.Ent<N1, Types.TInt>> SimpleOpnd.SimpleOpndEm<Types.TInt,JitType.IntJitType,N1> createIntReadOnly(Emitter<N0> em, JitType.IntJitType type, String name, Scope scope)
      Create a read-only int operand from the value on the stack
      Type Parameters:
      N1 - the tail of the stack (...)
      N0 - ..., value
      Parameters:
      em - the emitter
      type - the p-code type
      name - the name of the local variable to create
      scope - a scope for the local variable
      Returns:
      the operand and emitter with ...
      See Also:
    • getStackToStack

      static <FT extends Types.BPrim<?>, FJT extends JitType.SimpleJitType<FT, FJT>, TT extends Types.BPrim<?>, TJT extends JitType.SimpleJitType<TT, TJT>> Opnd.StackToStackConv<FT,FJT,TT,TJT> getStackToStack(FJT from, TJT to)
      Obtain the converter between two given simple types
      Type Parameters:
      FT - the "from" JVM type
      FJT - the "from" p-code type
      TT - the "to" JVM type
      TJT - the "to" p-code type
      Parameters:
      from - the source p-code type
      to - the destination p-code type
      Returns:
      the converter
    • convert

      static <FT extends Types.BPrim<?>, FJT extends JitType.SimpleJitType<FT, FJT>, TT extends Types.BPrim<?>, TJT extends JitType.SimpleJitType<TT, TJT>, N1 extends Emitter.Next, N0 extends Emitter.Ent<N1, FT>> Emitter<Emitter.Ent<N1,TT>> convert(Emitter<N0> em, FJT from, TJT to, Opnd.Ext ext)
      Convert from a given simple type to another simple type
      Type Parameters:
      FT - the "from" JVM type
      FJT - the "from" p-code type
      TT - the "to" JVM type
      TJT - the "to" p-code type
      N1 - the tail of the stack (...)
      N0 - ..., value
      Parameters:
      em - the emitter
      from - the source p-code type
      to - the destination p-code type
      ext - the kind of extension to apply
      Returns:
      the emitter with ..., result
    • convertIntToInt

      static <N1 extends Emitter.Next, N0 extends Emitter.Ent<N1, Types.TInt>> Emitter<Emitter.Ent<N1,Types.TInt>> convertIntToInt(Emitter<N0> em, JitType.IntJitType from, JitType.IntJitType to, Opnd.Ext ext)
      Convert from an int type to another int type
      Type Parameters:
      N1 - the tail of the stack (...)
      N0 - ..., value
      Parameters:
      em - the emitter
      from - the source p-code type
      to - the destination p-code type
      ext - the kind of extension to apply
      Returns:
      the emitter with ..., result
    • getStackToMp

      static <FT extends Types.BPrim<?>, FJT extends JitType.SimpleJitType<FT, FJT>, TT extends Types.BPrim<?>, TLT extends JitType.SimpleJitType<TT, TLT>, TJT extends JitType.LeggedJitType<TT, TLT>> Opnd.StackToMpConv<FT,FJT,TT,TLT,TJT> getStackToMp(FJT from, TJT to)
      Obtain the converter from a simple type to an mp type
      Type Parameters:
      FT - the "from" JVM type
      FJT - the "from" p-code type
      TT - the "to" JVM type for each mp leg
      TLT - the "to" p-code type for each mp leg
      TJT - the "to" p-code type
      Parameters:
      from - the source p-code type
      to - the destination p-code type
      Returns:
      the converter
    • convertToOpnd

      static <FT extends Types.BPrim<?>, FJT extends JitType.SimpleJitType<FT, FJT>, TT extends Types.BPrim<?>, TLT extends JitType.SimpleJitType<TT, TLT>, TJT extends JitType.LeggedJitType<TT, TLT>, N1 extends Emitter.Next, N0 extends Emitter.Ent<N1, FT>> Opnd.OpndEm<TJT,N1> convertToOpnd(Emitter<N0> em, FJT from, String name, TJT to, Opnd.Ext ext, Scope scope)
      Convert from a simple type to an mp type in local variables
      Type Parameters:
      FT - the "from" JVM type
      FJT - the "from" p-code type
      TT - the "to" JVM type for each mp leg
      TLT - the "to" p-code type for each mp leg
      TJT - the "to" p-code type
      N1 - the tail of the stack (...)
      N0 - ..., value
      Parameters:
      em - the emitter
      from - the source p-code type
      name - a name (prefix) for the mp-int
      to - the destination p-code type
      ext - the kind of extension to apply
      scope - a scope for generated variables
      Returns:
      the resulting operand and emitter with ...
    • convertToArray

      static <FT extends Types.BPrim<?>, FJT extends JitType.SimpleJitType<FT, FJT>, TT extends Types.BPrim<?>, TLT extends JitType.SimpleJitType<TT, TLT>, TJT extends JitType.LeggedJitType<TT, TLT>, N1 extends Emitter.Next, N0 extends Emitter.Ent<N1, FT>> Emitter<Emitter.Ent<N1,Types.TRef<int[]>>> convertToArray(Emitter<N0> em, FJT from, String name, TJT to, Opnd.Ext ext, Scope scope, int slack)
      Convert from a simple type to an mp type in an array
      Type Parameters:
      FT - the "from" JVM type
      FJT - the "from" p-code type
      TT - the "to" JVM type for each mp leg
      TLT - the "to" p-code type for each mp leg
      TJT - the "to" p-code type
      N1 - the tail of the stack (...)
      N0 - ..., value
      Parameters:
      em - the emitter
      from - the source p-code type
      name - a name (prefix) for the mp-int
      to - the destination p-code type
      ext - the kind of extension to apply
      scope - a scope for generated variables
      slack - the number of extra (more significant) elements to allocate in the array
      Returns:
      the emitter with ..., arrayref
    • type

      T type()
      Returns the p-code type.
      Returns:
      the p-code type
    • name

      String name()
      Returns the name.
      Returns:
      the name
    • legsLE

      List<? extends SimpleOpnd<?,?>> legsLE()
      Returns the legs in little-endian order.

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

      Returns:
      the legs in little-endian order