|
|
1.1 ! root 1: <?php ! 2: // ! 3: // nono ! 4: // Copyright (C) 2014 [email protected] ! 5: // ! 6: // gentable.php ! 7: // inst*.txt からディスパッチャ部分を生成 ! 8: // ! 9: // switch10 switch-case (10bit) を出力 ! 10: // switch13 switch-case (13bit) を出力 ! 11: // goto10 computed goto (10bit) を出力 ! 12: // mmu8 MMU の switch-case (8bit) を出力 ! 13: // ! 14: ! 15: if ($argc < 2) { ! 16: usage(); ! 17: } ! 18: ! 19: init_ea(); ! 20: $mputype = 3; ! 21: switch ($argv[1]) { ! 22: case "switch10": ! 23: case "switch13": ! 24: case "goto10": ! 25: if (preg_match("/10$/", $argv[1])) { ! 26: $nb = 10; ! 27: } else { ! 28: $nb = 13; ! 29: } ! 30: $insttable = read_instructions($mputype, "instructions.txt"); ! 31: $insttable = expandDST($insttable); ! 32: $insttable = expandSS($insttable); ! 33: $insttable = expandCond($insttable); ! 34: makeop16($insttable); ! 35: $op10table = makeop10table(); ! 36: $op10func = makeop10func($op10table); ! 37: $op10hash = makeop10hash($op10func); ! 38: if (preg_match("/switch/", $argv[1])) { ! 39: output_switch($op10table, $op10func); ! 40: } else { ! 41: output_goto($op10table, $op10func); ! 42: } ! 43: output_header($op10hash); ! 44: break; ! 45: ! 46: case "mmu8": ! 47: $nb = 8; ! 48: $insttable = read_instructions($mputype, "instmmu.txt"); ! 49: makeop16($insttable); ! 50: $op10table = makeop10table(); ! 51: $op10func = makeop10func($op10table); ! 52: $op10hash = makeop10hash($op10func); ! 53: output_switch($op10table, $op10func); ! 54: output_header($op10hash); ! 55: break; ! 56: default: ! 57: usage(); ! 58: } ! 59: exit(0); ! 60: ?> ! 61: <?php ! 62: function usage() ! 63: { ! 64: global $argv; ! 65: ! 66: print "Usage: {$argv[0]} switch10 | switch13\n"; ! 67: print " input: instruction.txt\n"; ! 68: print " output: switch.h.new, ops.cpp.new, ops.h.new\n"; ! 69: print "Usage: {$argv[0]} mmu8\n"; ! 70: print " input: instmmu.txt\n"; ! 71: print " output: \n"; ! 72: print "Usage: {$argv[0]} goto10\n"; ! 73: print " input: instruction.txt\n"; ! 74: print " output: goto.h.new, ops.cpp.new, ops.h.new\n"; ! 75: exit(1); ! 76: } ! 77: ! 78: function init_ea() ! 79: { ! 80: global $ambits; ! 81: ! 82: // アドレッシングモードの展開パターン ! 83: $ambits = array( ! 84: "d" => "000rrr", ! 85: "a" => "001rrr", ! 86: "m" => "010rrr", ! 87: "+" => "011rrr", ! 88: "-" => "100rrr", ! 89: "r" => "101rrr", ! 90: "x" => "110rrr", ! 91: "w" => "11100r", ! 92: "p" => "11101r", ! 93: "i" => "111100", ! 94: ); ! 95: } ! 96: ! 97: // instructions.txt を読み込んで $insttable[] 配列にする ! 98: function read_instructions($mputype, $filename) ! 99: { ! 100: $fp = fopen($filename, "r"); ! 101: if ($fp === false) { ! 102: print "fopen failed: {$filename}\n"; ! 103: exit(1); ! 104: } ! 105: ! 106: $insttable = array(); ! 107: ! 108: while (($line = fgets($fp))) { ! 109: $line = trim(preg_replace("/;.*/", "", $line)); ! 110: if ($line == "") { ! 111: continue; ! 112: } ! 113: ! 114: // 1行はこんな感じ ! 115: // 00000000SSmmmrrr d.m+-rxw.. 034 ori_S ORI.S #<imm>,<ea> ! 116: // 列は1つ以上のタブで区切られている。 ! 117: // $bits … 1ワード目のビットパターン ! 118: // $addr … 対応しているアドレッシングモード ! 119: // $mpu … MPU ごとのサポート有無 ! 120: // $name … 関数名 ! 121: // $text … コメント ! 122: ! 123: list ($bits, $addr, $mpu, $name, $text) = ! 124: preg_split("/\t+/", $line, -1, PREG_SPLIT_NO_EMPTY); ! 125: $name = trim($name); ! 126: $text = trim($text); ! 127: ! 128: // ターゲット CPU の命令のみ対象にする ! 129: if (preg_match("/{$mputype}/", $mpu) == false) { ! 130: continue; ! 131: } ! 132: ! 133: $newinst = array( ! 134: "bits" => $bits, ! 135: "addr" => $addr, ! 136: "mpu" => $mpu, ! 137: "name" => $name, ! 138: "text" => $text, ! 139: ); ! 140: // $insttable[] に追加する。 ! 141: // ただし bits が同じものがあれば text だけ追加。 ! 142: if (isset($insttable[$bits])) { ! 143: $insttable[$bits]["text"] .= ";{$text}"; ! 144: } else { ! 145: $insttable[$bits] = $newinst; ! 146: } ! 147: } ! 148: fclose($fp); ! 149: ! 150: // デバッグ表示 ! 151: if (0) { ! 152: print "read_instruction\n"; ! 153: foreach ($insttable as $inst) { ! 154: printf("%s|%s|%-14s|%s\n", ! 155: $inst["bits"], $inst["addr"], $inst["name"], $inst["text"]); ! 156: } ! 157: } ! 158: ! 159: return $insttable; ! 160: } ! 161: ! 162: // $insttable のうち MOVE の DST を展開する ! 163: function expandDST($insttable) ! 164: { ! 165: $dst = array( ! 166: array("xxx000", "dn", "Dx"), ! 167: array("xxx010", "anin", "(Ax)"), ! 168: array("xxx011", "anpi", "(Ax)+"), ! 169: array("xxx100", "anpd", "-(Ax)"), ! 170: array("xxx101", "andi", "d16(Ax)"), ! 171: array("xxx110", "anix", "(Ax,IX)"), ! 172: array("000111", "absw", "Abs.W"), ! 173: array("001111", "absl", "Abs.L"), ! 174: ); ! 175: $inst2table = array(); ! 176: foreach ($insttable as $inst) { ! 177: if (preg_match("/RRRMMM/", $inst["bits"])) { ! 178: foreach ($dst as $d) { ! 179: $inst2 = $inst; ! 180: $inst2["bits"] = preg_replace("/RRRMMM/", $d[0], $inst["bits"]); ! 181: $inst2["name"] = preg_replace("/DD/", $d[1], $inst["name"]); ! 182: $inst2["text"] = preg_replace("/DD/", $d[2], $inst["text"]); ! 183: ! 184: $inst2table[] = $inst2; ! 185: } ! 186: } else { ! 187: $inst2table[] = $inst; ! 188: } ! 189: } ! 190: ! 191: // デバッグ表示 ! 192: if (0) { ! 193: print "expandDST\n"; ! 194: foreach ($inst2table as $inst) { ! 195: printf("%s|%s|%-14s|%s\n", ! 196: $inst["bits"], $inst["addr"], $inst["name"], $inst["text"]); ! 197: } ! 198: } ! 199: ! 200: return $inst2table; ! 201: } ! 202: ! 203: // $insttable の SS と s を展開する ! 204: // これらは必ず上位10ビット内にあるので (というか下位6ビット以内に現れる ! 205: // やつはテキストにする時点で手動で展開してあるので)、 ! 206: // サイズ別の関数に展開できる。 ! 207: function expandSS($insttable) ! 208: { ! 209: $s3 = array( ! 210: array("00", "_b", ".B"), ! 211: array("01", "_w", ".W"), ! 212: array("10", "_l", ".L"), ! 213: ); ! 214: $s2 = array( ! 215: array("0", "_w", ".W"), ! 216: array("1", "_l", ".L"), ! 217: ); ! 218: ! 219: $inst2table = array(); ! 220: foreach ($insttable as $inst) { ! 221: if (preg_match("/SS/", $inst["bits"])) { ! 222: foreach ($s3 as $s) { ! 223: $inst2 = $inst; ! 224: $inst2["bits"] = preg_replace("/SS/", $s[0], $inst["bits"]); ! 225: $inst2["name"] = preg_replace("/_S/", $s[1], $inst["name"]); ! 226: $inst2["text"] = preg_replace("/\.S/", $s[2], $inst["text"]); ! 227: ! 228: $inst2table[] = $inst2; ! 229: } ! 230: } else if (preg_match("/s/", $inst["bits"])) { ! 231: foreach ($s2 as $s) { ! 232: $inst2 = $inst; ! 233: $inst2["bits"] = preg_replace("/s/", $s[0], $inst["bits"]); ! 234: $inst2["name"] = preg_replace("/_S/", $s[1], $inst["name"]); ! 235: $inst2["text"] = preg_replace("/\.S/", $s[2], $inst["text"]); ! 236: ! 237: $inst2table[] = $inst2; ! 238: } ! 239: } else { ! 240: $inst2table[] = $inst; ! 241: } ! 242: } ! 243: ! 244: // デバッグ表示 ! 245: if (0) { ! 246: print "expandSS\n"; ! 247: foreach ($inst2table as $inst) { ! 248: printf("%s|%s|%-14s|%s\n", ! 249: $inst["bits"], $inst["addr"], $inst["name"], $inst["text"]); ! 250: } ! 251: } ! 252: ! 253: return $inst2table; ! 254: } ! 255: ! 256: // $insttable の cccc を展開する。 ! 257: function expandCond($insttable) ! 258: { ! 259: $cccc = array( ! 260: "0000" => "t", ! 261: "0001" => "f", ! 262: "0010" => "hi", ! 263: "0011" => "ls", ! 264: "0100" => "cc", ! 265: "0101" => "cs", ! 266: "0110" => "ne", ! 267: "0111" => "eq", ! 268: "1000" => "vc", ! 269: "1001" => "vs", ! 270: "1010" => "pl", ! 271: "1011" => "mi", ! 272: "1100" => "ge", ! 273: "1101" => "lt", ! 274: "1110" => "gt", ! 275: "1111" => "le", ! 276: ); ! 277: $inst2table = array(); ! 278: foreach ($insttable as $inst) { ! 279: if (preg_match("/cccc/", $inst["bits"])) { ! 280: foreach ($cccc as $cbit => $cname) { ! 281: $uname = strtoupper($cname); ! 282: $inst2 = $inst; ! 283: $inst2["bits"] = preg_replace("/cccc/", $cbit, $inst["bits"]); ! 284: $inst2["name"] = preg_replace("/cc/", $cname, $inst["name"]); ! 285: $inst2["text"] = preg_replace("/cc/", $uname, $inst["text"]); ! 286: $inst2table[] = $inst2; ! 287: } ! 288: } else { ! 289: $inst2table[] = $inst; ! 290: } ! 291: } ! 292: ! 293: // デバッグ表示 ! 294: if (0) { ! 295: print "expandCond\n"; ! 296: foreach ($inst2table as $inst) { ! 297: printf("%s|%s|%-14s|%s\n", ! 298: $inst["bits"], $inst["addr"], $inst["name"], $inst["text"]); ! 299: } ! 300: } ! 301: ! 302: return $inst2table; ! 303: } ! 304: ! 305: // insttable を16ビットの op16table に展開。 ! 306: // $optable = array( ! 307: // 0 => &$inst0, ! 308: // 1 => &$inst1, ... ! 309: // ) ! 310: function makeop16($insttable) ! 311: { ! 312: global $op16table; ! 313: ! 314: $op16table = array(); ! 315: ! 316: foreach ($insttable as $inst) { ! 317: makeop16_sub($inst, $inst["bits"]); ! 318: } ! 319: ! 320: // デバッグ表示 ! 321: if (0) { ! 322: print "makeop16\n"; ! 323: for ($i = 0; $i < 65536; $i++) { ! 324: $b = str_repeat("0", 15) . decbin($i); ! 325: $b = substr($b, -16); ! 326: printf("%04x|%s|", $i, $b); ! 327: ! 328: if (isset($op16table[$i])) { ! 329: $inst = $op16table[$i]; ! 330: printf("%s|%-14s|%s\n", ! 331: $inst["bits"], $inst["name"], $inst["text"]); ! 332: } else { ! 333: printf("illegal\n"); ! 334: } ! 335: } ! 336: } ! 337: } ! 338: ! 339: // inst を1ビットずつ展開する再帰関数 ! 340: // lv は再帰レベル (デバッグ用) ! 341: function makeop16_sub($inst, $bits, $lv = 0) ! 342: { ! 343: global $op16table; ! 344: global $ambits; ! 345: ! 346: // $pos は bits の 0/1 でない最初の文字の位置 ! 347: $pos = strspn($bits, "01"); ! 348: if ($pos == 16) { ! 349: // 0/1 しか現れていないので確定 ! 350: // $optable に代入 ! 351: $num16 = bindec($bits); ! 352: $op16table[$num16] = $inst; ! 353: } else if (substr($bits, 10) == "mmmrrr") { ! 354: // アドレッシングモードによって展開 (いるかな?) ! 355: $head = substr($bits, 0, 10); ! 356: for ($i = 0; $i < strlen($inst["addr"]); $i++) { ! 357: $a = substr($inst["addr"], $i, 1); ! 358: if (isset($ambits[$a])) { ! 359: makeop16_sub($inst, "{$head}{$ambits[$a]}", $lv + 1); ! 360: } ! 361: } ! 362: } else { ! 363: // pos 番目の文字を 0 と 1 に変えて再帰実行 ! 364: $head = substr($bits, 0, $pos); ! 365: $tail = substr($bits, $pos + 1); ! 366: makeop16_sub($inst, "{$head}0{$tail}", $lv + 1); ! 367: makeop16_sub($inst, "{$head}1{$tail}", $lv + 1); ! 368: } ! 369: } ! 370: ! 371: // 16ビットテーブルから $nb (10 or 7) ビットテーブルを作成 ! 372: function makeop10table() ! 373: { ! 374: global $op16table; ! 375: global $nb; ! 376: ! 377: // 1ブロックあたりの命令数 ($nb=10 なら 64) ! 378: $ipb = 2 ** (16 - $nb); ! 379: ! 380: $op10table = array(); ! 381: for ($i = 0; $i < 2 ** $nb; $i++) { ! 382: $op10table[$i] = array(); ! 383: } ! 384: ! 385: for ($i = 0; $i < 65536; $i++) { ! 386: if (!isset($op16table[$i])) { ! 387: continue; ! 388: } ! 389: $inst = $op16table[$i]; ! 390: $j = $i / $ipb; ! 391: ! 392: // op10table[j][] にすでに同じエントリがなければ、追加 ! 393: $found = false; ! 394: foreach ($op10table[$j] as $ji) { ! 395: if ($inst["bits"] == $ji["bits"]) { ! 396: $found = true; ! 397: break; ! 398: } ! 399: } ! 400: if (!$found) { ! 401: $op10table[$j][] = $inst; ! 402: } ! 403: } ! 404: ! 405: // デバッグ用 ! 406: if (0) { ! 407: print "makeop10table\n"; ! 408: foreach ($op10table as $j => $arr) { ! 409: printf("0x%04x|", $j, $j * $ipb); ! 410: foreach ($arr as $inst) { ! 411: printf(" %s", $inst["name"]); ! 412: } ! 413: print "\n"; ! 414: } ! 415: } ! 416: ! 417: return $op10table; ! 418: } ! 419: ! 420: // op10table から op10func を作成 ! 421: // op10table は [1024] => array(inst, inst, ...) ! 422: // op10func は [1024] => 代表name ! 423: function makeop10func($op10table) ! 424: { ! 425: global $nb; ! 426: ! 427: $op10func = array(); ! 428: for ($i = 0; $i < 2 ** $nb; $i++) { ! 429: $op10func[$i] = ""; ! 430: } ! 431: ! 432: foreach ($op10table as $i => $arr) { ! 433: if (count($arr) == 0) { ! 434: $op10func[$i] = "illegal"; ! 435: continue; ! 436: } ! 437: ! 438: // 代表関数はこのブロックの中で最多数なもの。 ! 439: $funcname = ""; ! 440: $minbits = (16 - $nb) + 1; ! 441: foreach ($arr as $inst) { ! 442: // fixed は bits の末尾(16-nb)ビットのうち "0" と "1" の合計数 ! 443: $chs = count_chars(substr($inst["bits"], $nb), 0); ! 444: $fixed = $chs[0x30] + $chs[0x31]; ! 445: // fixed が小さい = 出力した命令の総数が大きい、なので採用 ! 446: if ($minbits > $fixed) { ! 447: $minbits = $fixed; ! 448: $funcname = $inst["name"]; ! 449: } ! 450: } ! 451: ! 452: $op10func[$i] = $funcname; ! 453: } ! 454: ! 455: // デバッグ用 ! 456: if (0) { ! 457: print "makeop10func\n"; ! 458: foreach ($op10func as $i => $name) { ! 459: printf("[%4d] %04x {$name}\n", $i, $i * 64); ! 460: } ! 461: } ! 462: ! 463: return $op10func; ! 464: } ! 465: ! 466: // op10hash は [代表name] => 代表name のハッシュ ! 467: // 実際に使われてる関数名一覧になる。 ! 468: function makeop10hash($op10func) ! 469: { ! 470: $op10hash = array(); ! 471: foreach ($op10func as $name) { ! 472: $op10hash[$name] = $name; ! 473: } ! 474: ! 475: return $op10hash; ! 476: } ! 477: ! 478: // switch 本体とソースの元を出力 ! 479: function output_switch($op10table, $op10func) ! 480: { ! 481: global $nb; ! 482: ! 483: $shift = 16 - $nb; ! 484: $ipb = 2 ** (16 - $nb); ! 485: ! 486: $func2 = $op10func; ! 487: ! 488: // 先に不当命令ブロックだけ抜いておく ! 489: $illegals = array(); ! 490: for ($i = 0; $i < 2 ** $nb; $i++) { ! 491: if (isset($func2[$i]) && $func2[$i] == "illegal") { ! 492: $illegals[$i] = $i; ! 493: unset($func2[$i]); ! 494: } ! 495: } ! 496: ! 497: $out = ""; ! 498: $cpp = ""; ! 499: for ($i = 0; $i < 2 ** $nb; $i++) { ! 500: if (!isset($func2[$i])) { ! 501: continue; ! 502: } ! 503: $funcname = $func2[$i]; ! 504: ! 505: $cases = array(); ! 506: $comments = array(); ! 507: ! 508: // この関数名をもつブロックに属する人全員のコメントを集める。 ! 509: // このブロック自身もここで集計するため $j は $i から始める。 ! 510: for ($j = $i; $j < 2 ** $nb; $j++) { ! 511: if (isset($func2[$j]) && $func2[$j] == $funcname) { ! 512: foreach ($op10table[$j] as $inst) { ! 513: // case ! 514: $cases[$j] = $j; ! 515: // コメント ! 516: // 同一 bits に別の命令が割り当てられているケースは ! 517: // ここで2行のコメントに分解 ! 518: foreach (split(";", $inst["text"]) as $text) { ! 519: $comm = "{$inst["bits"]}\t{$text}"; ! 520: $comments[$comm] = $comm; ! 521: } ! 522: } ! 523: // 集計したら消す ! 524: unset($func2[$j]); ! 525: } ! 526: } ! 527: // case ! 528: foreach ($cases as $c) { ! 529: $out .= sprintf("\t case (0x%04x >> ${shift}):\n", $c * $ipb); ! 530: } ! 531: // コメント ! 532: foreach ($comments as $comm) { ! 533: if ($nb == 8) { ! 534: // というか MMU というべきか ! 535: preg_match("/(...)(.....)(...)(.*)/", $comm, $m); ! 536: $comm1 = "%{$m[1]}_{$m[2]}_{$m[3]}_{$m[4]}"; ! 537: } else { ! 538: // 第1ワードというべきか ! 539: preg_match("/(....)(......)(.*)/", $comm, $m); ! 540: $comm1 = "%{$m[1]}_{$m[2]}_{$m[3]}"; ! 541: } ! 542: $out .= "\t\t// {$comm1}\n"; ! 543: $cpp .= "// {$comm1}\n"; ! 544: } ! 545: // 関数 ! 546: $out .= "\t\tOP_FUNC({$funcname});\n"; ! 547: $out .= "\t\tbreak;\n"; ! 548: ! 549: // ソース ! 550: $cpp .= output_func($funcname); ! 551: } ! 552: ! 553: // 不当命令ブロックを出力 ! 554: foreach ($illegals as $i) { ! 555: $out .= sprintf("\t case (0x%04x >> ${shift}):\n", $i * $ipb); ! 556: } ! 557: $out .= "\t\tOP_FUNC(illegal);\n"; ! 558: $out .= "\t\tbreak;\n"; ! 559: ! 560: // 不当命令 (ILLEGAL 命令ではないので最終的にどうするかはある) ! 561: $cpp .= "// illegal instructions\n"; ! 562: $cpp .= output_func("illegal"); ! 563: ! 564: // ファイルに出力 ! 565: write_file("switch.h.new", $out); ! 566: write_file("ops.cpp.new", $cpp); ! 567: } ! 568: ! 569: // computed-goto 本体とソースの元を出力 ! 570: function output_goto($op10table, $op10func) ! 571: { ! 572: global $nb; ! 573: ! 574: $shift = 16 - $nb; ! 575: $ipb = 2 ** (16 - $nb); ! 576: ! 577: // ジャンプテーブルを作成 ! 578: $table = "\t\tstatic const void *jumptable[] = {\n"; ! 579: for ($i = 0; $i < 2 ** $nb; $i++) { ! 580: $table .= sprintf("\t\t\t/* $%04X */&&label_goto_%s,\n", ! 581: $i * $ipb, $op10func[$i]); ! 582: } ! 583: $table .= "\t\t};\n"; ! 584: ! 585: $func2 = $op10func; ! 586: ! 587: // 先に不当命令ブロックだけ抜いておく ! 588: $illegals = array(); ! 589: for ($i = 0; $i < 2 ** $nb; $i++) { ! 590: if (isset($func2[$i]) && $func2[$i] == "illegal") { ! 591: $illegals[$i] = $i; ! 592: unset($func2[$i]); ! 593: } ! 594: } ! 595: ! 596: $out = ""; ! 597: $cpp = ""; ! 598: ! 599: $out .= "\t\tJUMP;\n"; ! 600: ! 601: for ($i = 0; $i < 2 ** $nb; $i++) { ! 602: if (!isset($func2[$i])) { ! 603: // 不当命令ブロック ! 604: continue; ! 605: } ! 606: $funcname = $func2[$i]; ! 607: ! 608: $cases = array(); ! 609: $comments = array(); ! 610: ! 611: // この関数名をもつブロックに属する人全員のコメントを集める。 ! 612: // このブロック自身もここで集計するため $j は $i から始める。 ! 613: for ($j = $i; $j < 2 ** $nb; $j++) { ! 614: if (isset($func2[$j]) && $func2[$j] == $funcname) { ! 615: foreach ($op10table[$j] as $inst) { ! 616: // case ! 617: $cases[$j] = $j; ! 618: // コメント ! 619: // 同一 bits に別の命令が割り当てられているケースは ! 620: // ここで2行のコメントに分解 ! 621: foreach (split(";", $inst["text"]) as $text) { ! 622: $comm = "{$inst["bits"]}\t{$text}"; ! 623: $comments[$comm] = $comm; ! 624: } ! 625: } ! 626: // 集計したら消す ! 627: unset($func2[$j]); ! 628: } ! 629: } ! 630: // ラベル ! 631: $out .= "\t label_goto_{$funcname}:\n"; ! 632: // コメント ! 633: foreach ($comments as $comm) { ! 634: if ($nb == 8) { ! 635: // というか MMU というべきか ! 636: preg_match("/(...)(.....)(...)(.*)/", $comm, $m); ! 637: $comm1 = "%{$m[1]}_{$m[2]}_{$m[3]}_{$m[4]}"; ! 638: } else { ! 639: // 第1ワードというべきか ! 640: preg_match("/(....)(......)(.*)/", $comm, $m); ! 641: $comm1 = "%{$m[1]}_{$m[2]}_{$m[3]}"; ! 642: } ! 643: $out .= "\t\t// {$comm1}\n"; ! 644: $cpp .= "// {$comm1}\n"; ! 645: } ! 646: // 関数 ! 647: $out .= "\t\tOP_FUNC({$funcname});\n"; ! 648: $out .= "\t\tCHECK_AND_JUMP;\n"; ! 649: ! 650: // ソース ! 651: $cpp .= output_func($funcname); ! 652: } ! 653: ! 654: // 不当命令ブロックを出力 ! 655: $out .= "\t label_goto_illegal:\n"; ! 656: $out .= "\t\tOP_FUNC(illegal);\n"; ! 657: $out .= "\t\tCHECK_AND_JUMP;\n"; ! 658: ! 659: // ファイルに出力 ! 660: write_file("goto.h.new", $table . $out); ! 661: write_file("ops.cpp.new", $cpp); ! 662: } ! 663: ! 664: // 関数ソースを出力 ! 665: function output_func($name) ! 666: { ! 667: $cpp = ""; ! 668: $cpp .= "OP_DEF({$name})\n"; ! 669: $cpp .= "{\n"; ! 670: $cpp .= "\tOP_FUNC(unimpl);\n"; ! 671: $cpp .= "}\n"; ! 672: $cpp .= "\n"; ! 673: ! 674: return $cpp; ! 675: } ! 676: ! 677: // ヘッダを出力 ! 678: function output_header($op10hash) ! 679: { ! 680: $out = ""; ! 681: foreach ($op10hash as $name) { ! 682: $out .= "OP_PROTO({$name});\n"; ! 683: } ! 684: ! 685: // ファイルに出力 ! 686: write_file("ops.h.new", $out); ! 687: } ! 688: ! 689: // ファイル出力 ! 690: function write_file($filename, $str) ! 691: { ! 692: $fp = fopen($filename, "w"); ! 693: fwrite($fp, $str); ! 694: fclose($fp); ! 695: ! 696: print "Output: {$filename}\n"; ! 697: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.