--- nono/m680x0/gentable.php 2026/04/29 17:05:22 1.1.1.6 +++ nono/m680x0/gentable.php 2026/04/29 17:05:57 1.1.1.9 @@ -1,7 +1,7 @@ &$inst0, @@ -277,7 +315,7 @@ function makeop16($insttable) printf("%s|%-14s|%s\n", $inst["bits"], $inst["name"], $inst["text"]); } else { - printf("illegal\n"); + printf("n/a\n"); } } } @@ -353,7 +391,7 @@ function makeop10table() if (0) { print "makeop10table\n"; foreach ($op10table as $j => $arr) { - printf("0x%04x|", $j, $j * $ipb); + printf("[0x%04x] $%04x|", $j, $j * $ipb); foreach ($arr as $inst) { printf(" %s", $inst["name"]); } @@ -378,7 +416,7 @@ function makeop10func($op10table) foreach ($op10table as $i => $arr) { if (count($arr) == 0) { - $op10func[$i] = "illegal"; + $op10func[$i] = "n/a"; continue; } @@ -416,12 +454,37 @@ function makeop10hash($op10func) { $op10hash = array(); foreach ($op10func as $name) { - $op10hash[$name] = $name; + if ($name != "n/a") { + $op10hash[$name] = $name; + } } return $op10hash; } +// コメントをいい感じにソートしたい。 +// $a, $b は "%1111_000000_mmmrrr dam+-rxwpi 034 OPNAME" みたいなやつ。 +// これのビットパターン部分でソート。ただし英字は "0"/"1" より前。 +// ビットパターンが同じなら出現順を維持(ソースファイルに記載の順)。 +function cmp_comments($comm_a, $comm_b) +{ + $va = preg_split('/\s+/', $comm_a); + $vb = preg_split('/\s+/', $comm_b); + + $a = $va[0]; + $b = $vb[0]; + + // 同じなら a, b の順。 + if ($a == $b) { + return -1; + } + + // "0"/"1" を英字の後ろにして比較。 + $a = str_replace(array("0","1"), array("{","}"), $a); + $b = str_replace(array("0","1"), array("{","}"), $b); + return $a <=> $b; +} + // switch 本体とソースの元を出力 function output_switch($op10table, $op10func) { @@ -433,10 +496,10 @@ function output_switch($op10table, $op10 $func2 = $op10func; // 先に不当命令ブロックだけ抜いておく - $illegals = array(); + $not_assigned = array(); for ($i = 0; $i < 2 ** $nb; $i++) { - if (isset($func2[$i]) && $func2[$i] == "illegal") { - $illegals[$i] = $i; + if (isset($func2[$i]) && $func2[$i] == "n/a") { + $not_assigned[$i] = $i; unset($func2[$i]); } } @@ -463,7 +526,8 @@ function output_switch($op10table, $op10 // 同一 bits に別の命令が割り当てられているケースは // ここで2行のコメントに分解 foreach (preg_split("/;/", $inst["text"]) as $text) { - $comm = "{$inst["bits"]}\t{$text}"; + $comm = "{$inst["bits"]} {$inst["addr"]} " + . "{$inst["mpu"]}\t{$text}"; $comments[$comm] = $comm; } } @@ -476,6 +540,7 @@ function output_switch($op10table, $op10 $out .= sprintf("\t case (0x%04x >> ${shift}):\n", $c * $ipb); } // コメント + usort($comments, "cmp_comments"); foreach ($comments as $comm) { if ($nb == 8) { // というか MMU というべきか @@ -486,8 +551,11 @@ function output_switch($op10table, $op10 preg_match("/(....)(......)(.*)/", $comm, $m); $comm1 = "%{$m[1]}_{$m[2]}_{$m[3]}"; } - $out .= "\t\t// {$comm1}\n"; $cpp .= "// {$comm1}\n"; + // ヘッダに出力するのはビットと名前だけに短縮。 + $comm2 = preg_replace('/(\S+)\s+\S+\s+\S+\s+(.*)/', "$1\t$2", + $comm1); + $out .= "\t\t// {$comm2}\n"; } // 関数 $out .= "\t\tOP_FUNC({$funcname});\n"; @@ -497,15 +565,15 @@ function output_switch($op10table, $op10 $cpp .= output_func($funcname); } - // 不当命令ブロックを出力 - foreach ($illegals as $i) { + // 不当命令のブロックを出力 + foreach ($not_assigned as $i) { $out .= sprintf("\t case (0x%04x >> ${shift}):\n", $i * $ipb); } $out .= "\t\tOP_FUNC(illegal);\n"; $out .= "\t\tbreak;\n"; - // 不当命令 (ILLEGAL 命令ではないので最終的にどうするかはある) - $cpp .= "// illegal instructions\n"; + // 不当命令 (ILLEGAL 命令と F ライン命令と不当命令の合流先…) + $cpp .= "// illegal (or not-assigned) instructions\n"; $cpp .= output_func("illegal"); // ファイルに出力 @@ -533,6 +601,7 @@ function output_header($op10hash) foreach ($op10hash as $name) { $out .= "OP_PROTO({$name});\n"; } + $out .= "OP_PROTO(illegal);\n"; // ファイルに出力 write_file("ops.h.new", $out);