http://comcat.blog.openrays.org/blog-htm-do-showone-tid-178.html
0. 概述
龙芯2E多媒体指令支持基于字节、半字、字以及双字整数的并行操作。这个与Intel的MMX很类似。事实上龙芯的多媒体指令吸取了MMX、SSE的优秀思想,并作了一些扩充。可惜目前龙芯仅支持对整数的并行操作,不支持SIMD浮点模型,期待龙芯的后续系列在多媒体方面能有大幅的提高。
另龙芯实现了双精度浮点指令(Paired-single, PS),可以同时对2个单精度数的浮点操作,庶几可以弥补一些遗憾。
龙芯2E多媒体指令直接使用FPU的浮点寄存器(64位,32个)作为多媒体寄存器。
龙芯2E多媒体指令的操作对象为64位,可以分割成8*8, 16*4, 32*2, 64*1。如果每个单元为8位(称为Packed byte)则有8个这样的单元;若每个单元为32位(Packed word)则有2个这样的单元。而每条指令可以同时对这几个单元进行操作(SIMD)。
这个在图像处理中很有用,可以同时处理8个像素(24位,RGB,每像素一个字节)。
注:龙芯体系结构下定义每个字(word)为32位,注意与x86的差别。
1. 龙芯多媒体指令介绍
注意: 因为目前尚无公开的龙芯多媒体指令文档,以下属我分析,未经一一验证,部分经验证、测试的指令会指出。
先给个指令列表吧,该列表从龙芯开发者为汇编器as提供的补丁中取出。
pandn
psrlh/psrlw
psrah/psraw
psllh/psllw
paddsh
paddush
paddb/paddh/paddw/paddd
paddsb
paddusb
psubsh
psubush
psubb/psubh/psubw/psubd
psubsb
psubusb
pmullh
pmulhh
pmuluw
pmulhuh
pmaddhw
pcmpeqb/pcmpeqh/pcmpeqw
pcmpgtb/pcmpgth/pcmpgtw
pmaxsh
pmaxub
pminsh
pminub
packsswh
packsshb
packushb
punpcklwd
punpckhwd
punpcklhw
punpckhhw
punpcklbh
punpckhbh
pavgh
pavgb
pshufh
pmovmskb
pextrh
pinsrh_0
pinsrh_1
pinsrh_2
pinsrh_3
for
fxor
fnor
fand
fsrl
fdsrl
fsra
fdsra
fsll
fdsll
fadd
faddu
fdadd
fsub
fsubu
fdsub
fseq
fseq1
fsltu
fslt
fsleu
fsle
pasubub
biadd
上述指令中,黑色的是可以对应于MMX指令,故而可以参考MMX的文档,绿色的对应SSE指令,红色的则为龙芯自定义的指令。下面要做的就是参考MMX、SSE的文档,测试、验证并熟悉这些指令,为进行多媒体优化作准备。
给个测试例子程序先:
#include <stdio.h>
unsigned short data[] = {
0x0, 0x0, 0x0, 0x0,
0x1, 0x3, 0x5, 0x7,
0x1, 0x3, 0x5, 0x7,
0x2, 0x4, 0x6, 0x8
};
inline void pmullh(unsigned short * const row)
{
asm volatile
(
".set mips3\n\t"
".set noreorder\n\t"
"ldc1 $f0, %1\n\t"
"ldc1 $f2, %2\n\t"
"pmullh $f2, $f2, $f0\n\t"
"sdc1 $f2, %0\n\t"
".set reorder\n\t"
".set mips0\n\t"
: "=m"(*row)
: "m"(*(row+4)), "m"(*(row+8)), "m"(*(row+12))
: "$f0", "$f2", "memory"
);
}
int main()
{
printf("%x, %x, %x, %x\n", data[0], data[1], data[2], data[3]);
pmullh(data);
printf("%d, %d, %d, %d\n", data[0], data[1], data[2], data[3]);
}
在盒子上,输出结果为:
0, 0, 0, 0
1, 9, 25, 49
可以看到,龙芯上的pmullh与MMX之pmullw的行为是一致的!!
(秩名) |