/** -*-c-*-
  This file contains instruction information for yarv instruction sequence.
  
  ----
  This file is auto generated by insns2vm.rb
  DO NOT TOUCH!
  
  If you want to fix something, you must edit 'template/insns_info.inc.tmpl'
  or insns2vm.rb
 */

#define TS_ISEQ 'S'
#define TS_GENTRY 'G'
#define TS_OFFSET 'O'
#define TS_DINDEX 'D'
#define TS_VARIABLE '.'
#define TS_CDHASH 'H'
#define TS_IC 'C'
#define TS_ID 'I'
#define TS_VALUE 'V'
#define TS_LINDEX 'L'
#define TS_NUM 'N'

static char *insn_name_info[] = {
  "nop",
  "getlocal",
  "setlocal",
  "getspecial",
  "setspecial",
  "getdynamic",
  "setdynamic",
  "getinstancevariable",
  "setinstancevariable",
  "getclassvariable",
  "setclassvariable",
  "getconstant",
  "setconstant",
  "getglobal",
  "setglobal",
  "putnil",
  "putself",
  "putundef",
  "putobject",
  "putstring",
  "concatstrings",
  "tostring",
  "toregexp",
  "newarray",
  "duparray",
  "expandarray",
  "concatarray",
  "splatarray",
  "checkincludearray",
  "newhash",
  "newrange",
  "putnot",
  "pop",
  "dup",
  "dupn",
  "swap",
  "reput",
  "topn",
  "setn",
  "emptstack",
  "definemethod",
  "alias",
  "undef",
  "defined",
  "postexe",
  "trace",
  "defineclass",
  "send",
  "invokesuper",
  "invokeblock",
  "leave",
  "finish",
  "throw",
  "jump",
  "branchif",
  "branchunless",
  "getinlinecache",
  "onceinlinecache",
  "setinlinecache",
  "opt_case_dispatch",
  "opt_checkenv",
  "opt_plus",
  "opt_minus",
  "opt_mult",
  "opt_div",
  "opt_mod",
  "opt_eq",
  "opt_lt",
  "opt_le",
  "opt_ltlt",
  "opt_aref",
  "opt_aset",
  "opt_length",
  "opt_succ",
  "opt_regexpmatch1",
  "opt_regexpmatch2",
  "opt_call_native_compiled",
  "bitblt",
  "answer",

};

static char *insn_operand_info[] = {
  "", 
  "L", 
  "L", 
  "NN", 
  "N", 
  "DN", 
  "DN", 
  "I", 
  "I", 
  "I", 
  "I", 
  "I", 
  "I", 
  "G", 
  "G", 
  "", 
  "", 
  "", 
  "V", 
  "V", 
  "N", 
  "", 
  "N", 
  "N", 
  "V", 
  "NN", 
  "", 
  "V", 
  "V", 
  "N", 
  "N", 
  "", 
  "", 
  "", 
  "N", 
  "", 
  "", 
  "N", 
  "N", 
  "", 
  "ISN", 
  "VII", 
  "I", 
  "NVV", 
  "S", 
  "NV", 
  "ISN", 
  "INSNC", 
  "NSN", 
  "NN", 
  "", 
  "", 
  "N", 
  "O", 
  "O", 
  "O", 
  "CO", 
  "CO", 
  "O", 
  "HO", 
  "", 
  "", 
  "", 
  "", 
  "", 
  "", 
  "", 
  "", 
  "", 
  "", 
  "", 
  "", 
  "", 
  "", 
  "V", 
  "", 
  "", 
  "", 
  "", 

};

static int insn_len_info[] = {
  1,
  2,
  2,
  3,
  2,
  3,
  3,
  2,
  2,
  2,
  2,
  2,
  2,
  2,
  2,
  1,
  1,
  1,
  2,
  2,
  2,
  1,
  2,
  2,
  2,
  3,
  1,
  2,
  2,
  2,
  2,
  1,
  1,
  1,
  2,
  1,
  1,
  2,
  2,
  1,
  4,
  4,
  2,
  4,
  2,
  3,
  4,
  6,
  4,
  3,
  1,
  1,
  2,
  2,
  2,
  2,
  3,
  3,
  2,
  3,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  2,
  1,
  1,
  1,
  1,

};

