summaryrefslogblamecommitdiff
path: root/rgo/src/fndchr.c
blob: 12cd006227d8d963d5397a8a09eaf6d54c57e169 (plain) (tree)



































































                                                                                                                    
/*
	Copyright 2022 Gabriel Jensen.
	This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
	If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

#include <rgo-priv.h>

#if defined(rgo_priv_fastimpl)
__asm__ (
	".global rgo_fndchr\n"

	"rgo_fndchr:\n"
		/*
			char const * str
			char         chr
		*/
#if defined(sus_arch_amd64)
		/* rax: Address of the current character. */
		"movq %rdi,%rax\n"
		/* rdx: Current character. */
	".loop:\n"
		"movb (%rax),%dl\n"
		"cmpb %dl,%sil\n"
		"je .fnd\n" /* Exit loop if we have found the character. */
		"testb %dl,%dl\n"
		"je .nfnd\n" /* We encountered the null-terminator but not the specified character. */
		"incq %rax\n"
		"jmp .loop\n"
	".fnd:\n"
		"subq %rdi,%rax\n"
		"ret\n"
	".nfnd:\n"
		"movq $0xFFFFFFFFFFFFFFFF,%rax\n"
		"ret\n"
#elif defined(sus_arch_ia32)
		/* eax: Address of the current character. */
		"movl 0x4(%esp),%eax\n"
		/* ecx: Character. */
		"movb 0x8(%esp),%cl\n"
		/* edx: Current character. */
	".loop:\n"
		"movb (%eax),%dl\n"
		"cmpb %dl,%cl\n"
		"je .fnd\n" /* Exit loop if we have found the character. */
		"testb %dl,%dl\n"
		"je .nfnd\n" /* We encountered the null-terminator but not the specified character. */
		"incl %eax\n"
		"jmp .loop\n"
	".fnd:\n"
		"subl 0x4(%esp),%eax\n"
		"ret\n"
	".nfnd:\n"
		"movl $0xFFFFFFFF,%eax\n"
		"ret\n"
#endif
);
#else
sus_typ_usz rgo_fndchr(char const * const sus_restr _str,char const _chr) {
	char const * sus_restr pos = _str;
	for (;;++pos) {
		char const chr = *pos;
		sus_unlikely (chr == _chr)  {return (sus_typ_usz)(pos - _str);}
		sus_unlikely (chr == '\x0') {return sus_typlit_usz(-0x1);}
	}
	sus_unreach();
}
#endif