// File: /workspace/github_c_makefile_star2_O3/heltilda[P]cicada/ciclib.c
// Function: cclib_find
void cclib_find()
{
    window *stringToSearchWindow, *soughtStringWindow;
    linkedlist *stringToSearch, *soughtString = NULL;
    char *strPtrToSearch, *soughtStrPtr;
    ccInt numArgs, startingPosition, numMatches, charCounter, mode, matchStart, rtrn;
    
    numArgs = numBIF_args();
    if ((numArgs < 2) || (numArgs > 4))
        {  setError(wrong_argument_count_err, pcCodePtr-1);  return;  }
    
    
        // load arguments:  the string to search within, then substring to look for
    
    stringToSearchWindow = getBIFstringArg(1);
    if (errCode != passed)  return;
    soughtStringWindow = getBIFstringArg(2);
    if (errCode != passed)  return;   
    
    stringToSearch = &(stringToSearchWindow->variable_ptr->mem.data);
    soughtString = &(soughtStringWindow->variable_ptr->mem.data);
    
    
        // if argument 3 is present, load it -- it is the 'mode' (search forwards from beginning, backwards from end, or count)
    
    if (numArgs < 3)  {  mode = 1;  startingPosition = 1;  }
    else  {
        
        mode = (ccInt) getBIFnumArg(3, -1., 1.);
        
        
            // if argument 4 is present, load it -- that is the point in the big string to start looking/counting (defaults to beginning/end)
        
        if (numArgs < 4)  {
            if (mode == -1)  startingPosition = stringToSearchWindow->width;
            else  startingPosition = 1;         }
        else  {
            startingPosition = (ccInt) getBIFnumArg(4, 1., (ccFloat) (stringToSearchWindow->width-soughtStringWindow->width+1));
    }   }
    
    if (errCode != passed)  return;
    
    
        // prepare the return variable
    
    rtrn = defragmentLinkedList(stringToSearch);
    if (rtrn != passed)  {  setError(out_of_memory_err, pcCodePtr-1);  return;  }
    rtrn = defragmentLinkedList(soughtString);
    if (rtrn != passed)  {  setError(out_of_memory_err, pcCodePtr-1);  return;  }
    
    
        // get pointers to our two strings
    
    if (stringToSearchWindow->width == 0)  {  intRegister = 0;  return;  }
    if (soughtStringWindow->width == 0)  {
        if (mode == 0)  intRegister = 0;
        else  intRegister = startingPosition;
        return;     }
    soughtStrPtr = (char *) element(soughtString, soughtStringWindow->offset+1);
    strPtrToSearch = (char *) element(stringToSearch, stringToSearchWindow->offset+1);
    
    numMatches = 0;
    
    if (mode > -1)  {               // search forwards
    for (matchStart = startingPosition-1; matchStart <= stringToSearchWindow->width-soughtStringWindow->width; matchStart++)  {
        
        for (charCounter = 0; charCounter < soughtStringWindow->width; charCounter++)  {
        if (strPtrToSearch[matchStart+charCounter] != soughtStrPtr[charCounter])   {
            break;
        }}
        
        if (charCounter == soughtStringWindow->width)  {
            if (mode == 1)   {  intRegister = matchStart+1;  return;   }
            else  numMatches++;     // count
    }}  }
    
    else    {                       // search backwards
    for (matchStart = startingPosition-1; matchStart >= 0; matchStart--)  {
        
        for (charCounter = 0; charCounter < soughtStringWindow->width; charCounter++)  {
        if (strPtrToSearch[matchStart+charCounter] != soughtStrPtr[charCounter])   {
            break;
        }}
        
        if (charCounter == soughtStringWindow->width)  {  intRegister = matchStart+1;  return;   }
    }}
    
    if (mode == 0)  intRegister = numMatches;
    else  intRegister = 0;     // if we were searching, rather than counting, then if we made it this far we found nothing
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
callq 0x19254
movl %eax, %r13d
leal -0x5(%r13), %eax
cmpl $-0x4, %eax
ja 0x18ba2
leaq 0xcbe1(%rip), %rax      # 0x25760
movq 0xb8(%rax), %rsi
addq $-0x4, %rsi
movl $0x2d, %edi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xcfa3
movl $0x1, %edi
callq 0x1943c
leaq 0xcbad(%rip), %rbp      # 0x25760
cmpl $0x0, 0x18(%rbp)
jne 0x18c5c
movq %rax, %r15
movl $0x2, %edi
callq 0x1943c
cmpl $0x0, 0x18(%rbp)
jne 0x18c5c
movq %rax, %rbx
movq 0x10(%r15), %r12
movq 0x10(%rax), %r14
movl $0x1, %eax
cmpl $0x3, %r13d
jae 0x18bf1
movl $0x1, %ecx
jmp 0x18c56
movsd 0x318f(%rip), %xmm0     # 0x1bd88
movsd 0x2407(%rip), %xmm1     # 0x1b008
movl $0x3, %edi
callq 0x1930e
cvttsd2si %xmm0, %ecx
cmpl $0x3, %r13d
jne 0x18c2a
cmpl $-0x1, %ecx
movl $0x1, %eax
jne 0x18c56
movl 0x1c(%r15), %eax
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
jmp 0x18c56
movl 0x1c(%r15), %eax
subl 0x1c(%rbx), %eax
incl %eax
xorps %xmm1, %xmm1
cvtsi2sd %eax, %xmm1
movsd 0x23c6(%rip), %xmm0     # 0x1b008
movl $0x4, %edi
movl %ecx, %r13d
callq 0x1930e
movl %r13d, %ecx
cvttsd2si %xmm0, %eax
cmpl $0x0, 0x18(%rbp)
je 0x18c6b
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %eax, 0x4(%rsp)
movl %ecx, %r13d
addq $0x10, %r12
movq %r12, %rdi
callq 0x8c00
testl %eax, %eax
jne 0x18c92
addq $0x10, %r14
movq %r14, %rdi
callq 0x8c00
testl %eax, %eax
je 0x18ca7
movq 0xb8(%rbp), %rsi
addq $-0x4, %rsi
movl $0x1, %edi
jmp 0x18b8f
cmpl $0x0, 0x1c(%r15)
je 0x18d55
cmpl $0x0, 0x1c(%rbx)
je 0x18d61
movl 0x18(%rbx), %esi
incl %esi
movq %r14, %rdi
callq 0x91d8
movq %rax, %r14
movl 0x18(%r15), %esi
incl %esi
movq %r12, %rdi
callq 0x91d8
movl %r13d, %r10d
testl %r13d, %r13d
js 0x18d74
movl 0x4(%rsp), %r8d
decl %r8d
movslq 0x1c(%r15), %rdx
movslq 0x1c(%rbx), %rsi
subq %rsi, %rdx
xorl %ecx, %ecx
cmpl %edx, %r8d
jg 0x18d4b
movl %esi, %edi
movslq %r8d, %rsi
addq %rsi, %rax
xorl %ecx, %ecx
movl $0x0, %r8d
testl %edi, %edi
jle 0x18d2b
xorl %r8d, %r8d
movb (%rax,%r8), %r9b
cmpb (%r14,%r8), %r9b
jne 0x18d2b
incq %r8
cmpq %r8, %rdi
jne 0x18d17
jmp 0x18d30
cmpl %edi, %r8d
jne 0x18d3c
cmpl $0x1, %r10d
je 0x18dbb
incl %ecx
leaq 0x1(%rsi), %r8
incq %rax
cmpq %rdx, %rsi
movq %r8, %rsi
jl 0x18d0a
xorl %eax, %eax
testl %r10d, %r10d
cmovel %ecx, %eax
jmp 0x18d6c
movl $0x0, 0x6c(%rbp)
jmp 0x18c5c
testl %r13d, %r13d
movl 0x4(%rsp), %eax
cmovel %r13d, %eax
movl %eax, 0x6c(%rbp)
jmp 0x18c5c
movslq 0x4(%rsp), %r8
addq %r8, %rax
decq %rax
xorl %ecx, %ecx
testq %r8, %r8
jle 0x18d4b
movq %r8, %rdx
movslq 0x1c(%rbx), %rsi
xorl %edi, %edi
testq %rsi, %rsi
jle 0x18da8
movb (%rax,%rdi), %r8b
cmpb (%r14,%rdi), %r8b
jne 0x18da8
incq %rdi
cmpq %rdi, %rsi
jne 0x18d94
jmp 0x18db3
leaq -0x1(%rdx), %r8
decq %rax
cmpl %esi, %edi
jne 0x18d81
movl %edx, 0x6c(%rbp)
jmp 0x18c5c
incl %esi
movl %esi, 0x6c(%rbp)
jmp 0x18c5c