static int insn_stack_push_num_info[] = {
  0,
  1,
  0,
  1,
  0,
  1,
  0,
  1,
  0,
  1,
  0,
  1,
  0,
  1,
  0,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  2,
  1,
  1,
  1,
  0,
  2,
  1,
  2,
  1,
  1,
  1,
  1,
  0,
  0,
  0,
  1,
  0,
  0,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  0,
  0,
  0,
  1,
  1,
  1,
  0,
  0,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  1,
  0,
  1,
  1,

};

static int
insn_stack_increase(int depth, int insn, VALUE *opes)
{
  switch(insn){
      case BIN(nop):{
        return depth + 0;
      }
      case BIN(getlocal):{
        return depth + 1;
      }
      case BIN(setlocal):{
        return depth + -1;
      }
      case BIN(getspecial):{
        return depth + 1;
      }
      case BIN(setspecial):{
        return depth + -1;
      }
      case BIN(getdynamic):{
        return depth + 1;
      }
      case BIN(setdynamic):{
        return depth + -1;
      }
      case BIN(getinstancevariable):{
        return depth + 1;
      }
      case BIN(setinstancevariable):{
        return depth + -1;
      }
      case BIN(getclassvariable):{
        return depth + 1;
      }
      case BIN(setclassvariable):{
        return depth + -1;
      }
      case BIN(getconstant):{
        return depth + 0;
      }
      case BIN(setconstant):{
        return depth + -2;
      }
      case BIN(getglobal):{
        return depth + 1;
      }
      case BIN(setglobal):{
        return depth + -1;
      }
      case BIN(putnil):{
        return depth + 1;
      }
      case BIN(putself):{
        return depth + 1;
      }
      case BIN(putundef):{
        return depth + 1;
      }
      case BIN(putobject):{
        return depth + 1;
      }
      case BIN(putstring):{
        return depth + 1;
      }
      case BIN(concatstrings):{
        int inc = 0;
        unsigned long num = FIX2INT(opes[0]);
         inc += 1 - num;;
        return depth + inc;
      }
      case BIN(tostring):{
        return depth + 0;
      }
      case BIN(toregexp):{
        return depth + 0;
      }
      case BIN(newarray):{
        int inc = 0;
        unsigned long num = FIX2INT(opes[0]);
         inc += 1 - num;;
        return depth + inc;
      }
      case BIN(duparray):{
        return depth + 1;
      }
      case BIN(expandarray):{
        int inc = 0;
        unsigned long num = FIX2INT(opes[0]);
        unsigned long flag = FIX2INT(opes[1]);
         inc += (num > 0) ? num - 1 + (flag ? 1 : 0) : num + 1 - (flag ? 1 : 0);;
        return depth + inc;
      }
      case BIN(concatarray):{
        return depth + -1;
      }
      case BIN(splatarray):{
        return depth + 0;
      }
      case BIN(checkincludearray):{
        return depth + 0;
      }
      case BIN(newhash):{
        int inc = 0;
        unsigned long num = FIX2INT(opes[0]);
         inc += 1 - num;;
        return depth + inc;
      }
      case BIN(newrange):{
        return depth + -1;
      }
      case BIN(putnot):{
        return depth + 0;
      }
      case BIN(pop):{
        return depth + -1;
      }
      case BIN(dup):{
        return depth + 1;
      }
      case BIN(dupn):{
        int inc = 0;
        unsigned long n = FIX2INT(opes[0]);
         inc += n;;
        return depth + inc;
      }
      case BIN(swap):{
        return depth + 0;
      }
      case BIN(reput):{
        int inc = 0;
         inc += 0;;
        return depth + inc;
      }
      case BIN(topn):{
        int inc = 0;
        unsigned long n = FIX2INT(opes[0]);
         inc += 1;;
        return depth + inc;
      }
      case BIN(setn):{
        int inc = 0;
        unsigned long n = FIX2INT(opes[0]);
         inc += 0;
        return depth + inc;
      }
      case BIN(emptstack):{
        int inc = 0;
         inc = 0; depth = 0;;
        return depth + inc;
      }
      case BIN(definemethod):{
        return depth + -1;
      }
      case BIN(alias):{
        return depth + 0;
      }
      case BIN(undef):{
        return depth + 0;
      }
      case BIN(defined):{
        return depth + 0;
      }
      case BIN(postexe):{
        return depth + 0;
      }
      case BIN(trace):{
        return depth + 0;
      }
      case BIN(defineclass):{
        return depth + -1;
      }
      case BIN(send):{
        int inc = 0;
        unsigned long op_argc = FIX2INT(opes[1]);
        unsigned long op_flag = FIX2INT(opes[3]);
         inc += - (op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));;
        return depth + inc;
      }
      case BIN(invokesuper):{
        int inc = 0;
        unsigned long op_argc = FIX2INT(opes[0]);
        unsigned long flag = FIX2INT(opes[2]);
         inc += - op_argc;;
        return depth + inc;
      }
      case BIN(invokeblock):{
        int inc = 0;
        unsigned long num = FIX2INT(opes[0]);
        unsigned long flag = FIX2INT(opes[1]);
         inc += 1 - num;;
        return depth + inc;
      }
      case BIN(leave):{
        return depth + 0;
      }
      case BIN(finish):{
        return depth + 0;
      }
      case BIN(throw):{
        return depth + 0;
      }
      case BIN(jump):{
        return depth + 0;
      }
      case BIN(branchif):{
        return depth + -1;
      }
      case BIN(branchunless):{
        return depth + -1;
      }
      case BIN(getinlinecache):{
        return depth + 1;
      }
      case BIN(onceinlinecache):{
        return depth + 1;
      }
      case BIN(setinlinecache):{
        return depth + 0;
      }
      case BIN(opt_case_dispatch):{
        int inc = 0;
         inc += -1;;
        return depth + inc;
      }
      case BIN(opt_checkenv):{
        return depth + 0;
      }
      case BIN(opt_plus):{
        return depth + -1;
      }
      case BIN(opt_minus):{
        return depth + -1;
      }
      case BIN(opt_mult):{
        return depth + -1;
      }
      case BIN(opt_div):{
        return depth + -1;
      }
      case BIN(opt_mod):{
        return depth + -1;
      }
      case BIN(opt_eq):{
        return depth + -1;
      }
      case BIN(opt_lt):{
        return depth + -1;
      }
      case BIN(opt_le):{
        return depth + -1;
      }
      case BIN(opt_ltlt):{
        return depth + -1;
      }
      case BIN(opt_aref):{
        return depth + -1;
      }
      case BIN(opt_aset):{
        return depth + -2;
      }
      case BIN(opt_length):{
        return depth + 0;
      }
      case BIN(opt_succ):{
        return depth + 0;
      }
      case BIN(opt_regexpmatch1):{
        return depth + 0;
      }
      case BIN(opt_regexpmatch2):{
        return depth + -1;
      }
      case BIN(opt_call_native_compiled):{
        return depth + 0;
      }
      case BIN(bitblt):{
        return depth + 1;
      }
      case BIN(answer):{
        return depth + 1;
      }

  default:
    rb_bug("insn_sp_increase: unreachable");
  }
  return 0;
}

/* some utilities */

static int
insn_len(int insn)
{
  return insn_len_info[insn];
}

static char *
insn_name(int insn)
{
  return insn_name_info[insn];
}

static char *
insn_op_types(int insn)
{
  return insn_operand_info[insn];
}

static int
insn_op_type(int insn, int pos)
{
  int len = insn_len(insn) - 1;
  if(pos < len){
    return insn_operand_info[insn][pos];
  }
  else{
    return 0;
  }
}

static int
insn_ret_num(int insn)
{
  return insn_stack_push_num_info[insn];
}
