ircd::simd: Start character string tools suite; add strlen(); add strcat().

This commit is contained in:
Jason Volk 2021-02-24 11:27:37 -08:00
parent ee904d9b33
commit 394858ff91
3 changed files with 233 additions and 0 deletions

View File

@ -39,6 +39,7 @@
#include "generate.h"
#include "accumulate.h"
#include "tokens.h"
#include "str.h"
#include "print.h"
namespace ircd

163
include/ircd/simd/str.h Normal file
View File

@ -0,0 +1,163 @@
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2021 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
#pragma once
#define HAVE_IRCD_SIMD_STR_H
// String toolset.
//
// Whole vectors are in play at a time, with null termination allowing for
// string ops at character granularity. A few basic rules:
//
// - Strings are laid onto vectors with character elements; the templates
// accept c8/i8/u8 in combination with vector sizes of 16, 32 and 64. This
// is not always addressable memory, so this is a value-oriented interface
// and uses no character pointers; only pointers to vectors (whole strings).
//
// - Strings are null terminated iff there is room for a null character. If
// a vector does not contain a null character the string's length is the
// vector size itself. It is up to the caller (or a derived interface) to
// compose long strings out of unterminated blocks.
//
// - Null termination *must* be padded out to the end of the vector. This is
// important for performance. Unless otherwise noted there is one string on
// a vector at a time and the first character is lane[0]
//
namespace ircd::simd
{
template<class T>
typename std::enable_if<simd::sizeof_lane<T>() == 1, u8>::type
strlen(const T) noexcept;
template<class T>
typename std::enable_if<simd::sizeof_lane<T>() == 1, bool>::type
streq(const T, const T) noexcept;
template<class T>
typename std::enable_if<simd::sizeof_lane<T>() == 1, T &>::type
strcpy(T &, const T) noexcept;
template<class T>
typename std::enable_if<simd::sizeof_lane<T>() == 1, T &>::type
strcpy(T &, const const_buffer &) noexcept;
template<class T>
typename std::enable_if<simd::sizeof_lane<T>() == 1, T &>::type
strcat(T &, const T) noexcept;
}
template<class T>
inline typename std::enable_if<ircd::simd::sizeof_lane<T>() == 1, T &>::type
ircd::simd::strcat(T &a,
const T b)
noexcept
{
static_assert
(
sizeof_lane<T>() == 1,
"internal template; for 8-bit character basis only"
);
size_t j{0}, i
{
strlen(a)
};
while(b[j] && i < lanes<T>())
a[i++] = b[j++];
while(i < lanes<T>())
a[i++] = 0;
return a;
}
template<class T>
inline typename std::enable_if<ircd::simd::sizeof_lane<T>() == 1, T &>::type
ircd::simd::strcpy(T &a,
const const_buffer &b)
noexcept
{
static_assert
(
sizeof_lane<T>() == 1,
"internal template; for 8-bit character basis only"
);
size_t i{0};
for(; i < lanes<T>() && i < size(b); ++i)
a[i] = b[i];
while(i < lanes<T>())
a[i++] = 0;
return a;
}
template<class T>
inline typename std::enable_if<ircd::simd::sizeof_lane<T>() == 1, T &>::type
ircd::simd::strcpy(T &a,
const T b)
noexcept
{
static_assert
(
sizeof_lane<T>() == 1,
"internal template; for 8-bit character basis only"
);
size_t i{0};
for(; b[i] && i < lanes<T>(); ++i)
a[i] = b[i];
while(i < lanes<T>())
a[i++] = 0;
return a;
}
template<class T>
inline typename std::enable_if<ircd::simd::sizeof_lane<T>() == 1, bool>::type
ircd::simd::streq(const T a,
const T b)
noexcept
{
static_assert
(
sizeof_lane<T>() == 1,
"internal template; for 8-bit character basis only"
);
const auto equal
{
a == b
};
return all<T>(equal);
}
template<class T>
inline typename std::enable_if<ircd::simd::sizeof_lane<T>() == 1, ircd::u8>::type
ircd::simd::strlen(const T str)
noexcept
{
static_assert
(
sizeof_lane<T>() == 1,
"internal template; for 8-bit character basis only"
);
u8 ret(0);
for(; ret < lanes<T>(); ++ret)
if(!str[ret])
break;
return ret;
}

View File

@ -0,0 +1,69 @@
// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2021 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
#pragma once
#define HAVE_IRCD_SIMD_STRCAT_H
namespace ircd::simd
{
template<class T>
T &_strcat(T &, const T) noexcept;
u8x16 &strcat(u8x16 &, const u8x16) noexcept;
u8x32 &strcat(u8x32 &, const u8x32) noexcept;
u8x64 &strcat(u8x64 &, const u8x64) noexcept;
}
inline ircd::simd::u8x64 &
ircd::simd::strcat(u8x64 &a,
const u8x64 b)
noexcept
{
return _strcat(a, b);
}
inline ircd::simd::u8x32 &
ircd::simd::strcat(u8x32 &a,
const u8x32 b)
noexcept
{
return _strcat(a, b);
}
inline ircd::simd::u8x16 &
ircd::simd::strcat(u8x16 &a,
const u8x16 b)
noexcept
{
return _strcat(a, b);
}
template<class T>
inline T &
ircd::simd::_strcat(T &a,
const T b)
noexcept
{
static_assert
(
sizeof_lane<T>() == 1,
"internal template; for 8-bit character basis only"
);
size_t j{0}, i
{
strlen(a)
};
while(b[j] && i < lanes<T>())
a[i++] = b[j++];
return a;
}