原来有个PSHFUD啊
:)
不过通篇不提MMX寄存器
实际上
MMX的32位乘快于SSE 可设计五个方案
1、MM积存器操作的
2、XMM寄存器操作的
3、混合寄存器操作的
4、2加双乘的
5、3加双乘的 谁有最新的指令的周期数据
晚于P4即可
回复 33# 的帖子
见我在 http://bbs.emath.ac.cn/viewthread.php?tid=173&page=1&fromuid=8#pid885 发的链接,那个 2.47MB 的压缩包就有你需要的东西(Instruction tables),它也曾对我有很大的帮助。 MMX刚写好, 120条, 似乎有点编译问题
(作废!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)
mov esi, left
mov edi, right
mov ebx, result
movd mm0,
pmuludq mm0,
movd , mm0
pshrq mm0, 32
movd mm1,
pmuludq mm1,
movd mm2,
pmuludq mm2,
//mm0+mm1+mm2
paddq mm0, mm1
movd mm1, mm0
pshrq mm0, 32
movd mm3, mm2
pshrq mm2, 32
paddq mm1, mm3
paddq mm0, mm2
movd , mm1
pshrq mm1, 32
paddq mm0, mm1
movd mm1,
pmuludq mm1,
movd mm2,
pmuludq mm2,
movd mm3,
pmuludq mm3,
//mm0+mm1+mm2+mm3
movd mm6, mm0
pshrq mm0, 32
movd mm7, mm1
pshrq mm1, 32
paddq mm6, mm7
movd mm7, mm2
pshrq mm2, 32
paddq mm6, mm7
movd mm7, mm3
pshrq mm3, 32
paddq mm6, mm7
paddq mm0, mm1
paddq mm0, mm2
paddq mm0, mm3
movd , mm6
pshrq mm6, 32
paddq mm0, mm6
movd mm1,
pmuludq mm1,
movd mm2,
pmuludq mm2,
movd mm3,
pmuludq mm3,
movd mm4,
pmuludq mm4,
//mm0+mm1+mm2+mm3+mm4
movd mm5, mm1
paddq mm0, mm5
pshrq mm1, 32
movd mm6, mm2
paddq mm0, mm6
pshrq mm2, 32
movd mm7, mm3
paddq mm0, mm7
pshrq mm3, 32
movd mm5, mm4
paddq mm0, mm5
psrq mm4, 32
paddq mm1, mm2
movd , mm0
paddq mm1, mm3
psrq mm0, 32
paddq mm1, mm4
paddq mm0, mm1
movd mm2,
pmuludq mm2,
movd mm1,
pmuludq mm1,
movd mm3,
pmuludq mm3,
//mm0+mm1+mm2+mm3
movd mm6, mm0
pshrq mm0, 32
movd mm7, mm1
pshrq mm1, 32
paddq mm6, mm7
movd mm7, mm2
pshrq mm2, 32
paddq mm6, mm7
movd mm7, mm3
pshrq mm3, 32
paddq mm6, mm7
paddq mm0, mm1
paddq mm0, mm2
paddq mm0, mm3
movd , mm6
pshrq mm6, 32
paddq mm0, mm6
mov mm1,
pmuludq mm1,
mov mm2,
pmuludq,
//mm0+mm1+mm2
paddq mm0, mm1
movd mm1, mm0
pshrq mm0, 32
movd mm3, mm2
pshrq mm2, 32
paddq mm1, mm3
paddq mm0, mm2
movd , mm1
pshrq mm1, 32
paddq mm0, mm1
mov mm1,
pmuludq,
//mm0+mm1
movd mm6, mm0
pshrq mm0, 32
movd mm7, mm0
pshrq mm1, 32
paddq mm6, mm7
movd , mm6
pshrq mm6, 32
paddq mm0, mm1
paddq mm0, mm6
movd , mm0
emms
ret; 版本太老 指令PSHUFW类似PSHUFD, 但针对mmx
又仔细搜索了文档, 还是找不到解四字或者双字组的方法 找到解决解开包装的方法
共4条相关的
分别能解开高低64位, 高低32位到低位
如果解一个双乘128位结果
需14条指令
涉及除XMM结果寄存器外, 2个XMM, 4个MMX寄存器
故指令条数应>(14 + 3(乘法)) * 8 + 8(保守估计加需要, 肯定更多) * 8 > 200条
=======================================
上面作废的MMX代码
修改下, 估计在140条内能解决
如果估计没错误, MMX乘是3个周期, SSE2双乘是5个, 此乃流水线周期
========================================
谁有更好方案? MMX寄存器使用SSE2指令的写出来了
但存在点错误在调试
初步测试时间是C写法的1/3 第一个可用代码,此问题MMX指令完全不可用
void UInt128x128To256_SSE2_40F( UINT32 * const result,
const UINT32 * const left,
const UINT32 * const right )
{
//使用MMX寄存器, 但用SSE2指令
__asm
{
mov esi, left
mov edi, right
mov ebx, result
//0:0
movd mm0,
pmuludq mm0,
movd , mm0
psrlq mm0, 32
// 0:1 1:0
movd mm1,
pmuludq mm1,
movd mm2,
pmuludq mm2,
mov eax, -1
//mm0+mm1+mm2
paddq mm0, mm1//mm0=mm0+mm1 mm0肯定小于 2^64
movd mm1, eax
pand mm1, mm0
psrlq mm0, 32 //分解mm0 = mm0:mm1
movd mm3, eax
pand mm3, mm2
psrlq mm2, 32 //分解mm2=mm2:mm3
paddq mm1, mm3 //mm1=mm1+mm3
paddq mm0, mm2 //mm0=mm0+mm2
movd , mm1 //mm1低位存储
psrlq mm1, 32 //mm1高位
paddq mm0, mm1 //得到进位
//1:1 0:2 2:0
movd mm1,
pmuludq mm1,
movd mm2,
pmuludq mm2,
movd mm3,
pmuludq mm3,
//mm0+mm1+mm2+mm3
movd mm6, eax
pand mm6, mm0
psrlq mm0, 32 //分解mm0=mm0:mm6
movd mm5, eax
pand mm5, mm1
psrlq mm1, 32 //分解mm1=mm1:mm5
paddq mm6, mm5 //mm6=mm6+mm5
paddq mm0, mm1 //mm0=mm0+mm1
movd mm4, eax
pand mm4, mm2
psrlq mm2, 32 //分解mm2=mm2:mm4
paddq mm6, mm4 //mm6=mm6+mm4
paddq mm0, mm2 //mm0=mm0+mm2
movd mm7, eax
pand mm7, mm3
psrlq mm3, 32 //分解mm3=mm3:mm7
paddq mm6, mm7 //mm6=mm6+mm7
paddq mm0, mm3 //mm0=mm0+mm3
movd , mm6 //mm6低位存储
psrlq mm6, 32
paddq mm0, mm6 //得到进位
//0:3 1:2 2:1 3:0
movd mm1,
pmuludq mm1,
movd mm2,
pmuludq mm2,
movd mm3,
pmuludq mm3,
movd mm4,
pmuludq mm4,
//mm0+mm1+mm2+mm3+mm4
movd mm5, eax
pand mm5, mm1
psrlq mm1, 32 //分解mm1=mm1:mm5
paddq mm0, mm5 //mm0=mm0+mm5
movd mm6, eax
pand mm6, mm2
psrlq mm2, 32 //分解mm2=mm2:mm6
paddq mm0, mm6 //mm0=mm0+mm6
paddq mm1, mm2 //mm1=mm1+mm2
movd mm7, eax
pand mm7, mm3
psrlq mm3, 32 //分解mm3=mm3:mm7
paddq mm0, mm7 //mm0=mm0+mm7
paddq mm1, mm3 //mm1=mm1+mm3
movd mm5, eax
pand mm5, mm4
psrlq mm4, 32 //分解mm4=mm4:mm5
paddq mm0, mm5 //mm0=mm0+mm5
paddq mm1, mm4 //mm1=mm1+mm4
movd , mm0 //mm0低位存储
psrlq mm0, 32
paddq mm0, mm1 //新进位
//1:3 2:2 3:1
movd mm2,
pmuludq mm2,
movd mm1,
pmuludq mm1,
movd mm3,
pmuludq mm3,
//mm0+mm1+mm2+mm3
movd mm7, eax
pand mm7, mm0
psrlq mm0, 32 //分解mm0=mm0:mm7
movd mm6, eax
pand mm6, mm1
psrlq mm1, 32 //分解mm1=mm1:mm6
paddq mm7, mm6 //mm7=mm7+mm6
paddq mm0, mm1 //mm0=mm0+mm1
movd mm5, eax
pand mm5, mm2
psrlq mm2, 32 //分解mm2=mm2:mm5
paddq mm7, mm5 //mm7=mm7+mm5
paddq mm0, mm2 //mm0=mm0+mm2
movd mm4, eax
pand mm4, mm3
psrlq mm3, 32 //分解mm3=mm3:mm4
paddq mm7, mm4 //mm7=mm7+mm4
paddq mm0, mm3 //mm0=mm0+mm3
movd , mm7 //mm7低位存储
psrlq mm7, 32
paddq mm0, mm7 //得到进位
//2:3 3:2
movd mm1,
pmuludq mm1,
movd mm2,
pmuludq mm2,
//mm0+mm1+mm2
movd mm7, eax
pand mm7, mm0
psrlq mm0, 32 //分解mm0=mm0:mm7
movd mm6, eax
pand mm6, mm1
psrlq mm1, 32 //分解mm1=mm1:mm6
paddq mm7, mm6 //mm7=mm7+mm6
paddq mm0, mm1 //mm0=mm0+mm1
movd mm5, eax
pand mm5, mm2
psrlq mm2, 32 //分解mm2=mm2:mm5
paddq mm7, mm5 //mm7=mm7+mm5
paddq mm0, mm2 //mm0=mm0+mm2
movd , mm7 //mm7低位存储
psrlq mm7, 32
paddq mm0, mm7 //得到进位
//3:3
movd mm1,
pmuludq mm1,
//mm0+mm1
movd mm6, eax
pand mm6, mm0
psrlq mm0, 32 //分解mm0=mm0:mm6
movd mm7, eax
pand mm7, mm1
psrlq mm1, 32 //分解mm1=mm1:mm7
paddq mm6, mm7 //mm6=mm6+mm7
paddq mm0, mm1 //mm0=mm0+mm1
movd , mm6 //mm6低位存储
psrlq mm6, 32
paddq mm0, mm6 //进位
movd , mm0 //存储
emms
//ret
}
}