* 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バイト→?||

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS