---
title: 替换x86 pcmpestri汇编指令
description: "编译报错Error: unknown mnemonic 'pcmpestri' -- 'pcmpestri'。"
url: https://www.hikunpeng.com/document/detail/zh/kunpenggrf/codeprtr/kunpengtaishanporting_12_0019.html
sourcePath: /source/zh/kunpenggrf/codeprtr/kunpengtaishanporting_12_0019.html
indexId: 84a4a6f80ac1cf449209040011cbb55f04819f6da658e4538e03b7f01c31a79765
---
# 替换x86 pcmpestri汇编指令

#### 现象描述

编译报错Error: unknown mnemonic 'pcmpestri' -- 'pcmpestri'。


#### 问题原因

与pcmpestrm指令类似，pcmpestri也是x86 SSE4指令集中的指令。根据指令介绍，其用途是根据指定的比较模式，判断字符串str2的字节是否在str1中出现，返回匹配到的位置索引（首个匹配结果为0的位置）。同样，对于该指令，需要彻底了解其功能，通过C代码重新实现。

指令介绍：

https://software.intel.com/sites/landingpage/IntrinsicsGuide/#techs=SSE4_2&expand=834(https://software.intel.com/sites/landingpage/IntrinsicsGuide/#techs=SSE4_2&expand=835,834)

https://docs.microsoft.com/zh-cn/previous-versions/visualstudio/visual-studio-2010/bb531465(v=vs.100)(https://docs.microsoft.com/zh-cn/previous-versions/visualstudio/visual-studio-2010/bb531465(v=vs.100))


#### 处理步骤

如下代码段是Impala中对pcmpestri指令的调用，该调用参考Intel的_mm_cmpestri接口实现将pcmpestri指令封装成SSE4_cmpestri：

```
template<int MODE>
static inline int SSE4_cmpestri(__m128i str1, int len1, __m128i str2, int len2) {
int result;
__asm__ __volatile__("pcmpestri %5, %2, %1": "=c"(result) : "x"(str1), "xm"(str2), "a"(len1), "d"(len2), "i"(MODE) : "cc");
return result;
}
```

从指令介绍中看，不同的模式所执行的操作差异较大，完全实现指令功能所需代码行太多。结合代码中对接口的调用，实际使用到的模式为PCMPSTR_EQUAL_EACH | PCMPSTR_UBYTE_OPS | PCMPSTR_NEG_POLARITY。即按照字节长度做匹配，对str1与str2做对应位置字符是否相等判断，若相等，则将对应bit位置设置为1，最后输出首次出现1的位置。

根据该思路进行代码实现：

```
#include <arm_neon.h>
template <int MODE>
static inline int SSE4_cmpestri(int32x4_t str1, int len1, int32x4_t str2, int len2)
{
__oword a, b;
a.m128i = str1;
b.m128i = str2;
int len_s, len_l;
if (len1 > len2)
{
len_s = len2;
len_l = len1;
}
else
{
len_s = len1;
len_l = len2;
}
//本例替换的模式STRCMP_MODE =
// PCMPSTR_EQUAL_EACH | PCMPSTR_UBYTE_OPS | PCMPSTR_NEG_POLARITY
int result;
int i;
for (i = 0; i < len_s; i++)
{
if (a.m128i_u8[i] == b.m128i_u8[i])
{
break;
}
}
result = i;
if (result == len_s)
{
result = len_l;
}
return result;
}
```
