lut を使う場合に 4bit x4 で無難に実装しているんだが 1 bit + 5 bit x3 の実装を試してみたが、これがかなり tricky にわりと早くメモリ消費もそこそこらしいというコードができた.
lea table+0x80,a0 moveq #0x3e,d1 moveq #0,d0 ;output q add.w d2,d2 ;input d #if delta >= 8 roxr.w #16-delta,d0 #elif delta >= 1 roxl.w #delta+1,d0 #else ;delta == 0 addx.w d0,d0 #endif move.w d2,d3 and.w d1,d3 or.w (-0x80,a0,d3.w),d0 lsr.w #5,d2 move.w d2,d3 and.w d1,d3 or.w (-0x40,a0,d3.w),d0 lsr.w #5,d2 and.w d1,d2 or.w (0,a0,d2.w),d0
src 15 to dest:clocks 0: 112 8: 130 1: 118 9: 128 2: 120 10: 126 3: 122 11: 124 4: 124 12: 122 5: 126 13: 120 6: 128 14: 118 7: 130 15: 116
delta は src bit 15 が dest bit 0 からの移動量ということになり、それらの条件で生成する命令や実行時間がことなってくる.
lut へは (d8,an,IX) の addressing で取り込むのだが、68000 は index に scale をつけられない上に 16 bit 単位アクセスなので、通常は index を左循環1回をやってから右循環を繰り返して index を作成することになる.
ここでは左循環1回ではなく左シフト1回相当の add.w d2,d2 を使って src bit 15 を X に追いやる. X を bit0 にいれる場合は addx d0,d0, bit 1 に入れる場合は roxl.w #2,d0, bit 15 に入れる場合は roxr.w #1,d0 となる.
src bit 15 を片付けると index は都合よくズレているので lsr.w で随時 index 作成となる.
src bit 15 に対する dest bit が 7 とか 8 だと循環回数が 8 回になって遅いが addx が使えるのならとても早くてメモリ消費も悪くないというコード.
lut 3 段は他に試作したコードは下記があり 5*2+6 がバランスがよいだろうということになる.
i o step shift clocks elemnts bytes 16 16 16 1 42 0x10000 0x20000 16 16 8*2 9 98 0x200 0x400 16 16 4*4 13 142 0x40 0x80 16 16 4*2+8 9 116 0x120 0x240 16 16 5*2+6 11 122 0x80 0x100 16 16 1+5*3 11+n 112..130 0x60 0xc0 16 16 4+6*2 11 126 0x90 0x120