概要
ilasmでstack machineやってみた。
俺cpuはstack machineなので、ilasmのニーモニックが動くように改造してみる。
ilasmをrom化してみる。
方針
- Plunkerを使う。
- verilogで使えるように
写真
投入したソース
fizzbuzz
ldc.i4 100
stloc b
ldc.i4 1
stloc a
loop:
ldloc a
ldloc b
bgt bye
ldloc a
ldc.i4 15
rem
brfalse fb
ldloc a
ldc.i4 5
rem
brfalse b
ldloc a
ldc.i4 3
rem
brfalse f
ldloc a
call void [mscorlib] System.Console::WriteLine(int32)
br tugi
fb:
ldstr "fibu"
br print
b:
ldstr "buzz"
br print
f:
ldstr "fizz"
print:
call void [mscorlib] System.Console::WriteLine(string)
tugi:
ldloc a
ldc.i4 1
add
stloc a
br loop
bye:
ret
実行結果
mem[8'd0] = 12'h164;
mem[8'd1] = 12'hf0b;
mem[8'd2] = 12'h101;
mem[8'd3] = 12'hf09;
mem[8'd4] = 12'hf0a;
mem[8'd5] = 12'hf0c;
mem[8'd6] = 12'h71f;
mem[8'd7] = 12'hf0a;
mem[8'd8] = 12'h10f;
mem[8'd9] = 12'hf06;
mem[8'd10] = 12'ha15;
mem[8'd11] = 12'hf0a;
mem[8'd12] = 12'h105;
mem[8'd13] = 12'hf06;
mem[8'd14] = 12'ha17;
mem[8'd15] = 12'hf0a;
mem[8'd16] = 12'h103;
mem[8'd17] = 12'hf06;
mem[8'd18] = 12'ha19;
mem[8'd19] = 12'hf0a;
mem[8'd20] = 12'h400;
mem[8'd21] = 12'h91a;
mem[8'd22] = 12'h201;
mem[8'd23] = 12'h266;
mem[8'd24] = 12'h269;
mem[8'd25] = 12'h262;
mem[8'd26] = 12'h275;
mem[8'd27] = 12'h200;
mem[8'd28] = 12'h91a;
mem[8'd29] = 12'h201;
mem[8'd30] = 12'h262;
mem[8'd31] = 12'h275;
mem[8'd32] = 12'h27a;
mem[8'd33] = 12'h27a;
mem[8'd34] = 12'h200;
mem[8'd35] = 12'h91a;
mem[8'd36] = 12'h201;
mem[8'd37] = 12'h266;
mem[8'd38] = 12'h269;
mem[8'd39] = 12'h27a;
mem[8'd40] = 12'h27a;
mem[8'd41] = 12'h200;
mem[8'd42] = 12'h500;
mem[8'd43] = 12'hf0a;
mem[8'd44] = 12'h101;
mem[8'd45] = 12'hf02;
mem[8'd46] = 12'hf09;
mem[8'd47] = 12'h904;
mem[8'd48] = 12'h001;
サンプルコード
コンパイラ
var out = document.getElementById("out");
var src = document.getElementById("src");
function hexs(val) {
var v = val.charCodeAt(0);
var w = v.toString(16);
w = "0000" + w;
code = w.substring(w.length - 2, w.length);
return code
}
function hex(val) {
var v = parseInt(val);
var w = v.toString(16);
w = "0000" + w;
code = w.substring(w.length - 2, w.length);
return code
}
function run() {
var str = src.value;
str = str.replace(/\t/g, " ");
str = str.replace(/ /g, " ");
str = str.replace(/ /g, " ");
str = str.replace(/ /g, " ");
var codes = str.split("\n");
var pc = 0;
var len = codes.length;
var i;
var label = {};
var res = "";
var adr = 0;
for (i = 0; i < len; i++)
{
if (codes[i].indexOf(":") > -1)
{
label[codes[i]] = adr;
}
else if (codes[i] == "ldstr")
{
adr += 6;
}
else
{
adr++;
}
}
adr = 0;
while (i > 0)
{
var code = codes[pc].split(" ");
switch (code[1])
{
case "ldstr":
res += "mem[8'd" + adr + "] = 12'h201;\n";
adr++;
res += "mem[8'd" + adr + "] = 12'h2" + hexs(code[2][1]) + ";\n";
adr++;
res += "mem[8'd" + adr + "] = 12'h2" + hexs(code[2][2]) + ";\n";
adr++;
res += "mem[8'd" + adr + "] = 12'h2" + hexs(code[2][3]) + ";\n";
adr++;
res += "mem[8'd" + adr + "] = 12'h2" + hexs(code[2][4]) + ";\n";
adr++;
res += "mem[8'd" + adr + "] = 12'h200;\n";
pc++;
adr++;
break;
case "ldc.i4":
res += "mem[8'd" + adr + "] = 12'h1" + hex(code[2]) + ";\n";
pc++;
adr++;
break;
case "stloc":
if (code[2] == "a")
res += "mem[8'd" + adr + "] = 12'hf09;\n";
if (code[2] == "b")
res += "mem[8'd" + adr + "] = 12'hf0b;\n";
pc++;
adr++;
break;
case "ldloc":
if (code[2] == "a")
res += "mem[8'd" + adr + "] = 12'hf0a;\n";
if (code[2] == "b")
res += "mem[8'd" + adr + "] = 12'hf0c;\n";
pc++;
adr++;
break;
case "call":
if (code[4] == "System.Console::WriteLine(int32)")
res += "mem[8'd" + adr + "] = 12'h400;\n";
if (code[4] == "System.Console::WriteLine(string)")
res += "mem[8'd" + adr + "] = 12'h500;\n";
pc++;
adr++;
break;
case "br":
res += "mem[8'd" + adr + "] = 12'h9" + hex(label[code[2] + ":"]) + ";\n";
pc++;
adr++;
break;
case "brtrue":
res += "mem[8'd" + adr + "] = 12'hb" + hex(label[code[2] + ":"]) + ";\n";
pc++;
adr++;
break;
case "brfalse":
res += "mem[8'd" + adr + "] = 12'ha" + hex(label[code[2] + ":"]) + ";\n";
pc++;
adr++;
break;
case "bgt":
res += "mem[8'd" + adr + "] = 12'h7" + hex(label[code[2] + ":"]) + ";\n";
pc++;
adr++;
break;
case "add":
res += "mem[8'd" + adr + "] = 12'hf02;\n";
pc++;
adr++;
break;
case "mul":
res += "mem[8'd" + adr + "] = 12'hf04;\n";
pc++;
adr++;
break;
case "sub":
res += "mem[8'd" + adr + "] = 12'hf03;\n";
pc++;
adr++;
break;
case "div":
res += "mem[8'd" + adr + "] = 12'hf05;\n";
pc++;
adr++;
break;
case "rem":
res += "mem[8'd" + adr + "] = 12'hf06;\n";
pc++;
adr++;
break;
case "ret":
res += "mem[8'd" + adr + "] = 12'h001;\n";
i = 0;
break;
case undefined:
pc++;
break;
default:
alert(code[1]);
pc++;
break;
}
}
out.value = res;
}
成果物
以上