我正在尝试编写一个例程,逻辑上将n位置向右移位,以最有效的方式为向量的所有元素提供以下向量类型:BYTE-> BYTE,WORD-> WORD, DWORD-> DWORD和WORD-> BYTE(假设结果中只有8位)。我希望每种类型有三个例程,具体取决于处理器的类型(支持SSE2,仅支持MMX,仅支持标准指令)。因此我总共需要12个功能。
我自己已经找到了如何备份和恢复我需要的寄存器,如何进行循环,如何将数据复制到常规寄存器或MMX寄存器以及如何逻辑地移位1个位置。
因为我不熟悉汇编语言。 我应该为每个指令集使用哪些寄存器? 如何优化L1缓存中大矢量(图像)的可用性? 我如何找到向量的下一个元素(指针类型的东西),我知道我可以通过地址制作一个mov,我假设我必须根据我的数据类型将地址增加1,2或4? / p>
虽然我有所有的想法,但在这一点上编写代码有点困难。
谢谢。
阿诺。
编辑: 这是我正在尝试为MMX做一个在DWORD上移1:
__asm("push mm"); // backup register
__asm("push cx"); // backup register
__asm("mov %cx, length"); // initialize loop
__asm("loopstart_shift1:"); // start label
__asm("movd %xmm0, r/m32"); // get 32 bits data
__asm("psrlq %xmm0, 1"); // right shift 32 bits data logically (stuffs 0 on the left) by 1
__asm("mov r/m32,%xmm0"); // set 32 bits data
__asm("dec %cx"); // decrement index
__asm("cmp %cx,0");
__asm("jnz loopstart_shift1");
__asm("pop cx"); // restore register
__asm("pop mm"); // restore register
__asm("emms"); // leave MMX state
答案 0 :(得分:1)
我强烈建议您暂停并查看使用内在函数与C或C ++而不是尝试编写原始asm - 这样C / C ++编译器将负责所有寄存器分配,指令调度和一般内务处理任务,你可以只关注重要的部分,例如而不是psrlq
使用_m_psrlq
中的mmintrin.h
。 (更好的是,看看使用128位SSE内在函数。)
答案 1 :(得分:0)
听起来您可以使用或查看BitMagic的来源。它也完全基于内在函数,这使得它更具可移植性(尽管从它的外观看你使用GCC,所以它可能必须得到MSVC到GCC内在映射)。