せっかくのgather命令

バイト単位じゃないともったいない。

z = si_lqx(spu_slqw(spu_gather(y), 4), mag_lut);
r = spu_xor(spu_rlmaskqw(y,-1), z);

これだと、ワード単位のgatherになっちゃって結果が4ビットしか得られないんですよ。
1命令使って、結果がたったの4ビットですよ。
シャッフルしてからバイト単位gatherすれば、結果は16ビットになってうはうはだと思ったんです。

x = spu_shuffle(y, _, s);
z = si_lqx(spu_gather((vector byte)x), mag_lut);
r = spu_xor(spu_rlmaskqw(y,-1), z);

シャッフルで下4バイトに0を放り込んで、その上に目的のバイトを並べとけば4ビットシフトはいらなくなりました。
しかも、シャッフルの引数が一個余ってる。

シャッフルの引数を有効利用するためにふたつを一度にやってみると

r0 = (y0 >> 1) ^ mag01[y0 & 1]
r1 = (y1 >> 1) ^ mag01[y1 & 1]

x = spu_gather((vector byte)spu_shuffle(y0, y1, s));
z0 = si_lqx(x, mag_lut0);
z1 = si_lqx(x, mag_lut1);
r0 = spu_xor(spu_rlmaskqw(y0,-1), z0); 
r1 = spu_xor(spu_rlmaskqw(y1,-1), z1); 

これで、even*2+odd*6だからひとつ当たりだとeven*1+odd*3になりました。
ルックアップテーブルが大きくなりますが、256エントリのテーブルをふたつは余裕で収まったので問題なし。