* kharc #03
-(by [[K]], 2025.07.29)
** (0) これはなに?
-kharcでいろいろやってみるページ
** 2025.07.29 Tue #0
-uckの代入式の解釈のやり方
[1] 0-5-2-94-2; (3バイト)
→読みやすくするためにカッコを付けるとこうなる: 0 (5 2 94) 2;
0は代入命令。末尾の2は変数番号(i2:y)。
5 2 94 が少し難しい。 5 は 引き算。2は2つ前の代入式で代入された値(i6:y1)。
94は0x14のことなので、20。
これをまとめるとこうなる: let (- y1 20) y; → y = y1 - 20;
[2] 0-5-2-94-1; (3バイト)
→ 0 (5 2 94) 1;
→ let (- x1 20) x;
→ x = x1 - 20;
[3] 0-db1-9f-4-6-1-1-6-2-2-3; (7バイト)
→ 0 (db1 (9f (4 (6 1 1) (6 2 2)))) 3;
→ let (ff16Sqrt (<<16 (+ (* x x) (* y y)))) d;
→ d = ff16Sqrt((x * x + y * y) << 16);
[4] 0-b0-6-db2-5-b3-6-1-e28c-8c-6-a0-e413-c64-4-1-9f-85-4; (17.5バイト)
→ 0 (b0 (6 (db2 (5 (b3 (6 1 e28c) 8c) (6 a0 e413))) c64) (4 1 (9f 85))) 4;
→ let (/ (* (ff16Sin (- (>> (* d 652) 12) (* t 1043))) 100) (+ d (<<16 5))) z;
→ z = ff16Sin(((d * 652) >> 12) - 1043 * t) * 100 / (d + (5<<16));
[5] 0-4-6-a6-c2a-a5-3; (5.5バイト)
→ 0 (4 (6 a6 c2a) a5) 3;
→ let (+ (* y1 42) x1) d;
→ d = y1 * 42 + x1;
-簡単な変換方法: (kharcはスタックマシンではなくレジスタマシンなので、JITコンパイルの際には変換する必要があるのです。)
func temp() { return str("t%d", tempNo++); }
func val(zero)
{
i = get(); switch (i) {
case 0: return str("%d", zero);
case 1~3: return repeat[i - 1];
case 4: t = temp(); put(str("%s = %s + %s;", t, val(1), val(1))); return t;
case 5: t = temp(); put(str("%s = %s - %s;", t, val(1), val(1))); return t;
case 6: t = temp(); put(str("%s = %s * %s;", t, val(2), val(2))); return t;
case 0x80~0x98: return str("%d", i - 0x80);
case 0x99~0x9e: return str("%d", 32 << (i - 0x99));
case 0x9f: t = temp(); put(str("%s = %s << 16;", val(1))); return t;
case 0xa0~0xaf: return str("i%d", i - 0xa0);
case 0xb0: t = temp(); put(str("%s = %s / %s;", t, val(1), val(3))); return t;
case 0xb3: t = temp(); put(str("%s = %s >> %s;", t, val(0), val(1))); return t;
case 0xc00~0xcff: return str("%d", i - 0xc00);
case 0xdb1: t = temp(); put(str("%s = ff16Sqrt(%s);", t, val(0))); return t;
case 0xdb2: t = temp(); put(str("%s = ff16Sin(%s);", t, val(0))); return t;
}
}
func let() { tempNo = 0; v = val(0); i = get(); put(str("i%d = %s;", i, v)); updateRepeat(i); }
-変換例
0-5-2-94-2; → t0 = i6 - 20; i2 = t0;
0-5-2-94-1; → t0 = i5 - 20; i1 = t0;
0-db1-9f-4-6-1-1-6-2-2-3; → t3 = i1 * i1; t4 = i2 * i2; t2 = t3 + t4; t1 = t2 << 16; t0 = ff16Sqrt(t1); i3 = t0;
** 2025.08.14 Thu #0
-現状のまとめ:
|mandel|RIGHT:79バイト|OSECPU-VM rev2 では109バイト(シグネチャを抜いて比較)|
|3dwave|RIGHT:95バイト||
|kcube(6色)|RIGHT:344バイト|第一世代OSASKでは1393バイト|
|kcube(単色)|RIGHT:405バイト||
|hexdump|RIGHT:[推定]86バイト|OSECPU-VM rev2 では102バイト(シグネチャを抜いて比較)|
|hello|RIGHT:[推定]13バイト|OSECPU-VM rev1 では13バイト(シグネチャを抜いて比較)|
|chars|RIGHT:[推定]6バイト|OSECPU-VM rev1 では6バイト(シグネチャを抜いて比較)|
-まだ十分に検討しきれていないところ: 変数リピート指定では、更新時だけではなく参照時もリピート列を更新するべきなのかどうか。
-その他にも、まだ細かい調整要素はあるので、数パーセントは変動する可能性がある。
** 2025.08.26 Tue #0
-現状のまとめ:
|mandel|RIGHT:79バイト→75バイト|OSECPU-VM rev2 では109バイト(シグネチャを抜いて比較)|
|3dwave|RIGHT:95バイト→92バイト||
|kcube(6色)|RIGHT:344バイト→?|第一世代OSASKでは1393バイト|
|kcube(6色)|RIGHT:344バイト→340バイト|第一世代OSASKでは1393バイト|
|kcube(単色)|RIGHT:405バイト→?||