MD5 Optimized in MMX part5

前回の続き:(http://d.hatena.ne.jp/studiokingyo/20051216
MD5MMX用のマクロは以下ので間違いないはずなんですが・・・(テストをしましたが多分どこか間違っている。)
どうも、マクロなためデバッガで追いにくいのでバグがチマチマと発生しているようです。

多分、マクロの引数のx,y,zあたりがアップデートされてバグっているのでしょうね。


/*
#define MD5_VC_MMX_STEP(f, w, x, y, z, data, s) \
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
core rotate plus
*/

上記のようにwの部分だけがアップデートされるんですよ。
とりあえず、C言語のマクロ版と関数版とMMX inline assembler マクロ版を載っけておきます。
ちなみにMMX inline assembler マクロ版はバグっていると思います。設計自体がミスっているのでバグを取ってくださる有志の方がいらっしゃっても取らなくてOKれす。


C言語

#define C_F1(d,x, y, z) (d = (z ^ (x & (y ^ z))))
#define C_F2(d,x,y,z) C_F1(d,z,x,y)
#define C_F3(d,x, y, z) (d = (x ^ y ^ z))
#define C_F4(d,x, y, z) (d = (y ^ (x | ~z)))
#define C_CORE(d,w,f,x,y,z,data) (d = (w += f(d,x, y, z) + data))
#define MD5STEP(f, w, x, y, z, data, s,te) \
( C_CORE(te,w,f,x,y,z,data), w = w<<s | w>>(32-s),w += x )

typedef uint32 (*md5_function_t)(uint32,uint32,uint32);


///#define C_F1(d,x, y, z) (d = (z ^ (x & (y ^ z))))
inline uint32 c_f1(uint32 x,uint32 y,uint32 z){
uint32 t = (z ^ (x & (y ^ z)));
return t;
}

///#define C_F2(d,x,y,z) C_F1(d,z,x,y)
inline uint32 c_f2(uint32 x,uint32 y,uint32 z){
uint32 t = c_f1(z,x,y);
return t;
}
///#define C_F3(d,x, y, z) (d = (x ^ y ^ z))
DKC_INLINE uint32 c_f3(uint32 x,uint32 y,uint32 z){
uint32 t = (x ^ y ^ z);
return t;
}
///#define C_F4(d,x, y, z) (d = (y ^ (x | ~z)))
DKC_INLINE uint32 c_f4(uint32 x,uint32 y,uint32 z){
uint32 t = (y ^ (x | ~z));
return t;
}

DKC_INLINE uint32 c_rotate(uint32 w,uint32 s){
uint32 t = w<<s | w>>(32-s);
return t;
}
DKC_INLINE uint32 c_core(
md5_function_t f,
uint32 w,uint32 x,uint32 y,uint32 z,
uint32 data)
{
uint32 t = f(x,y,z);
t += data;
t += w;
return t;
}
DKC_INLINE void c_md5step(md5_function_t f,
uint32 *w,uint32 *x,uint32 *y,uint32 *z,
uint32 data,uint32 s)
{
uint32 t = c_core(f,*w,*x,*y,*z,data);
t = c_rotate(t,s);
*w = t + *x;
}

MD5 MMX inline assembler マクロ版(bug持ち)



/**
#define MD5_VC_MMX_F1(x, y, z) (z ^ (x & (y ^ z)))
d:dest x:mm0 y:mm1 z:mm2
*/

#define MD5_VC_MMX_F1(d,x,y,z)\
_asm pxor y,z\
_asm pand x,y\
_asm pxor z,x\
_asm movq d,z

#define MD5_VC_MMX_F2(d,x, y, z) MD5_VC_MMX_F1(d,z, x, y)

///#define MD5_VC_MMX_F3(x, y, z) (x ^ y ^ z)
#define MD5_VC_MMX_F3(d,x,y,z)\
_asm pxor y,z\
_asm pxor x,y\
_asm movq d,x



///#define MD5_VC_MMX_F4(x, y, z) (y ^ (x | ~z))
#define MD5_VC_MMX_F4(d,x,y,z)\
_asm pandn z,mm5\
_asm por x,z\
_asm pxor y,x\
_asm movq d,y



/* This is the central step in the MD5 algorithm.
#define MD5_VC_MMX_STEP(f, w, x, y, z, data, s) \
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
core rotate plus
*/

#define MD5_VC_MMX_CORE(temp,w,f,x,y,z,data)\
f(temp,x,y,z)\
_asm paddd temp,data\
_asm paddd w,temp


///out d
///w = w<<s | w>>(32-s)
#define MD5_VC_MMX_ROTATE(d,w,s)\
_asm movq d,w\
_asm psllq d,s\
_asm psrlq w,32-s\
_asm por d,w


///lastout w,temp
#define MD5_VC_MMX_STEP(f, w, x, y, z, data, s,temp) \
_asm movq mm7,x\
MD5_VC_MMX_CORE(temp,w,f,x,y,z,(data))\
MD5_VC_MMX_ROTATE(temp,w,s)\
_asm paddd temp,mm7\
_asm movq w,temp