Package erjang.beam.repr

Source Code of erjang.beam.repr.Insn$I

/** -*- tab-width: 4 -*-
* This file is part of Erjang - A JVM-based Erlang VM
*
* Copyright (c) 2010 by Trifork
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/

package erjang.beam.repr;

import static erjang.beam.CodeAtoms.ARITHFBIF_ATOM;
import static erjang.beam.CodeAtoms.ATOM_ATOM;
import static erjang.beam.CodeAtoms.BIF_ATOM;
import static erjang.beam.CodeAtoms.FIELD_FLAGS_ATOM;
import static erjang.beam.CodeAtoms.F_ATOM;
import static erjang.beam.CodeAtoms.GCBIF_ATOM;
import static erjang.beam.CodeAtoms.NOFAIL_ATOM;
import static erjang.beam.CodeAtoms.START_ATOM;
import static erjang.beam.CodeAtoms.TEST_ATOM;
import erjang.EList;
import erjang.EObject;
import erjang.ERT;
import erjang.ESmall;
import erjang.ETuple;
import erjang.beam.BeamInstruction;
import erjang.beam.BeamOpcode;
import erjang.beam.repr.Operands.AllocList;
import erjang.beam.repr.Operands.Atom;
import erjang.beam.repr.Operands.BitString;
import erjang.beam.repr.Operands.ByteString;
import erjang.beam.repr.Operands.DestinationOperand;
import erjang.beam.repr.Operands.Label;
import erjang.beam.repr.Operands.SelectList;
import erjang.beam.repr.Operands.SourceOperand;
import erjang.beam.repr.Operands.XReg;
import erjang.beam.repr.Operands.YReg;

public class Insn implements BeamInstruction {
  protected final BeamOpcode opcode;
  public Insn(BeamOpcode opcode) {this.opcode = opcode;}
  public BeamOpcode opcode() {return opcode;}

  public String toString() {return toSymbolic().toString();}
  public EObject toSymbolic() {
      return opcode.symbol;
  }
  public final ETuple toSymbolicTuple() {
    EObject symInsn0 = toSymbolic();
    ETuple symInsn = (symInsn0 instanceof ETuple)?
      ((ETuple)symInsn0) : ETuple.make(symInsn0);
    return symInsn;
  }

  private static EObject NOFAIL_REPR = ETuple.make(F_ATOM, new ESmall(0));
  private static EObject START_REPR = ETuple.make(ATOM_ATOM, START_ATOM);
  static EObject labelToSymbolic(Label label) {
    return label==null? NOFAIL_REPR : label.toSymbolic();
  }
  static EObject labelToSymbolic_nf(Label label) {
    return label==null? NOFAIL_ATOM : label.toSymbolic();
  }

  static EObject bsFieldFlagsToSymbolic(int flags) {
    return ETuple.make(FIELD_FLAGS_ATOM, new ESmall(flags));
  }
  /*============================================================
   *                     Instruction formats
   * Class names encode the format - the parameter types - as follows:
   * I - Integer
   * A - Atom
   * Bi - Bitstring
   * By - Bytestring
   * S - Source operand: register or literal
   * D - Destination operand: register
   * L - Label
   * K - Optional label (fail label)
   * E - External function
   * F - Anonymous function object
   * W - Allocation size
   */

  public static class I extends Insn { // E.g. 'deallocate'
    public final int i1;
    public I(BeamOpcode opcode, int i1) {
      super(opcode);
      this.i1 = i1;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol, new ESmall(i1));
    }
  }

  public static class S extends Insn { // E.g. 'put'
    public final SourceOperand src;
    public S(BeamOpcode opcode, SourceOperand src) {
      super(opcode);
      this.src = src;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol, src.toSymbolic());
    }
  }

  public static class D extends Insn { // E.g. 'init'
    public final DestinationOperand dest;
    public D(BeamOpcode opcode, DestinationOperand dest) {
      super(opcode);
      this.dest = dest;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol, dest.toSymbolic());
    }
  }

  public static class L extends Insn { // E.g. 'jump'
    public final Label label;
    public L(BeamOpcode opcode, Label label) {
      super(opcode);
      this.label = label;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol, label.toSymbolic());
    }
  }

  public static class F extends Insn { // E.g. 'make_fun2'
    public final int anon_fun_no;
    public final AnonFun anon_fun;
    public F(BeamOpcode opcode, int anon_fun_no, AnonFun anon_fun) {
      super(opcode);
      this.anon_fun_no = anon_fun_no;
      this.anon_fun = anon_fun;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 anon_fun.toSymbolic(),
                 new ESmall(anon_fun_no),
                 new ESmall(anon_fun.old_uniq),
                 new ESmall(anon_fun.free_vars));
    }
  }

  public static class Y extends Insn { // E.g. 'catch'
    public final YReg y;
    public Y(BeamOpcode opcode, YReg y) {
      super(opcode);
      this.y = y;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol, y.toSymbolic());
    }
  }

  public static class By extends Insn { // E.g. 'bs_put_string'
    public final ByteString bin;
    public By(BeamOpcode opcode, ByteString bin) {
      super(opcode);
      this.bin = bin;
    }

    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 new ESmall(bin.byteLength()),
                 bin.toSymbolic());
    }
  }

  public static class DI extends Insn { // E.g. 'bs_save2'
    public final DestinationOperand dest;
    public final int i2;
    public final boolean is_saverestore;
    public DI(BeamOpcode opcode, DestinationOperand dest, int i2, boolean is_saverestore) {
      super(opcode);
      this.dest = dest;
      this.i2 = i2;
      this.is_saverestore = is_saverestore;
    }
    public ETuple toSymbolic() {
      if (is_saverestore)
        return ETuple.make(opcode.symbol,
                   dest.toSymbolic(),
                   (i2==-1 ? START_REPR : new ESmall(i2)));
      else
        return ETuple.make(opcode.symbol,
                   dest.toSymbolic(),
                   new ESmall(i2));
    }
  }

  public static class SD extends Insn { // E.g. 'move'
    public final SourceOperand src;
    public final DestinationOperand dest;
    public SD(BeamOpcode opcode, SourceOperand src, DestinationOperand dest) {
      super(opcode);
      this.src = src;
      this.dest = dest;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 src.toSymbolic(),
                 dest.toSymbolic());
    }
  }

  public static class LD extends L { // E.g. 'loop_rec'
    public final DestinationOperand dest;
    public final boolean is_test;
    public LD(BeamOpcode opcode, Label label, DestinationOperand dest) {
      super(opcode, label);
      this.dest = dest;
      this.is_test = false;
    }
    public LD(BeamOpcode opcode, Label label, DestinationOperand dest, boolean is_test) {
      super(opcode, label);
      this.dest = dest;
      this.is_test = is_test;
    }
    public ETuple toSymbolic() {
      if (is_test)
        return ETuple.make(TEST_ATOM,
                   opcode.symbol,
                   label.toSymbolic(),
                   EList.make(dest.toSymbolic()));
      else
        return ETuple.make(opcode.symbol,
                   label.toSymbolic(),
                   dest.toSymbolic());
    }
  }

  public static class YL extends Insn { // E.g. 'catch'
    public final YReg y;
    public final Label label;
    public YL(BeamOpcode opcode, YReg y, Label label) {
      super(opcode);
      this.y = y;
      this.label = label;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 y.toSymbolic(),
                 label.toSymbolic());
    }
  }

  public static class LS extends L { // E.g. 'is_nil'
    public final SourceOperand src;
    public final boolean is_test;
    public LS(BeamOpcode opcode, Label label, SourceOperand src, boolean is_test) {
      super(opcode, label);
      this.src = src;
      this.is_test = is_test;
    }
    public ETuple toSymbolic() {
      if (is_test)
        return ETuple.make(TEST_ATOM,
                   opcode.symbol,
                   label.toSymbolic(),
                   EList.make(src.toSymbolic()));
      else
        return ETuple.make(opcode.symbol,
                   label.toSymbolic(),
                   src.toSymbolic());
    }
  }

  public static class II extends I { // E.g. 'allocate'
    public final int i2;
    public II(BeamOpcode opcode, int i1, int i2) {
      super(opcode, i1);
      this.i2 = i2;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 new ESmall(i1),
                 new ESmall(i2));
    }
  }

  public static class IL extends I { // E.g. 'call'
    public final Label label;
    public final boolean is_call;
    public final FunctionInfo functionAtLabel;

    public IL(BeamOpcode opcode, int i1, Label label,  FunctionInfo fal) {
      super(opcode, i1);
      this.label = label;
      this.is_call = true;
      this.functionAtLabel = fal;
    }

    public ETuple toSymbolic() {
      if (is_call)
        return ETuple.make(opcode.symbol,
                   new ESmall(i1),
                   functionAtLabel.toSymbolic());
      else
        return ETuple.make(opcode.symbol,
                   new ESmall(i1),
                   label.toSymbolic());
    }
  }

  public static class SS extends Insn { // E.g. 'raise'
    public final SourceOperand src1, src2;
    public SS(BeamOpcode opcode, SourceOperand src1, SourceOperand src2) {
      super(opcode);
      this.src1 = src1;
      this.src2 = src2;
    }
    public ETuple toSymbolic() {
      if (opcode == BeamOpcode.raise)
        return ETuple.make(opcode.symbol,
                   new Label(0).toSymbolic(),
                   EList.make(src1.toSymbolic(),
                        src2.toSymbolic()),
                   XReg.get(0).toSymbolic());
      else
        return ETuple.make(opcode.symbol,
                   src1.toSymbolic(),
                   src2.toSymbolic());
    }
  }

  public static class AAI extends Insn { // E.g. 'func_info'
    public final Atom a1,a2;
    public final int i3;
    public AAI(BeamOpcode opcode, Atom a1, Atom a2, int i3) {
      super(opcode);
      this.a1 = a1;
      this.a2 = a2;
      this.i3 = i3;
    }

    public ExtFun getExtFun() {
      return new ExtFun(a1.getEAtom(), a2.getEAtom(), i3);
    }

    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 a1.toSymbolic(),
                 a2.toSymbolic(),
                 new ESmall(i3));
    }
  }

  public static class IE extends I { // E.g. 'call_ext'
    public final ExtFun ext_fun;
    public IE(BeamOpcode opcode, int i1, ExtFun ext_fun) {
      super(opcode, i1);
      this.ext_fun = ext_fun;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 new ESmall(i1),
                 ext_fun.toSymbolic());
    }
  }

  public static class ID extends Insn { // E.g. 'put_tuple'
    public final int i1;
    public final DestinationOperand dest;
    public ID(BeamOpcode opcode, int i1, DestinationOperand dest) {
      super(opcode);
      this.i1 = i1;
      this.dest = dest;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 new ESmall(i1),
                 dest.toSymbolic());
    }
  }

  public static class WI extends Insn { // E.g. 'test_heap'
    public final AllocList alist;
    public final int i2;
    public WI(BeamOpcode opcode, AllocList alist, int i2) {
      super(opcode);
      this.alist = alist;
      this.i2 = i2;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 alist.toSymbolic(),
                 new ESmall(i2));
    }
  }

  public static class IWI extends I { // E.g. 'allocate_heap'
    public final int i3;
    public final AllocList al;
    public IWI(BeamOpcode opcode, int i1, AllocList al, int i3) {
      super(opcode, i1);
      this.al = al;
      this.i3 = i3;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 new ESmall(i1),
                 al.toSymbolic(),
                 new ESmall(i3));
    }
  }

  public static class LDI extends LD { // E.g. 'test_arity'
    public final int i;
    public LDI(BeamOpcode opcode, Label label, DestinationOperand dest, int i, boolean is_test) {
      super(opcode, label, dest, is_test);
      this.i = i;
    }
    public ETuple toSymbolic() {
      if (is_test)
        return ETuple.make(TEST_ATOM,
                   opcode.symbol,
                   label.toSymbolic(),
                   EList.make(dest.toSymbolic(),
                        new ESmall(i)));
      else
        return ETuple.make(opcode.symbol,
                   label.toSymbolic(),
                   dest.toSymbolic(),
                   new ESmall(i));
    }
  }

  public static class SID extends Insn { // E.g. 'get_tuple_element'
    public final SourceOperand src;
    public final int i;
    public final DestinationOperand dest;
    public SID(BeamOpcode opcode, SourceOperand src, int i, DestinationOperand dest) {
      super(opcode);
      this.src = src;
      this.i = i;
      this.dest = dest;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 src.toSymbolic(),
                 new ESmall(i),
                 dest.toSymbolic());
    }
  }

  public static class LSS extends L { // E.g. 'is_eq_exact'
    public final SourceOperand src1, src2;
    public final boolean is_test;
    public LSS(BeamOpcode opcode, Label label, SourceOperand src1, SourceOperand src2, boolean is_test) {
      super(opcode, label);
      this.src1 = src1;
      this.src2 = src2;
      this.is_test = is_test;
    }
    public ETuple toSymbolic() {
      if (is_test)
        return ETuple.make(TEST_ATOM,
                   opcode.symbol,
                   label.toSymbolic(),
                   EList.make(src1.toSymbolic(),
                        src2.toSymbolic()));
      else
        return ETuple.make(opcode.symbol,
                   label.toSymbolic(),
                   src1.toSymbolic(),
                   src2.toSymbolic());
    }
  }

  public static class LDS extends LD { // E.g. 'is_function2'
    public final SourceOperand src;
    public LDS(BeamOpcode opcode, Label label, DestinationOperand dest, SourceOperand src, boolean is_test) {
      super(opcode, label, dest, is_test);
      this.src = src;
    }

    public ETuple toSymbolic() {
      if (is_test)
        return ETuple.make(TEST_ATOM,
                   opcode.symbol,
                   label.toSymbolic(),
                   EList.make(dest.toSymbolic(),
                        src.toSymbolic()));
      else
        return ETuple.make(opcode.symbol,
                   label.toSymbolic(),
                   dest.toSymbolic(),
                   src.toSymbolic());
    }
  }

  public static class LSD extends Insn { // E.g. 'bs_utf8_size'
    public final Label label;
    public final SourceOperand src;
    public final DestinationOperand dest;
    public LSD(BeamOpcode opcode, Label label, SourceOperand src, DestinationOperand dest) {
      super(opcode);
      this.label = label;
      this.src = src;
      this.dest = dest;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 label.toSymbolic(),
                 src.toSymbolic(),
                 dest.toSymbolic());
    }
  }

  public static class SDD extends Insn { // E.g. 'get_list'
    public final SourceOperand src;
    public final DestinationOperand dest1;
    public final DestinationOperand dest2;
    public SDD(BeamOpcode opcode, SourceOperand src, DestinationOperand dest1, DestinationOperand dest2) {
      super(opcode);
      this.src = src;
      this.dest1 = dest1;
      this.dest2 = dest2;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 src.toSymbolic(),
                 dest1.toSymbolic(),
                 dest2.toSymbolic());
    }
  }

  public static class SSD extends Insn { // E.g. 'move'
    public final SourceOperand src1;
    public final SourceOperand src2;
    public final DestinationOperand dest;
    public SSD(BeamOpcode opcode, SourceOperand src1, SourceOperand src2, DestinationOperand dest) {
      super(opcode);
      this.src1 = src1;
      this.src2 = src2;
      this.dest = dest;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 src1.toSymbolic(),
                 src2.toSymbolic(),
                 dest.toSymbolic());
    }
  }

  public static class SDI extends Insn { // E.g. 'set_tuple_element'
    public final SourceOperand src;
    public final DestinationOperand dest;
    public final int i;
    public SDI(BeamOpcode opcode, SourceOperand src, DestinationOperand dest, int i) {
      super(opcode);
      this.src = src;
      this.dest = dest;
      this.i = i;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 src.toSymbolic(),
                 dest.toSymbolic(),
                 new ESmall(i));
    }
  }


  public static class ILI extends IL { // E.g. 'call'
    public final int i3;
    public final boolean is_call;
    public ILI(BeamOpcode opcode, int i1, Label label, int i3, FunctionInfo fal) {
      super(opcode, i1, label, fal);
      this.i3 = i3;
      this.is_call = true;
    }

    public ETuple toSymbolic() {
      if (is_call)
        return ETuple.make(opcode.symbol,
                   new ESmall(i1),
                   functionAtLabel.toSymbolic(),
                   new ESmall(i3));
      else
        return ETuple.make(opcode.symbol,
                   new ESmall(i1),
                   label.toSymbolic(),
                   new ESmall(i3));
    }
  }

  public static class IEI extends IE { // E.g. 'call'
    public final int i3;
    public IEI(BeamOpcode opcode, int i1, ExtFun ext_fun, int i3) {
      super(opcode, i1, ext_fun);
      this.i3 = i3;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 new ESmall(i1),
                 ext_fun.toSymbolic(),
                 new ESmall(i3));
    }
  }

  public static class ByD extends Insn { // E.g. 'put_string'
    public final ByteString bin;
    public final DestinationOperand dest;
    public ByD(BeamOpcode opcode, ByteString bin, DestinationOperand dest) {
      super(opcode);
      this.bin = bin;
      this.dest = dest;
    }

    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 new ESmall(bin.byteLength()),
                 bin.toSymbolic(),
                 dest.toSymbolic());
    }
  }

  public static class LSSD extends Insn { // E.g. 'fmul'
    public final Label label;
    public final SourceOperand src1;
    public final SourceOperand src2;
    public final DestinationOperand dest;
    public final boolean is_arithfbif;
    public LSSD(BeamOpcode opcode, Label label,
          SourceOperand src1, SourceOperand src2,
          DestinationOperand dest,
          boolean is_arithfbif)
    {
      super(opcode);
      this.label = label;
      this.src1 = src1;
      this.src2 = src2;
      this.dest = dest;
      this.is_arithfbif = is_arithfbif;
    }
    public ETuple toSymbolic() {
      if (is_arithfbif)
        return ETuple.make(ARITHFBIF_ATOM,
                   opcode.symbol,
                   label.toSymbolic(),
                   EList.make(src1.toSymbolic(),
                        src2.toSymbolic()),
                   dest.toSymbolic());
      else
        return ETuple.make(opcode.symbol,
                   label.toSymbolic(),
                   src1.toSymbolic(),
                   src2.toSymbolic(),
                   dest.toSymbolic());
    }
  }

  public static class LSSID extends Insn { // E.g. 'bs_add'
    public final Label label;
    public final SourceOperand src1;
    public final SourceOperand src2;
    public final int i3;
    public final DestinationOperand dest;
    public LSSID(BeamOpcode opcode, Label label,
           SourceOperand src1, SourceOperand src2,
           int i3, DestinationOperand dest)
    {
      super(opcode);
      this.label = label;
      this.src1 = src1;
      this.src2 = src2;
      this.i3 = i3;
      this.dest = dest;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 label.toSymbolic(),
                 EList.make(src1.toSymbolic(),
                      src2.toSymbolic(),
                      new ESmall(i3)),
                 dest.toSymbolic());
    }
  }

  public static class LDBi extends LD { // E.g. 'bs_match_string'
    public final BitString bin;
    public LDBi(BeamOpcode opcode, Label label, DestinationOperand dest, BitString bin) {
      super(opcode, label, dest, true);
      this.bin = bin;
    }

    public ETuple toSymbolic() {
      return ETuple.make(TEST_ATOM,
                 opcode.symbol,
                 label.toSymbolic(),
                 EList.make(dest.toSymbolic(),
                      ERT.box(bin.bitLength()),
                      bin.toSymbolic()));
    }
  }

  public static class LDII extends LD { // E.g. 'bs_skip_utf8'
    public final int i3, i4;
    public LDII(BeamOpcode opcode, Label label, DestinationOperand dest, int i3, int i4) {
      super(opcode, label, dest, true);
      this.i3 = i3;
      this.i4 = i4;
    }

    public ETuple toSymbolic() {
      return ETuple.make(TEST_ATOM,
                 opcode.symbol,
                 label.toSymbolic(),
                 EList.make(dest.toSymbolic(),
                      new ESmall(i3),
                      bsFieldFlagsToSymbolic(i4)));
    }
  }


  public static class LSIIS extends Insn { // E.g. 'bs_put_integer'
    public final Label label;
    public final SourceOperand src2, src5;
    public final int i3, i4;
    public final boolean is_bs;
    public LSIIS(BeamOpcode opcode, Label label, SourceOperand src2, int i3, int i4, SourceOperand src5, boolean is_bs) {
      super(opcode);
      this.label = label;
      this.src2 = src2;
      this.i3 = i3;
      this.i4 = i4;
      this.src5 = src5;
      this.is_bs = is_bs;
    }

    public ETuple toSymbolic() {
      if (is_bs)
        return ETuple.make(opcode.symbol,
                   label.toSymbolic(),
                   src2.toSymbolic(),
                   new ESmall(i3),
                   bsFieldFlagsToSymbolic(i4),
                   src5.toSymbolic());
      else
        throw new erjang.NotImplemented();
    }
  }

  public static class LIS extends Insn { // E.g. 'bs_put_utf8'
    public final Label label;
    public final int i2;
    public final SourceOperand src;
    public final boolean is_bsput;
    public LIS(BeamOpcode opcode, Label label, int i2, SourceOperand src, boolean is_bsput) {
      super(opcode);
      this.label = label;
      this.i2 = i2;
      this.src = src;
      this.is_bsput = is_bsput;
    }

    public ETuple toSymbolic() {
      if (is_bsput)
        return ETuple.make(opcode.symbol,
                   label.toSymbolic(),
                   bsFieldFlagsToSymbolic(i2),
                   src.toSymbolic());
      else
        throw new erjang.NotImplemented();
    }
  }


  public static class LDIID extends LD { // E.g. 'bs_start_match2'
    public final int i3, i4;
    public final DestinationOperand dest5;
    public final boolean i4_is_bsflags;
    public LDIID(BeamOpcode opcode, Label label, DestinationOperand dest2, int i3, int i4, DestinationOperand dest5, boolean i4_is_bsflags) {
      super(opcode, label, dest2, true);
      this.i3 = i3;
      this.i4 = i4;
      this.dest5 = dest5;
      this.i4_is_bsflags = i4_is_bsflags;
    }

    public ETuple toSymbolic() {
      return ETuple.make(TEST_ATOM,
                 opcode.symbol,
                 label.toSymbolic(),
                 EList.make(dest.toSymbolic(),
                      new ESmall(i3),
                      i4_is_bsflags
                      ? bsFieldFlagsToSymbolic(i4)
                      : new ESmall(i4),
                      dest5.toSymbolic()));
    }
  }

  public static class LSIIID extends Insn { // E.g. 'bs_init2'
    public final Label label;
    public final SourceOperand src2;
    public final int i3, i4,i5;
    public final DestinationOperand dest;
    public final boolean is_bs;
    public LSIIID(BeamOpcode opcode, Label label,
            SourceOperand src2,
            int i3, int i4, int i5,
            DestinationOperand dest,
            boolean is_bs)
    {
      super(opcode);
      this.label = label;
      this.src2 = src2;
      this.i3 = i3;
      this.i4 = i4;
      this.i5 = i5;
      this.dest = dest;
      this.is_bs = is_bs;
    }

    public ETuple toSymbolic() {
      if (is_bs)
        return ETuple.make(opcode.symbol,
                   labelToSymbolic(label),
                   src2.toSymbolic(),
                   new ESmall(i3),
                   new ESmall(i4),
                   bsFieldFlagsToSymbolic(i5),
                   dest.toSymbolic());
      else
        throw new erjang.NotImplemented();
    }
  }

  public static class LDSII extends LD { // E.g. 'bs_skip_bits2'
    public final SourceOperand src3;
    public final int i4, i5;

    public LDSII(BeamOpcode opcode, Label label,
           DestinationOperand dest, SourceOperand src3,
           int i4, int i5)
    {
      super(opcode, label, dest, true);
      this.src3 = src3;
      this.i4 = i4;
      this.i5 = i5;
    }
    public ETuple toSymbolic() {
      return ETuple.make(TEST_ATOM,
                 opcode.symbol,
                 label.toSymbolic(),
                 EList.make(dest.toSymbolic(),
                      src3.toSymbolic(),
                      new ESmall(i4),
                      bsFieldFlagsToSymbolic(i5)));
    }
  }

  public static class LDISIID extends LD { // E.g. 'bs_get_integer2'
    public final int i3;
    public final SourceOperand src4;
    public final int i5, i6;
    public final DestinationOperand dest7;

    public LDISIID(BeamOpcode opcode, Label label,
             DestinationOperand dest2, int i3,
             SourceOperand src4, int i5, int i6,
             DestinationOperand dest7)
    {
      super(opcode, label, dest2, true);
      this.i3 = i3;
      this.src4 = src4;
      this.i5 = i5;
      this.i6 = i6;
      this.dest7 = dest7;
    }
    public ETuple toSymbolic() {
      if (is_test)
        return ETuple.make(TEST_ATOM,
                   opcode.symbol,
                   label.toSymbolic(),
                   EList.make(dest.toSymbolic(),
                        new ESmall(i3),
                        src4.toSymbolic(),
                        new ESmall(i5),
                        bsFieldFlagsToSymbolic(i6),
                        dest7.toSymbolic()));
      else
        throw new erjang.NotImplemented();
    }
  }

  //============================================================

  public static class Bif extends Insn { // 'bif0-2'
    public final Label label;
    public final ExtFun ext_fun;
    public final SourceOperand[] args;
    public final DestinationOperand dest;
    protected Bif(BeamOpcode opcode, Label label, ExtFun ext_fun, SourceOperand[] args, DestinationOperand dest) {
      super(opcode);
      this.label = label;
      this.ext_fun = ext_fun;
      this.dest = dest;
      this.args = args;
    }

    private static SourceOperand[] NO_ARGS = new SourceOperand[] {};
    public Bif(BeamOpcode opcode, Label label, ExtFun ext_fun, DestinationOperand dest) {
      this(opcode, label, ext_fun, NO_ARGS, dest);
    }
    public Bif(BeamOpcode opcode, Label label, ExtFun ext_fun, SourceOperand src, DestinationOperand dest) {
      this(opcode, label, ext_fun, new SourceOperand[] {src}, dest);
    }
    public Bif(BeamOpcode opcode, Label label, ExtFun ext_fun, SourceOperand src1, SourceOperand src2, DestinationOperand dest) {
      this(opcode, label, ext_fun, new SourceOperand[] {src1, src2}, dest);
    }

    public SourceOperand[] argList() {return args;}

    public ETuple toSymbolic() {
      return ETuple.make(BIF_ATOM,
                 ext_fun.fun,
                 labelToSymbolic_nf(label),
                 Operands.toSymbolicList(args),
                 dest.toSymbolic());
    }
  }



  public static class GcBif extends Insn { // 'gc_bif1-2'
    public final Label label;
    public final ExtFun ext_fun;
    public final int i;
    public final SourceOperand[] args;
    public final DestinationOperand dest;
    protected GcBif(BeamOpcode opcode, Label label, ExtFun ext_fun, int i, SourceOperand[] args, DestinationOperand dest) {
      super(opcode);
      this.label = label;
      this.ext_fun = ext_fun;
      this.i = i;
      this.args = args;
      this.dest = dest;
    }

    public GcBif(BeamOpcode opcode, Label label, ExtFun ext_fun, int i, SourceOperand src, DestinationOperand dest) {
      this(opcode, label, ext_fun, i, new SourceOperand[]{src}, dest);
    }
    public GcBif(BeamOpcode opcode, Label label, ExtFun ext_fun, int i, SourceOperand src1, SourceOperand src2, DestinationOperand dest) {
      this(opcode, label, ext_fun, i, new SourceOperand[]{src1,src2}, dest);
    }
    public GcBif(BeamOpcode opcode, Label label, ExtFun ext_fun, int i, SourceOperand src1, SourceOperand src2, SourceOperand src3, DestinationOperand dest) {
      this(opcode, label, ext_fun, i, new SourceOperand[]{src1,src2,src3}, dest);
    }

    public SourceOperand[] argList() {return args;}

    public ETuple toSymbolic() {
      return ETuple.make(GCBIF_ATOM,
                 ext_fun.fun,
                 label.toSymbolic(),
                 new ESmall(i),
                 Operands.toSymbolicList(args),
                 dest.toSymbolic());
    }
  }

  public static class Select extends Insn { // E.g. 'select_val'
    public final SourceOperand src;
    public final Label defaultLabel;
    public final SelectList jumpTable; // TODO: Improve representation.
    public Select(BeamOpcode opcode,
            SourceOperand src,
            Label defaultLabel,
            SelectList jumpTable)
    {
      super(opcode);
      this.src = src;
      this.defaultLabel = defaultLabel;
      this.jumpTable = jumpTable;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 src.toSymbolic(),
                 defaultLabel.toSymbolic(),
                 jumpTable.toSymbolic());
    }
  }

  public static class BSAppend extends Insn { // E.g. 'bs_append'
    // LSIIISID
    public final Label label;
    public final SourceOperand src2;
    public final int i3, i4, i5, i7;
    public final SourceOperand src6;
    public final DestinationOperand dest8;
    public BSAppend(BeamOpcode opcode, Label label, SourceOperand src2, int i3, int i4, int i5, SourceOperand src6, int i7, DestinationOperand dest8) {
      super(opcode);
      this.label = label;
      this.src2 = src2;
      this.i3 = i3;
      this.i4 = i4;
      this.i5 = i5;
      this.src6 = src6;
      this.i7 = i7;
      this.dest8 = dest8;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 label.toSymbolic(),
                 src2.toSymbolic(),
                 new ESmall(i3),
                 new ESmall(i4),
                 new ESmall(i5),
                 src6.toSymbolic(),
                 bsFieldFlagsToSymbolic(i7),
                 dest8.toSymbolic());
    }
  }

  public static class BSPrivateAppend extends Insn { // E.g. 'bs_private_append'
    //  // LSISID
    public final Label label;
    public final SourceOperand src2, src4;
    public final int i3, i5;
    public final DestinationOperand dest;
    public BSPrivateAppend(BeamOpcode opcode, Label label, SourceOperand src2, int i3, SourceOperand src4, int i5, DestinationOperand dest) {
      super(opcode);
      this.label = label;
      this.src2 = src2;
      this.i3 = i3;
      this.src4 = src4;
      this.i5 = i5;
      this.dest = dest;
    }
    public ETuple toSymbolic() {
      return ETuple.make(opcode.symbol,
                 label.toSymbolic(),
                 src2.toSymbolic(),
                 new ESmall(i3),
                 src4.toSymbolic(),
                 bsFieldFlagsToSymbolic(i5),
                 dest.toSymbolic());
    }
  }
}
TOP

Related Classes of erjang.beam.repr.Insn$I

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.