#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef int /*<<< orphan*/ uint32_t;

/* Variables and functions */
char *sse4_strstr_len4(char *s1, int n1, char *s2, int n2) {
  uint32_t dummy __attribute__((unused));
  char *result;
  __asm__ volatile("movdqu (%%eax), %%xmm1" : : "a"(s1));
  __asm__ volatile("pxor    %%xmm0, %%xmm0" : :);
  __asm__ volatile("0:					\n"
                   "	movdqu (%%esi), %%xmm2		\n"
                   "	addl $8, %%esi			\n"
                   "	mpsadbw $0, %%xmm1, %%xmm2	\n"
                   "	pcmpeqw %%xmm0, %%xmm2		\n"
                   "	ptest   %%xmm2, %%xmm0		\n"
                   "	jnc     1f			\n"
                   "	subl $8, %%ecx			\n"
                   "	cmpl $0, %%ecx			\n"
                   "	jg   0b				\n"
                   "	xorl %%eax, %%eax		\n"
                   "	jmp  2f				\n"
                   "1:					\n"
                   "	pmovmskb %%xmm2, %%eax		\n"
                   "	bsfl      %%eax, %%eax		\n"
                   "	shrl         $1, %%eax		\n"
                   "	lea -8(%%esi, %%eax), %%eax	\n"
                   "2:					\n"
                   : "=a"(result), "=S"(dummy), "=c"(dummy)
                   : "S"(s2), "c"(n2 - n1));
  return result;
}


x86 assembly (clang, -O0):
<sse4_strstr_len4>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
mov    -0x8(%rbp),%rax
movdqu (%eax),%xmm1
pxor   %xmm0,%xmm0
mov    -0x18(%rbp),%rsi
mov    -0x1c(%rbp),%ecx
sub    -0xc(%rbp),%ecx
movdqu (%esi),%xmm2
add    $0x8,%esi
mpsadbw $0x0,%xmm1,%xmm2
pcmpeqw %xmm0,%xmm2
ptest  %xmm2,%xmm0
jae    1159 <sse4_strstr_len4+0x59>
sub    $0x8,%ecx
cmp    $0x0,%ecx
jg     1129 <sse4_strstr_len4+0x29>
xor    %eax,%eax
jmp    1167 <sse4_strstr_len4+0x67>
pmovmskb %xmm2,%eax
bsf    %eax,%eax
shr    %eax
lea    -0x8(%esi,%eax,1),%eax
mov    %rax,-0x28(%rbp)
mov    %esi,-0x20(%rbp)
mov    %ecx,-0x20(%rbp)
mov    -0x28(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<sse4_strstr_len4>:
mov    %rdi,%rax
movdqu (%eax),%xmm1
pxor   %xmm0,%xmm0
sub    %esi,%ecx
mov    %rdx,%rsi
movdqu (%esi),%xmm2
add    $0x8,%esi
mpsadbw $0x0,%xmm1,%xmm2
pcmpeqw %xmm0,%xmm2
ptest  %xmm2,%xmm0
jae    1136 <sse4_strstr_len4+0x36>
sub    $0x8,%ecx
cmp    $0x0,%ecx
jg     1111 <sse4_strstr_len4+0x11>
xor    %eax,%eax
jmp    1144 <sse4_strstr_len4+0x44>
pmovmskb %xmm2,%eax
bsf    %eax,%eax
shr    %eax
lea    -0x8(%esi,%eax,1),%eax
ret

LLVM IR (-O0):
define i8* @sse4_strstr_len4(i8* %0, i32 %1, i8* %2, i32 %3) {
%5 = alloca i8*
%6 = alloca i32
%7 = alloca i8*
%8 = alloca i32
%9 = alloca i32
%10 = alloca i8*
store i8* %0, i8** %5
store i32 %1, i32* %6
store i8* %2, i8** %7
store i32 %3, i32* %8
%11 = load i8*, i8** %5
%12 = load i8*, i8** %7
%13 = load i32, i32* %8
%14 = load i32, i32* %6
%15 = sub nsw i32 %13, %14
%16 = call { i8*, i32, i32 } asm sideeffect "0:\09\09\09\09\09\0A\09movdqu (%esi), %xmm2\09\09\0A\09addl $$8, %esi\09\09\09\0A\09mpsadbw $$0, %xmm1, %xmm2\09\0A\09pcmpeqw %xmm0, %xmm2\09\09\0A\09ptest %xmm2, %xmm0\09\09\0A\09jnc 1f\09\09\09\0A\09subl $$8, %ecx\09\09\09\0A\09cmpl $$0, %ecx\09\09\09\0A\09jg 0b\09\09\09\09\0A\09xorl %eax, %eax\09\09\0A\09jmp 2f\09\09\09\09\0A1:\09\09\09\09\09\0A\09pmovmskb %xmm2, %eax\09\09\0A\09bsfl %eax, %eax\09\09\0A\09shrl $$1, %eax\09\09\0A\09lea -8(%esi, %eax), %eax\09\0A2:\09\09\09\09\09\0A", "={ax},={si},={cx},{si},{cx},~{dirflag},~{fpsr},~{flags}"(i8* %12, i32 %15)
%17 = extractvalue { i8*, i32, i32 } %16, 0
%18 = extractvalue { i8*, i32, i32 } %16, 1
%19 = extractvalue { i8*, i32, i32 } %16, 2
store i8* %17, i8** %10
store i32 %18, i32* %9
store i32 %19, i32* %9
%20 = load i8*, i8** %10
ret i8* %20
}

LLVM IR (-O2):
define i8* @sse4_strstr_len4(i8* %0, i32 %1, i8* %2, i32 %3) {
tail call void asm sideeffect "movdqu (%eax), %xmm1", "{ax},~{dirflag},~{fpsr},~{flags}"(i8* %0)
tail call void asm sideeffect "pxor %xmm0, %xmm0", "~{dirflag},~{fpsr},~{flags}"()
%5 = sub nsw i32 %3, %1
%6 = tail call { i8*, i32, i32 } asm sideeffect "0:\09\09\09\09\09\0A\09movdqu (%esi), %xmm2\09\09\0A\09addl $$8, %esi\09\09\09\0A\09mpsadbw $$0, %xmm1, %xmm2\09\0A\09pcmpeqw %xmm0, %xmm2\09\09\0A\09ptest %xmm2, %xmm0\09\09\0A\09jnc 1f\09\09\09\0A\09subl $$8, %ecx\09\09\09\0A\09cmpl $$0, %ecx\09\09\09\0A\09jg 0b\09\09\09\09\0A\09xorl %eax, %eax\09\09\0A\09jmp 2f\09\09\09\09\0A1:\09\09\09\09\09\0A\09pmovmskb %xmm2, %eax\09\09\0A\09bsfl %eax, %eax\09\09\0A\09shrl $$1, %eax\09\09\0A\09lea -8(%esi, %eax), %eax\09\0A2:\09\09\09\09\09\0A", "={ax},={si},={cx},{si},{cx},~{dirflag},~{fpsr},~{flags}"(i8* %2, i32 %5)
%7 = extractvalue { i8*, i32, i32 } %6, 0
ret i8* %7
}