Interface TypeConversions

All Superinterfaces:
org.objectweb.asm.Opcodes

public interface TypeConversions extends org.objectweb.asm.Opcodes
The generator for various type conversion.

These conversions are no more than bitwise casts. The underlying bits are unchanged, but the interpretation and/or the way the JVM has tagged them does.

Many of the methods (and also many other bits of the code generator) follow a convention where the input type(s) are passed as parameter(s), and the resulting type is returned. In many cases the desired type is also taken as a parameter. Upon success, we'd expect that desired type to be the exact type returned, but this may not always be the case. This convention ensures all pieces of the generator know the p-code type (and thus JVM type) of the variable at the top of the JVM stack.

Type conversions are applicable at a few boundaries:

  • To ensure use-def values conform to the requirements of the operands where they are used and defined. The JitTypeModel aims to reduce the number of conversions required by assigning appropriate types to the use-def value nodes, but this will not necessarily eliminate them all.
  • Within the implementation of an operator, type conversions may be necessary to ensure the p-code types of input operands conform with the JVM types required by the emitted bytecodes, and that the output JVM type conforms to the p-code type of the output operand.
  • When loading or storing as bytes from the state. The conversion from and to bytes is done using JVM integral types, and so the value may be converted if the operand requires a floating-point type.
  • Method Details

    • checkGenIntMask

      static void checkGenIntMask(JitType from, JitType.IntJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit an Opcodes.IAND to reduce the number of bits to those permitted in an int of the given size.

      For example to mask from an int4 to an JitType.IntJitType.I2, this would emit iand 0xffff. If the source size is smaller than or equal to that of the destination, nothing is emitted.

      Parameters:
      from - the source type
      to - the destination type
      mv - the method visitor
    • generateIntToInt

      static JitType.IntJitType generateIntToInt(JitType.IntJitType from, JitType.IntJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit bytecode to convert one p-code in (in a JVM int) to another
      Parameters:
      from - the source type
      to - the destination type
      mv - the method visitor
      Returns:
      the destination type
    • generateLongToInt

      static JitType.IntJitType generateLongToInt(JitType.LongJitType from, JitType.IntJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit bytecode to convert one p-code int (in a JVM long) to one in a JVM int.
      Parameters:
      from - the source type
      to - the destination type
      mv - the method visitor
      Returns:
      the destination type
    • generateFloatToInt

      static JitType.IntJitType generateFloatToInt(JitType.FloatJitType from, JitType.IntJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit bytecode to convert a float4 to an int4.
      Parameters:
      from - the source type (must be float4)
      to - the destination type (must be int4)
      mv - the method visitor
      Returns:
      the destination type (int4)
    • generateMpIntToInt

      static JitType.IntJitType generateMpIntToInt(JitType.MpIntJitType from, JitType.IntJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit bytecode to convert a mult-precision int to a p-code int that fits in a JVM int.
      Parameters:
      from - the source type
      to - the destination type
      mv - the method visitor
      Returns:
      the destination type
    • generateToInt

      static JitType.IntJitType generateToInt(JitType from, JitType.IntJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit bytecode to convert any (compatible) type to a p-code int that fits in a JVM int.

      The only acceptable floating-point source type is float4.

      Parameters:
      from - the source type
      to - the destination type
      mv - the method visitor
      Returns:
      the destination type
    • checkGenLongMask

      static void checkGenLongMask(JitType from, JitType.LongJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit an Opcodes.LAND to reduce the number of bits to those permitted in an int of the given size.

      For example to mask from a int8 to a JitType.LongJitType.I6, this would emit land 0x0ffffffffffffL. If the source size is smaller than or equal to that of the destination, nothing is emitted.

      Parameters:
      from - the source type
      to - the destination type
      mv - the method visitor
    • generateIntToLong

      static JitType.LongJitType generateIntToLong(JitType.IntJitType from, JitType.LongJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit bytecode to convert one p-code int (in a JVM int) to one in a JVM long.

      Care must be taken to ensure conversions to larger types extend with zeros (unsigned).

      Parameters:
      from - the source type
      to - the destination type
      mv - the method visitor
      Returns:
      the destination type
    • generateLongToLong

      static JitType.LongJitType generateLongToLong(JitType.LongJitType from, JitType.LongJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit bytecode to convert one p-code in (in a JVM long) to another
      Parameters:
      from - the source type
      to - the destination type
      mv - the method visitor
      Returns:
      the destination type
    • generateDoubleToLong

      static JitType.LongJitType generateDoubleToLong(JitType.DoubleJitType from, JitType.LongJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit bytecode to convert a float8 to an int8.
      Parameters:
      from - the source type (must be float8)
      to - the destination type (must be int8)
      mv - the method visitor
      Returns:
      the destination type (int8)
    • generateMpIntToLong

      static JitType.LongJitType generateMpIntToLong(JitType.MpIntJitType from, JitType.LongJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit bytecode to convert a mult-precision int to a p-code int that fits in a JVM long.
      Parameters:
      from - the source type
      to - the destination type
      mv - the method visitor
      Returns:
      the destination type
    • generateToLong

      static JitType.LongJitType generateToLong(JitType from, JitType.LongJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit bytecode to convert any (compatible) type to a p-code that fits in a JVM long.

      The only acceptable floating-point source type is float8.

      Parameters:
      from - the source type
      to - the destination type
      mv - the method visitor
      Returns:
      the destination type
    • generateIntToFloat

      static JitType.FloatJitType generateIntToFloat(JitType.IntJitType from, JitType.FloatJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit bytecode to convert an int4 to a float4.
      Parameters:
      from - the source type (must be int4)
      to - the destination type (must be float4)
      mv - the method visitor
      Returns:
      the destination type (float4)
    • generateToFloat

      static JitType.FloatJitType generateToFloat(JitType from, JitType.FloatJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit bytecode to convert any (compatible) type to a float4.
      Parameters:
      from - the source type (int4 or float4)
      to - the destination type
      mv - the method visitor
      Returns:
      the destination type (float4)
    • generateLongToDouble

      static JitType.DoubleJitType generateLongToDouble(JitType.LongJitType from, JitType.DoubleJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit bytecode to convert an int8 to a float8.
      Parameters:
      from - the source type (must be int8)
      to - the destination type (must be float8)
      mv - the method visitor
      Returns:
      the destination type (float8)
    • generateToDouble

      static JitType.DoubleJitType generateToDouble(JitType from, JitType.DoubleJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit bytecode to convert any (compatible) type to a float8.
      Parameters:
      from - the source type (int8 or float8)
      to - the destination type
      mv - the method visitor
      Returns:
      the destination type (float8)
    • generateIntToMpInt

      static JitType.MpIntJitType generateIntToMpInt(JitType.IntJitType from, JitType.MpIntJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit bytecode to convert a p-code int that fits in a JVM int to a multi-precision int.
      Parameters:
      from - the source type
      to - the destination type
      mv - the method visitor
      Returns:
      the destination type
    • generateLongToMpInt

      static JitType.MpIntJitType generateLongToMpInt(JitType.LongJitType from, JitType.MpIntJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit bytecode to convert a p-code int that its int a JVM long to multi-precision int.
      Parameters:
      from - the source type
      to - the destination type
      mv - the method visitor
      Returns:
      the destination type
    • generateMpIntToMpInt

      static JitType.MpIntJitType generateMpIntToMpInt(JitCodeGenerator gen, JitType.MpIntJitType from, JitType.MpIntJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit bytecode to convert a mult-precision int from one size to another
      Parameters:
      gen - the code generator
      from - the source type
      to - the destination type
      mv - the method visitor
      Returns:
      the destination type
    • generateToMpInt

      static JitType.MpIntJitType generateToMpInt(JitCodeGenerator gen, JitType from, JitType.MpIntJitType to, org.objectweb.asm.MethodVisitor mv)
      Emit bytecode to convert any (compatible) type to a p-code int that fits in a JVM int.

      No floating-point source types are currently acceptable. Support for floats of size other than 4 and 8 bytes is a work in progress.

      Parameters:
      gen - the code generator
      from - the source type
      to - the destination type
      mv - the method visitor
      Returns:
      the destination type
    • generate

      static JitType generate(JitCodeGenerator gen, JitType from, JitType to, org.objectweb.asm.MethodVisitor mv)
      Emit bytecode to convert the value on top of the JVM stack from one p-code type to another.

      If the source and destination are already of the same type, or if conversion between them does not require any bytecode, then no bytecode is emitted.

      Parameters:
      gen - the code generator
      from - the source type
      to - the destination type
      mv - the method visitor
      Returns:
      the resulting (destination) type
    • generateIntToBool

      static void generateIntToBool(JitType from, org.objectweb.asm.MethodVisitor mv)
      Collapse an mp-int or long to a single int.

      If and only if the input is all zeros will the output also be all zeros. Otherwise, the output can be any non-zero value.

      There is no explicit "boolean" p-code type. Instead, like C, many of the operators take an int type and require "false" to be represented by the value 0. Any non-zero value is interpreted as "true." That said, conventionally, all p-code booleans ought to be an int1 where "true" is represented by 1 and "false" is represented by 0. The p-code operators that output "boolean" values are all implemented to follow this convention, except that size is determined by the Slaspec author.

      This conversion deals with input operands used as booleans that do not conform to these conventions. If, e.g., a cbranch is given a condition operand of type int8, we have to ensure that all bits, not just the lower 32, are considered. This is trivially accomplished by pushing 0L and emitting an Opcodes.LCMP, which consumes the JVM long and replaces it with a JVM int representing the same boolean value. For multi-precision ints, we reduce all the legs using Opcodes.IOR. If a float is used as a boolean, it must be converted to an int first.

      Parameters:
      from - the type of the value currently on the stack
      mv - the method visitor
      See Also:
    • generatePop

      static void generatePop(JitType type, org.objectweb.asm.MethodVisitor mv)
      Remove a value of the given type from the JVM stack.

      Depending on the type, we must emit either Opcodes.POP or Opcodes.POP2. This is used to ignore an input or drop an output. For example, the boolean operators may short circuit examination of the second operand, in which case it must be popped. Also, if a userop returns a value, but the p-code does not provide an output operand, the return value must be popped.

      Parameters:
      type - the type
      mv - the method visitor
    • generateLdcTrue

      static void generateLdcTrue(JitType type, org.objectweb.asm.MethodVisitor mv)
      Generate a "boolean" true value of the given type

      This performs the inverse of generateIntToBool(JitType, MethodVisitor), but for the constant "true." Instead of loading a constant 1 into an int1 and then converting to the desired type, this can just load the constant 1 directly as the desired type.

      This is often used with conditional jumps to produce a boolean output.

      Parameters:
      type - an integer type
      mv - the method visitor
      See Also:
    • generateLdcFalse

      static void generateLdcFalse(JitType type, org.objectweb.asm.MethodVisitor mv)
      Generate a "boolean" false value of the given type

      This performs the inverse of generateIntToBool(JitType, MethodVisitor), but for the constant "false." Instead of loading a constant 0 into an int1 and then converting to the desired type, this can just load the constant 0 directly as the desired type.

      This is often used with conditional jumps to produce a boolean output.

      Parameters:
      type - an integer type
      mv - the method visitor
      See Also:
    • generateSExt

      static JitType generateSExt(JitType type, org.objectweb.asm.MethodVisitor mv)
      Emit code to extend a signed value of the given type to fill its host JVM type.

      This is implemented in the same manner as int_sext.

      Parameters:
      type - the p-code type
      mv - the method visitor
      Returns:
      the p-code type that exactly fits the host JVM type, i.e., the resulting p-code type.
    • generateSExtIntToLong

      static JitType.LongJitType generateSExtIntToLong(org.objectweb.asm.MethodVisitor mv)
      Convert a signed int4 to int8.

      Note that if conversion from a smaller int type is needed, the generator must first call generateSExt(JitType, MethodVisitor).

      Parameters:
      mv - the method visitor
      Returns:
      the resulting type (int8)
    • forceUniformZExt

      static JitType forceUniformZExt(JitType myType, JitType otherType, org.objectweb.asm.MethodVisitor mv)
      Select the larger of two types and emit code to convert an unsigned value of the first type to the host JVM type of the selected type.

      JVM bytecodes for binary operators often require that both operands have the same size. Consider that the JVM provides a Opcodes.IADD and a Opcodes.LADD, but no "ILADD". Both operands must be JVM ints, or both must be JVM longs. This method provides an idiom for converting both operands to the same type. Ideally, we choose the smallest type possible (as opposed to just converting everything to long always), but we must choose a type large enough to accommodate the larger of the two p-code operands.

      For a binary operator requiring type uniformity, we must apply this method immediately after loading each operand onto the stack. That operand's type is passed as myType and the type of the other operand as otherType. Consider the left operand. We must override afterLeft if we're using BinOpGen. If the left type is the larger, then we select it and we need only extend the left operand to fill its host JVM type. (We'll deal with the right operand in a moment.) If the right type is larger, then we select it and we extend the left to fill the right's host JVM type. We then return the resulting left type so that we'll know what it was when emitting the actual operator bytecodes. Things work similarly for the right operand, which we handle within generateBinOpRunCode if we're using it. The two resulting types should now be equal, and we can examine them and emit the correct bytecodes.

      Parameters:
      myType - the type of an operand, probably in a binary operator
      otherType - the type of the other operand of a binary operator
      mv - the method visitor
      Returns:
      the new type of the operand
    • forceUniformSExt

      static JitType forceUniformSExt(JitType myType, JitType otherType, org.objectweb.asm.MethodVisitor mv)
      Do the same as forceUniformZExt(JitType, JitType, MethodVisitor), but with signed values.
      Parameters:
      myType - the type of an operand, probably in a binary operator
      otherType - the type of the other operand of a binary operator
      mv - the method visitor
      Returns:
      the new type of the operand