⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 opcodes.awk

📁 idel虚拟机源码
💻 AWK
字号:
# Generate the inner interpreter and related tables from the opcodes file.# Copyright (C) 2001-2002 Darius BaconBEGIN {  gnu_c = (cc == "gcc");  nesting = 0;  opcode = -1;  code_file = "src/interp.inc";  dict_file = "src/dict.inc";  name_file = "src/names.inc";  args_file = "src/args.inc";  enum_file = "src/enum.inc";  label_file = "src/labels.inc";  effect_file = "src/effect.inc";  prims_file = "src/prims.inc";  peep_file = "src/peep.inc";  peep1_file = "src/peep1.inc";  # The peep files won't necessarily get written to, so let's clear  # them out before we start -- otherwise we might have an old version  # lying around afterwards.  print "" >peep_file;  print "" >peep1_file;  if (gnu_c)    code("goto *(void*)*pc;");  else {    code("for (;;) switch (*pc) {")  }}/^#/ { next; }         # skip comments/^[^ \t]/ {   ++opcode;   new_op();   next;}NF != 0 {   sub(/^[ \t]*/, "");  lines[opcode, ++nlines[opcode]] = $0;}END {   while (getline <"src/combos" > 0) {    if ($1 in op_named && $2 in op_named)      combine_ops(++opcode, op_named[$1], op_named[$2]);    else      error("No such opcode: one of " $0);  }  for (i = 0; i <= opcode; ++i)    dump_op(i);  printf ("  num_opcodes = %d\n", opcode + 1) >enum_file;  if (!gnu_c) {    code("default: unreachable ();");    code("}");  }}function new_op(    j, inp, ty, outp){  mnemonic[opcode] = "";  nlines[opcode] = 0;  parse_signature();}function parse_signature(    i){  popping[opcode] = istream[opcode] = pushing[opcode] = 0;  range[opcode] = $1;  c_name[opcode] = $2;  op_named[c_name[opcode]] = opcode;  for (i = 3; ; ++i) {    if (NF < i)      error("No `--' in instruction signature");    if ($i == "--")      break;    if ($i == "??")      popping[opcode] = -1;    else if ($i ~ /^[unp][1-4]$/) {      if (mnemonic[opcode] == "")	inputs[opcode, ++popping[opcode]] = $i;      else	inlines[opcode, ++istream[opcode]] = $i;    } else {      if (mnemonic[opcode] != "")	error("Mnemonic not obvious");      mnemonic[opcode] = $i;    }  }  for (++i; i <= NF; ++i) {    if ($i == "??")      pushing[opcode] = -1;    else if ($i ~ /^[unp][1-4]$/)      outputs[opcode, ++pushing[opcode]] = $i;    else      error("Unknown output type");  }}function combine_ops(opc, op1, op2,   j, k, tween, tweens, inp, outp, src){  part1[opc] = op1;  part2[opc] = op2;  mnemonic[opc] = mnemonic[op1] "_" mnemonic[op2];  c_name[opc] = c_name[op1] "_" c_name[op2];  op_named[c_name[opc]] = opc;  istream[opc] = istream[op1] + istream[op2];  for (j = 1; j <= istream[opc]; ++j)    inlines[opc, j] = "n_operand_" c_name[op2] "_" j;  range[opc] = "3";  if (0 <= popping[op2] - pushing[op1]) {    popping[opc] = popping[op1] - pushing[op1] + popping[op2];    pushing[opc] = pushing[op2];  } else {    popping[opc] = popping[op1];    pushing[opc] = pushing[op1] - popping[op2] + pushing[op2];  }  # FIXME: account correctly for dynamic stack effects  if (popping[op1] < 0)    popping[opc] = -1;  if (pushing[op2] < 0)    pushing[opc] = -1;  for (j = 1; j <= popping[opc]; ++j)    inputs[opc, j] = "n_in_" c_name[opc] "_" j;  for (j = 1; j <= pushing[opc]; ++j)    outputs[opc, j] = "n_out_" c_name[opc] "_" j;  tween = "n_tween_" c_name[opc] "_";  tweens = min(pushing[op1], popping[op2]);  k = 0;  lines[opc, ++k] = "{";  for (j = 1; j <= tweens; ++j)    lines[opc, ++k] = sprintf("%s %s;", 			      type("n"), tween j);  lines[opc, ++k] = "{";  for (j = 1; j <= istream[op1]; ++j)    lines[opc, ++k] = sprintf("%s %s = %s;",			      type(inlines[op1, j]),			      inlines[op1, j],			      inlines[opc, j]);  for (j = 1; j <= pushing[op1]; ++j)    lines[opc, ++k] = sprintf("%s %s;", 			      type(outputs[op1, j]),			      outputs[op1, j]);  for (j = 1; j <= popping[op1]; ++j)    lines[opc, ++k] = sprintf("%s %s = %s;", 			      type(inputs[op1, j]), 			      inputs[op1, j],			      inputs[opc, popping[opc] - popping[op1] + j]);  for (j = 1; j <= nlines[op1]; ++j)    lines[opc, ++k] = lines[op1, j];  for (j = 1; j <= pushing[op1]; ++j) {    if (j <= pushing[op1] - tweens)      outp = outputs[opc, j];    else      outp = tween (j - (pushing[op1] - tweens))    lines[opc, ++k] = sprintf("%s = %s;", 			      outp,			      outputs[op1, j]);  }  lines[opc, ++k] = "}";  lines[opc, ++k] = "{";  for (j = 1; j <= istream[op2]; ++j)    lines[opc, ++k] = sprintf("%s %s = %s;",			      type(inlines[op2, j]),			      inlines[op2, j],			      inlines[opc, istream[op1] + j]);  for (j = 1; j <= pushing[op2]; ++j)    lines[opc, ++k] = sprintf("%s %s;", 			      type(outputs[op2, j]),			      outputs[op2, j]);  for (j = 1; j <= popping[op2]; ++j) {    inp = inputs[op2, j];    if (j <= popping[op2] - tweens)      src = inputs[opc, j];    else      src = tween (j - (popping[op2] - tweens))    lines[opc, ++k] = sprintf("%s %s = %s;", type(inp), inp, src);  }  for (j = 1; j <= nlines[op2]; ++j)    lines[opc, ++k] = lines[op2, j];  for (j = 1; j <= pushing[op2]; ++j)     lines[opc, ++k] = sprintf("%s = %s;",			      outputs[opc, j + (pushing[opc] - pushing[op2])],			      outputs[op2, j]);  lines[opc, ++k] = "}";  lines[opc, ++k] = "}";  nlines[opc] = k;}function dump_peep(opc,   file, any, j, combo, R, else_part){  if (0 == istream[opc])    file = peep_file;  else    file = peep1_file;  for (j = 0; j <= opcode; ++j) {    if (j in part1 && part1[j] == opc) {      if (!any)	print "      case " c_name[opc] ":" >file;      combo = c_name[j]      R = c_name[part2[j]];      else_part = (any ? "else " : "");      print "	" else_part "if (vm->there[0] == (i32) opcode_labels[" R "])" >file;      print "	  combined_opcode = " combo ";" >file;      any = 1;    }  }  if (any)    print "	break;" >file;}function dump_op(opc){  dump_peep(opc);  printf("  \"%s\",\n", c_name[opc]) >name_file;  printf("  %d,\n", istream[opc]) >args_file;  printf ("  %s = %d,\n", c_name[opc], opc) >enum_file;  if (!is_internal(opc)) {    printf("  install_primitive(\"%s\", %d);\n", mnemonic[opc], opc) >dict_file;    if (c_name[opc] != "save")      printf("    case %s:\n", c_name[opc]) >prims_file;  }  printf("  { %d, %d },\n", popping[opc], pushing[opc] - popping[opc]) >effect_file;  if (gnu_c) {    print "  &&opcode" opc "," >label_file;    code("opcode%d:\t\t\t/* %s */", opc, c_name[opc]);  } else {    print "  (cplabel) " opc "," >label_file;    code("case %d:\t\t\t/* %s */", opc, c_name[opc]);  }  dump_op_code(opc);}function dump_op_code(opc,   j, inp, ty, outp, line, saw_next){  code("#ifdef opcode_profiling");  code("++instruction_count[previous_opcode][%s];", c_name[opc]);  code("previous_opcode = %s;", c_name[opc]);  code("#endif");  code("if (tracing) trace_op (pc, stack, sp+1);");  code("{");  for (j = 1; j <= istream[opc]; ++j) {    inp = inlines[opc, j];    ty = type(inp);    code("%s %s = (%s) pc[%d];", ty, inp, ty, j);  }  for (j = 1; j <= popping[opc]; ++j) {    inp = inputs[opc, popping[opc] - j + 1];    ty = type(inp);    code("%s %s = (%s) sp[-%d];", ty, inp, ty, j-1);  }  for (j = 1; j <= pushing[opc]; ++j) {    outp = outputs[opc, j];    ty = type(outp);    code("%s %s;", ty, outp);  }  for (j = 1; j <= nlines[opc]; ++j) {    line = lines[opc, j];    if (line ~ /NEXT/) {      saw_next = 1;      gsub(/NEXT/, "pc += " 1 + istream[opc], line);    }    code("%s", line);  }  if (!saw_next)    code("pc += %d;", 1 + istream[opc]);  if (pushing[opc] != popping[opc] && 0 <= pushing[opc] && 0 <= popping[opc])    code("sp += %d;", pushing[opc] - popping[opc]);  if (gnu_c) {    code("{");    code("void *next_label = (void *) *pc;");  }  for (j = pushing[opc]; 1 <= j; --j) {    outp = outputs[opc, pushing[opc] - j + 1];    code("sp[-%d] = %s;", j-1, outp);  }  if (gnu_c) {    code("goto *next_label;");    code("}");  } else {    code("break;");  }  code("}");}function type(v){  if (v ~ /^n/) return "i32";  if (v ~ /^u/) return "u32";  if (v ~ /^p/) return "u32";    # todo: add in range-checking code  error("Huh?");}function code(format, a, b, c, d, e, out){  out = sprintf(format, a, b, c, d, e);  if (out ~ /}/) --level;  printf("%*s%s\n", level*2, "", out) >code_file;  if (out ~ /{/) ++level;}# FIXME: I suspect we want more distinctionsfunction is_internal(opc){  return range[opc] != "123";}function min(x, y){  return x < y ? x : y;}function error(message){  print message >"/dev/stderr";  exit(1);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -