--- nono/m680x0/gentable.php 2026/04/29 17:04:28 1.1.1.1 +++ nono/m680x0/gentable.php 2026/04/29 17:05:22 1.1.1.6 @@ -2,13 +2,16 @@ // // nono // Copyright (C) 2014 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt +// + // // gentable.php // inst*.txt からディスパッチャ部分を生成 // // switch10 switch-case (10bit) を出力 // switch13 switch-case (13bit) を出力 -// goto10 computed goto (10bit) を出力 // mmu8 MMU の switch-case (8bit) を出力 // @@ -17,11 +20,12 @@ } init_ea(); - $mputype = 3; + // 今の所逆アセンブラの分離度が低いので、 + // コアも逆アセンブラも両方とも 68020/030 という扱いにしておく。 + $mputype = "[23]"; switch ($argv[1]) { case "switch10": case "switch13": - case "goto10": if (preg_match("/10$/", $argv[1])) { $nb = 10; } else { @@ -30,16 +34,11 @@ $insttable = read_instructions($mputype, "instructions.txt"); $insttable = expandDST($insttable); $insttable = expandSS($insttable); - $insttable = expandCond($insttable); makeop16($insttable); $op10table = makeop10table(); $op10func = makeop10func($op10table); $op10hash = makeop10hash($op10func); - if (preg_match("/switch/", $argv[1])) { - output_switch($op10table, $op10func); - } else { - output_goto($op10table, $op10func); - } + output_switch($op10table, $op10func); output_header($op10hash); break; @@ -69,9 +68,6 @@ function usage() print "Usage: {$argv[0]} mmu8\n"; print " input: instmmu.txt\n"; print " output: \n"; - print "Usage: {$argv[0]} goto10\n"; - print " input: instruction.txt\n"; - print " output: goto.h.new, ops.cpp.new, ops.h.new\n"; exit(1); } @@ -253,55 +249,6 @@ function expandSS($insttable) return $inst2table; } -// $insttable の cccc を展開する。 -function expandCond($insttable) -{ - $cccc = array( - "0000" => "t", - "0001" => "f", - "0010" => "hi", - "0011" => "ls", - "0100" => "cc", - "0101" => "cs", - "0110" => "ne", - "0111" => "eq", - "1000" => "vc", - "1001" => "vs", - "1010" => "pl", - "1011" => "mi", - "1100" => "ge", - "1101" => "lt", - "1110" => "gt", - "1111" => "le", - ); - $inst2table = array(); - foreach ($insttable as $inst) { - if (preg_match("/cccc/", $inst["bits"])) { - foreach ($cccc as $cbit => $cname) { - $uname = strtoupper($cname); - $inst2 = $inst; - $inst2["bits"] = preg_replace("/cccc/", $cbit, $inst["bits"]); - $inst2["name"] = preg_replace("/cc/", $cname, $inst["name"]); - $inst2["text"] = preg_replace("/cc/", $uname, $inst["text"]); - $inst2table[] = $inst2; - } - } else { - $inst2table[] = $inst; - } - } - - // デバッグ表示 - if (0) { - print "expandCond\n"; - foreach ($inst2table as $inst) { - printf("%s|%s|%-14s|%s\n", - $inst["bits"], $inst["addr"], $inst["name"], $inst["text"]); - } - } - - return $inst2table; -} - // insttable を16ビットの op16table に展開。 // $optable = array( // 0 => &$inst0, @@ -515,7 +462,7 @@ function output_switch($op10table, $op10 // コメント // 同一 bits に別の命令が割り当てられているケースは // ここで2行のコメントに分解 - foreach (split(";", $inst["text"]) as $text) { + foreach (preg_split("/;/", $inst["text"]) as $text) { $comm = "{$inst["bits"]}\t{$text}"; $comments[$comm] = $comm; } @@ -566,101 +513,6 @@ function output_switch($op10table, $op10 write_file("ops.cpp.new", $cpp); } -// computed-goto 本体とソースの元を出力 -function output_goto($op10table, $op10func) -{ - global $nb; - - $shift = 16 - $nb; - $ipb = 2 ** (16 - $nb); - - // ジャンプテーブルを作成 - $table = "\t\tstatic const void *jumptable[] = {\n"; - for ($i = 0; $i < 2 ** $nb; $i++) { - $table .= sprintf("\t\t\t/* $%04X */&&label_goto_%s,\n", - $i * $ipb, $op10func[$i]); - } - $table .= "\t\t};\n"; - - $func2 = $op10func; - - // 先に不当命令ブロックだけ抜いておく - $illegals = array(); - for ($i = 0; $i < 2 ** $nb; $i++) { - if (isset($func2[$i]) && $func2[$i] == "illegal") { - $illegals[$i] = $i; - unset($func2[$i]); - } - } - - $out = ""; - $cpp = ""; - - $out .= "\t\tJUMP;\n"; - - for ($i = 0; $i < 2 ** $nb; $i++) { - if (!isset($func2[$i])) { - // 不当命令ブロック - continue; - } - $funcname = $func2[$i]; - - $cases = array(); - $comments = array(); - - // この関数名をもつブロックに属する人全員のコメントを集める。 - // このブロック自身もここで集計するため $j は $i から始める。 - for ($j = $i; $j < 2 ** $nb; $j++) { - if (isset($func2[$j]) && $func2[$j] == $funcname) { - foreach ($op10table[$j] as $inst) { - // case - $cases[$j] = $j; - // コメント - // 同一 bits に別の命令が割り当てられているケースは - // ここで2行のコメントに分解 - foreach (split(";", $inst["text"]) as $text) { - $comm = "{$inst["bits"]}\t{$text}"; - $comments[$comm] = $comm; - } - } - // 集計したら消す - unset($func2[$j]); - } - } - // ラベル - $out .= "\t label_goto_{$funcname}:\n"; - // コメント - foreach ($comments as $comm) { - if ($nb == 8) { - // というか MMU というべきか - preg_match("/(...)(.....)(...)(.*)/", $comm, $m); - $comm1 = "%{$m[1]}_{$m[2]}_{$m[3]}_{$m[4]}"; - } else { - // 第1ワードというべきか - preg_match("/(....)(......)(.*)/", $comm, $m); - $comm1 = "%{$m[1]}_{$m[2]}_{$m[3]}"; - } - $out .= "\t\t// {$comm1}\n"; - $cpp .= "// {$comm1}\n"; - } - // 関数 - $out .= "\t\tOP_FUNC({$funcname});\n"; - $out .= "\t\tCHECK_AND_JUMP;\n"; - - // ソース - $cpp .= output_func($funcname); - } - - // 不当命令ブロックを出力 - $out .= "\t label_goto_illegal:\n"; - $out .= "\t\tOP_FUNC(illegal);\n"; - $out .= "\t\tCHECK_AND_JUMP;\n"; - - // ファイルに出力 - write_file("goto.h.new", $table . $out); - write_file("ops.cpp.new", $cpp); -} - // 関数ソースを出力 function output_func($name) { @@ -695,3 +547,4 @@ function write_file($filename, $str) print "Output: {$filename}\n"; } +?>