mirror of
https://github.com/matrix-construct/construct
synced 2024-12-25 23:14:13 +01:00
ircd::simd: Consolidate sum_ templates into lateral template template.
This commit is contained in:
parent
6577365d40
commit
82308ee4b3
7 changed files with 263 additions and 630 deletions
256
include/ircd/simd/lateral.h
Normal file
256
include/ircd/simd/lateral.h
Normal file
|
@ -0,0 +1,256 @@
|
|||
// The Construct
|
||||
//
|
||||
// Copyright (C) The Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2020 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_LATERAL_H
|
||||
|
||||
namespace ircd::simd
|
||||
{
|
||||
/// Perform a horizontal operation among lanes. The operation is specified
|
||||
/// by the caller who supplies a functor template like `std::bit_or` or
|
||||
/// `std::plus` etc. The result resides in lane[0] of the return vector
|
||||
/// while all other lanes of the return vector are undefined/junk as far
|
||||
/// as the caller is concerned.
|
||||
///
|
||||
/// This operation is intended to "reduce" or "collapse" a vector to a
|
||||
/// scalar value generally to make some control transfer etc. It does not
|
||||
/// necessitate a scalar result so it can be integrated into a sequence of
|
||||
/// vector operations without loss of purity. But of course, this operation
|
||||
/// is not efficient (crossing lanes never really is) and this template
|
||||
/// will output some log2 number of instructions. Using larger lane widths
|
||||
/// (i.e u64 rather than u8) can decrease the number of operations.
|
||||
///
|
||||
template<template<class>
|
||||
class op,
|
||||
class T>
|
||||
T lateral(T) noexcept = delete;
|
||||
|
||||
template<template<class> class op> u8x16 lateral(u8x16) noexcept;
|
||||
template<template<class> class op> u8x32 lateral(u8x32) noexcept;
|
||||
template<template<class> class op> u8x64 lateral(u8x64) noexcept;
|
||||
|
||||
template<template<class> class op> u16x8 lateral(u16x8) noexcept;
|
||||
template<template<class> class op> u16x16 lateral(u16x16) noexcept;
|
||||
template<template<class> class op> u16x32 lateral(u16x32) noexcept;
|
||||
|
||||
template<template<class> class op> u32x4 lateral(u32x4) noexcept;
|
||||
template<template<class> class op> u32x8 lateral(u32x8) noexcept;
|
||||
template<template<class> class op> u32x16 lateral(u32x16) noexcept;
|
||||
|
||||
template<template<class> class op> u64x2 lateral(u64x2) noexcept;
|
||||
template<template<class> class op> u64x4 lateral(u64x4) noexcept;
|
||||
template<template<class> class op> u64x8 lateral(u64x8) noexcept;
|
||||
}
|
||||
|
||||
template<template<class>
|
||||
class op>
|
||||
inline ircd::u64x8
|
||||
ircd::simd::lateral(u64x8 a)
|
||||
noexcept
|
||||
{
|
||||
u64x4 b, c;
|
||||
for(size_t i(0); i < 4; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 4];
|
||||
|
||||
b = op{}(b, c);
|
||||
b = lateral<op>(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<template<class>
|
||||
class op>
|
||||
inline ircd::u64x4
|
||||
ircd::simd::lateral(u64x4 a)
|
||||
noexcept
|
||||
{
|
||||
u64x2 b, c;
|
||||
for(size_t i(0); i < 2; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 2];
|
||||
|
||||
b = op{}(b, c);
|
||||
b = lateral<op>(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<template<class>
|
||||
class op>
|
||||
inline ircd::u64x2
|
||||
ircd::simd::lateral(u64x2 a)
|
||||
noexcept
|
||||
{
|
||||
const u64x2 b
|
||||
{
|
||||
a[1], a[0]
|
||||
};
|
||||
|
||||
a = op{}(a, b);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<template<class>
|
||||
class op>
|
||||
inline ircd::u32x16
|
||||
ircd::simd::lateral(u32x16 a)
|
||||
noexcept
|
||||
{
|
||||
u32x8 b, c;
|
||||
for(size_t i(0); i < 8; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 8];
|
||||
|
||||
b = op{}(b, c);
|
||||
b = lateral<op>(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<template<class>
|
||||
class op>
|
||||
inline ircd::u32x8
|
||||
ircd::simd::lateral(u32x8 a)
|
||||
noexcept
|
||||
{
|
||||
u32x4 b, c;
|
||||
for(size_t i(0); i < 4; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 4];
|
||||
|
||||
b = op{}(b, c);
|
||||
b = lateral<op>(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<template<class>
|
||||
class op>
|
||||
inline ircd::u32x4
|
||||
ircd::simd::lateral(u32x4 a)
|
||||
noexcept
|
||||
{
|
||||
u32x4 b
|
||||
{
|
||||
a[2], a[3], 0, 0,
|
||||
};
|
||||
|
||||
a = op{}(a, b);
|
||||
b[0] = a[1];
|
||||
a = op{}(a, b);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<template<class>
|
||||
class op>
|
||||
inline ircd::u16x32
|
||||
ircd::simd::lateral(u16x32 a)
|
||||
noexcept
|
||||
{
|
||||
u16x16 b, c;
|
||||
for(size_t i(0); i < 16; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 16];
|
||||
|
||||
b = op{}(b, c);
|
||||
b = lateral<op>(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<template<class>
|
||||
class op>
|
||||
inline ircd::u16x16
|
||||
ircd::simd::lateral(u16x16 a)
|
||||
noexcept
|
||||
{
|
||||
u16x8 b, c;
|
||||
for(size_t i(0); i < 8; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 8];
|
||||
|
||||
b = op{}(b, c);
|
||||
b = lateral<op>(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<template<class>
|
||||
class op>
|
||||
inline ircd::u16x8
|
||||
ircd::simd::lateral(u16x8 a)
|
||||
noexcept
|
||||
{
|
||||
u16x8 b
|
||||
{
|
||||
a[4], a[5], a[6], a[7]
|
||||
};
|
||||
|
||||
a = op{}(a, b);
|
||||
b[0] = a[2];
|
||||
b[1] = a[3];
|
||||
a = op{}(a, b);
|
||||
b[0] = a[1];
|
||||
a = op{}(a, b);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<template<class>
|
||||
class op>
|
||||
inline ircd::u8x64
|
||||
ircd::simd::lateral(u8x64 a)
|
||||
noexcept
|
||||
{
|
||||
u8x32 b, c;
|
||||
for(size_t i(0); i < 32; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 32];
|
||||
|
||||
b = op{}(b, c);
|
||||
b = lateral<op>(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<template<class>
|
||||
class op>
|
||||
inline ircd::u8x32
|
||||
ircd::simd::lateral(u8x32 a)
|
||||
noexcept
|
||||
{
|
||||
u8x16 b, c;
|
||||
for(size_t i(0); i < 16; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 16];
|
||||
|
||||
b = op{}(b, c);
|
||||
b = lateral<op>(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<template<class>
|
||||
class op>
|
||||
inline ircd::u8x16
|
||||
ircd::simd::lateral(u8x16 a)
|
||||
noexcept
|
||||
{
|
||||
u8x16 b
|
||||
{
|
||||
a[0x8], a[0x9], a[0xa], a[0xb], a[0xc], a[0xd], a[0xe], a[0xf],
|
||||
};
|
||||
|
||||
a = op{}(a, b);
|
||||
b = u8x16
|
||||
{
|
||||
a[0x4], a[0x5], a[0x6], a[0x7],
|
||||
};
|
||||
|
||||
a = op{}(a, b);
|
||||
b[0x0] = a[0x2];
|
||||
b[0x1] = a[0x3];
|
||||
a = op{}(a, b);
|
||||
b[0x0] = a[0x1];
|
||||
a = op{}(a, b);
|
||||
return a;
|
||||
}
|
|
@ -23,9 +23,7 @@
|
|||
#include "popcnt.h"
|
||||
#include "lzcnt.h"
|
||||
#include "tzcnt.h"
|
||||
#include "sum_or.h"
|
||||
#include "sum_and.h"
|
||||
#include "sum_add.h"
|
||||
#include "lateral.h"
|
||||
#include "print.h"
|
||||
|
||||
namespace ircd
|
||||
|
@ -41,4 +39,6 @@ namespace ircd
|
|||
using simd::popcnt;
|
||||
using simd::popmask;
|
||||
using simd::boolmask;
|
||||
|
||||
using simd::lateral;
|
||||
}
|
||||
|
|
|
@ -1,227 +0,0 @@
|
|||
// The Construct
|
||||
//
|
||||
// Copyright (C) The Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2020 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_SUM_ADD_H
|
||||
|
||||
namespace ircd::simd
|
||||
{
|
||||
template<class T> T sum_add(T) noexcept = delete;
|
||||
|
||||
template<> u8x16 sum_add(u8x16) noexcept;
|
||||
template<> u8x32 sum_add(u8x32) noexcept;
|
||||
template<> u8x64 sum_add(u8x64) noexcept;
|
||||
|
||||
template<> u16x8 sum_add(u16x8) noexcept;
|
||||
template<> u16x16 sum_add(u16x16) noexcept;
|
||||
template<> u16x32 sum_add(u16x32) noexcept;
|
||||
|
||||
template<> u32x4 sum_add(u32x4) noexcept;
|
||||
template<> u32x8 sum_add(u32x8) noexcept;
|
||||
template<> u32x16 sum_add(u32x16) noexcept;
|
||||
|
||||
template<> u64x2 sum_add(u64x2) noexcept;
|
||||
template<> u64x4 sum_add(u64x4) noexcept;
|
||||
template<> u64x8 sum_add(u64x8) noexcept;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u64x8
|
||||
ircd::simd::sum_add(u64x8 a)
|
||||
noexcept
|
||||
{
|
||||
u64x4 b, c;
|
||||
for(size_t i(0); i < 4; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 4];
|
||||
|
||||
b += c;
|
||||
b = sum_add(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u64x4
|
||||
ircd::simd::sum_add(u64x4 a)
|
||||
noexcept
|
||||
{
|
||||
u64x2 b, c;
|
||||
for(size_t i(0); i < 2; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 2];
|
||||
|
||||
b += c;
|
||||
b = sum_add(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u64x2
|
||||
ircd::simd::sum_add(u64x2 a)
|
||||
noexcept
|
||||
{
|
||||
const u64x2 b
|
||||
{
|
||||
a[1], a[0]
|
||||
};
|
||||
|
||||
a += b;
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u32x16
|
||||
ircd::simd::sum_add(u32x16 a)
|
||||
noexcept
|
||||
{
|
||||
u32x8 b, c;
|
||||
for(size_t i(0); i < 8; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 8];
|
||||
|
||||
b += c;
|
||||
b = sum_add(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u32x8
|
||||
ircd::simd::sum_add(u32x8 a)
|
||||
noexcept
|
||||
{
|
||||
u32x4 b, c;
|
||||
for(size_t i(0); i < 4; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 4];
|
||||
|
||||
b += c;
|
||||
b = sum_add(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u32x4
|
||||
ircd::simd::sum_add(u32x4 a)
|
||||
noexcept
|
||||
{
|
||||
u32x4 b
|
||||
{
|
||||
a[2], a[3], 0, 0,
|
||||
};
|
||||
|
||||
a = a + b;
|
||||
b[0] = a[1];
|
||||
a = a + b;
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u16x32
|
||||
ircd::simd::sum_add(u16x32 a)
|
||||
noexcept
|
||||
{
|
||||
u16x16 b, c;
|
||||
for(size_t i(0); i < 16; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 16];
|
||||
|
||||
b += c;
|
||||
b = sum_add(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u16x16
|
||||
ircd::simd::sum_add(u16x16 a)
|
||||
noexcept
|
||||
{
|
||||
u16x8 b, c;
|
||||
for(size_t i(0); i < 8; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 8];
|
||||
|
||||
b += c;
|
||||
b = sum_add(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u16x8
|
||||
ircd::simd::sum_add(u16x8 a)
|
||||
noexcept
|
||||
{
|
||||
u16x8 b
|
||||
{
|
||||
a[4], a[5], a[6], a[7]
|
||||
};
|
||||
|
||||
a = a + b;
|
||||
b[0] = a[2];
|
||||
b[1] = a[3];
|
||||
a = a + b;
|
||||
b[0] = a[1];
|
||||
a = a + b;
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u8x64
|
||||
ircd::simd::sum_add(u8x64 a)
|
||||
noexcept
|
||||
{
|
||||
u8x32 b, c;
|
||||
for(size_t i(0); i < 32; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 32];
|
||||
|
||||
b += c;
|
||||
b = sum_add(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u8x32
|
||||
ircd::simd::sum_add(u8x32 a)
|
||||
noexcept
|
||||
{
|
||||
u8x16 b, c;
|
||||
for(size_t i(0); i < 16; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 16];
|
||||
|
||||
b += c;
|
||||
b = sum_add(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u8x16
|
||||
ircd::simd::sum_add(u8x16 a)
|
||||
noexcept
|
||||
{
|
||||
u8x16 b
|
||||
{
|
||||
a[0x8], a[0x9], a[0xa], a[0xb], a[0xc], a[0xd], a[0xe], a[0xf],
|
||||
};
|
||||
|
||||
a = a + b;
|
||||
b = u8x16
|
||||
{
|
||||
a[0x4], a[0x5], a[0x6], a[0x7],
|
||||
};
|
||||
|
||||
a = a + b;
|
||||
b[0x0] = a[0x2];
|
||||
b[0x1] = a[0x3];
|
||||
a = a + b;
|
||||
b[0x0] = a[0x1];
|
||||
a = a + b;
|
||||
return a;
|
||||
}
|
|
@ -1,198 +0,0 @@
|
|||
// The Construct
|
||||
//
|
||||
// Copyright (C) The Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2020 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_SUM_AND_H
|
||||
|
||||
namespace ircd::simd
|
||||
{
|
||||
template<class T> T sum_and(T) noexcept = delete;
|
||||
|
||||
template<> u64x2 sum_and(u64x2) noexcept;
|
||||
template<> u64x4 sum_and(u64x4) noexcept;
|
||||
template<> u64x8 sum_and(u64x8) noexcept;
|
||||
|
||||
template<> u16x8 sum_and(u16x8) noexcept;
|
||||
template<> u16x16 sum_and(u16x16) noexcept;
|
||||
template<> u16x32 sum_and(u16x32) noexcept;
|
||||
|
||||
template<> u32x4 sum_and(u32x4) noexcept;
|
||||
template<> u32x8 sum_and(u32x8) noexcept;
|
||||
template<> u32x16 sum_and(u32x16) noexcept;
|
||||
|
||||
template<> u8x16 sum_and(u8x16) noexcept;
|
||||
template<> u8x32 sum_and(u8x32) noexcept;
|
||||
template<> u8x64 sum_and(u8x64) noexcept;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u8x64
|
||||
ircd::simd::sum_and(u8x64 a)
|
||||
noexcept
|
||||
{
|
||||
u8x32 b, c;
|
||||
for(size_t i(0); i < 32; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 32];
|
||||
|
||||
b &= c;
|
||||
b = sum_and(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u8x32
|
||||
ircd::simd::sum_and(u8x32 a)
|
||||
noexcept
|
||||
{
|
||||
u8x16 b, c;
|
||||
for(size_t i(0); i < 16; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 16];
|
||||
|
||||
b &= c;
|
||||
b = sum_and(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u8x16
|
||||
ircd::simd::sum_and(u8x16 a)
|
||||
noexcept
|
||||
{
|
||||
a &= shr<64>(a);
|
||||
a &= shr<32>(a);
|
||||
a &= shr<16>(a);
|
||||
a &= shr<8>(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u16x32
|
||||
ircd::simd::sum_and(u16x32 a)
|
||||
noexcept
|
||||
{
|
||||
u16x16 b, c;
|
||||
for(size_t i(0); i < 16; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 16];
|
||||
|
||||
b &= c;
|
||||
b = sum_and(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u16x16
|
||||
ircd::simd::sum_and(u16x16 a)
|
||||
noexcept
|
||||
{
|
||||
u16x8 b, c;
|
||||
for(size_t i(0); i < 8; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 8];
|
||||
|
||||
b &= c;
|
||||
b = sum_and(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u16x8
|
||||
ircd::simd::sum_and(u16x8 a)
|
||||
noexcept
|
||||
{
|
||||
u32x4 b(a);
|
||||
b = sum_and(b);
|
||||
a[0] &= u16x8(b)[1];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u32x16
|
||||
ircd::simd::sum_and(u32x16 a)
|
||||
noexcept
|
||||
{
|
||||
u32x8 b, c;
|
||||
for(size_t i(0); i < 8; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 8];
|
||||
|
||||
b &= c;
|
||||
b = sum_and(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u32x8
|
||||
ircd::simd::sum_and(u32x8 a)
|
||||
noexcept
|
||||
{
|
||||
u32x4 b, c;
|
||||
for(size_t i(0); i < 4; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 4];
|
||||
|
||||
b &= c;
|
||||
b = sum_and(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u32x4
|
||||
ircd::simd::sum_and(u32x4 a)
|
||||
noexcept
|
||||
{
|
||||
u64x2 b(a);
|
||||
b = sum_and(b);
|
||||
a[0] &= u32x4(b)[1];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u64x8
|
||||
ircd::simd::sum_and(u64x8 a)
|
||||
noexcept
|
||||
{
|
||||
u64x4 b, c;
|
||||
for(size_t i(0); i < 4; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 4];
|
||||
|
||||
b &= c;
|
||||
b = sum_and(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u64x4
|
||||
ircd::simd::sum_and(u64x4 a)
|
||||
noexcept
|
||||
{
|
||||
u64x2 b, c;
|
||||
for(size_t i(0); i < 2; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 2];
|
||||
|
||||
b &= c;
|
||||
b = sum_and(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u64x2
|
||||
ircd::simd::sum_and(u64x2 a)
|
||||
noexcept
|
||||
{
|
||||
u128x1 b(a);
|
||||
b = shr<64>(b);
|
||||
a &= u64x2(b);
|
||||
return a;
|
||||
}
|
|
@ -1,198 +0,0 @@
|
|||
// The Construct
|
||||
//
|
||||
// Copyright (C) The Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2020 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_SUM_OR_H
|
||||
|
||||
namespace ircd::simd
|
||||
{
|
||||
template<class T> T sum_or(T) noexcept = delete;
|
||||
|
||||
template<> u64x2 sum_or(u64x2) noexcept;
|
||||
template<> u64x4 sum_or(u64x4) noexcept;
|
||||
template<> u64x8 sum_or(u64x8) noexcept;
|
||||
|
||||
template<> u16x8 sum_or(u16x8) noexcept;
|
||||
template<> u16x16 sum_or(u16x16) noexcept;
|
||||
template<> u16x32 sum_or(u16x32) noexcept;
|
||||
|
||||
template<> u32x4 sum_or(u32x4) noexcept;
|
||||
template<> u32x8 sum_or(u32x8) noexcept;
|
||||
template<> u32x16 sum_or(u32x16) noexcept;
|
||||
|
||||
template<> u8x16 sum_or(u8x16) noexcept;
|
||||
template<> u8x32 sum_or(u8x32) noexcept;
|
||||
template<> u8x64 sum_or(u8x64) noexcept;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u8x64
|
||||
ircd::simd::sum_or(u8x64 a)
|
||||
noexcept
|
||||
{
|
||||
u8x32 b, c;
|
||||
for(size_t i(0); i < 32; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 32];
|
||||
|
||||
b |= c;
|
||||
b = sum_or(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u8x32
|
||||
ircd::simd::sum_or(u8x32 a)
|
||||
noexcept
|
||||
{
|
||||
u8x16 b, c;
|
||||
for(size_t i(0); i < 16; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 16];
|
||||
|
||||
b |= c;
|
||||
b = sum_or(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u8x16
|
||||
ircd::simd::sum_or(u8x16 a)
|
||||
noexcept
|
||||
{
|
||||
a |= shr<64>(a);
|
||||
a |= shr<32>(a);
|
||||
a |= shr<16>(a);
|
||||
a |= shr<8>(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u16x32
|
||||
ircd::simd::sum_or(u16x32 a)
|
||||
noexcept
|
||||
{
|
||||
u16x16 b, c;
|
||||
for(size_t i(0); i < 16; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 16];
|
||||
|
||||
b |= c;
|
||||
b = sum_or(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u16x16
|
||||
ircd::simd::sum_or(u16x16 a)
|
||||
noexcept
|
||||
{
|
||||
u16x8 b, c;
|
||||
for(size_t i(0); i < 8; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 8];
|
||||
|
||||
b |= c;
|
||||
b = sum_or(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u16x8
|
||||
ircd::simd::sum_or(u16x8 a)
|
||||
noexcept
|
||||
{
|
||||
u32x4 b(a);
|
||||
b = sum_or(b);
|
||||
a[0] |= u16x8(b)[1];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u32x16
|
||||
ircd::simd::sum_or(u32x16 a)
|
||||
noexcept
|
||||
{
|
||||
u32x8 b, c;
|
||||
for(size_t i(0); i < 8; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 8];
|
||||
|
||||
b |= c;
|
||||
b = sum_or(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u32x8
|
||||
ircd::simd::sum_or(u32x8 a)
|
||||
noexcept
|
||||
{
|
||||
u32x4 b, c;
|
||||
for(size_t i(0); i < 4; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 4];
|
||||
|
||||
b |= c;
|
||||
b = sum_or(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u32x4
|
||||
ircd::simd::sum_or(u32x4 a)
|
||||
noexcept
|
||||
{
|
||||
u64x2 b(a);
|
||||
b = sum_or(b);
|
||||
a[0] |= u32x4(b)[1];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u64x8
|
||||
ircd::simd::sum_or(u64x8 a)
|
||||
noexcept
|
||||
{
|
||||
u64x4 b, c;
|
||||
for(size_t i(0); i < 4; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 4];
|
||||
|
||||
b |= c;
|
||||
b = sum_or(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u64x4
|
||||
ircd::simd::sum_or(u64x4 a)
|
||||
noexcept
|
||||
{
|
||||
u64x2 b, c;
|
||||
for(size_t i(0); i < 2; ++i)
|
||||
b[i] = a[i], c[i] = a[i + 2];
|
||||
|
||||
b |= c;
|
||||
b = sum_or(b);
|
||||
a[0] = b[0];
|
||||
return a;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ircd::u64x2
|
||||
ircd::simd::sum_or(u64x2 a)
|
||||
noexcept
|
||||
{
|
||||
u128x1 b(a);
|
||||
b = shr<64>(b);
|
||||
a |= u64x2(b);
|
||||
return a;
|
||||
}
|
|
@ -378,7 +378,7 @@ ircd::b64::decode(const mutable_buffer &out,
|
|||
err |= _err & i64x8(mask);
|
||||
}
|
||||
|
||||
if(unlikely(simd::sum_or(u64x8(err))[0]))
|
||||
if(unlikely(simd::lateral<std::bit_or>(u64x8(err))[0]))
|
||||
throw invalid_encoding
|
||||
{
|
||||
"base64 encoding contained invalid characters."
|
||||
|
|
|
@ -572,7 +572,7 @@ noexcept
|
|||
|
||||
const block_t is_regular
|
||||
{
|
||||
simd::sum_and(~is_special)
|
||||
simd::lateral<std::bit_and>(~is_special)
|
||||
};
|
||||
|
||||
if(likely(is_regular[0]))
|
||||
|
@ -3536,7 +3536,7 @@ ircd::json::string_stringify(u8x16 &block,
|
|||
|
||||
const u8x16 any_special
|
||||
{
|
||||
simd::sum_or(is_special | ~block_mask)
|
||||
simd::lateral<std::bit_or>(is_special | ~block_mask)
|
||||
};
|
||||
|
||||
// Fastest-path; backward branch to count and consume all of the input.
|
||||
|
@ -3797,7 +3797,7 @@ ircd::json::string_serialized(const u8x16 block,
|
|||
|
||||
const u8x16 any_special
|
||||
{
|
||||
simd::sum_or(is_special | ~block_mask)
|
||||
simd::lateral<std::bit_or>(is_special | ~block_mask)
|
||||
};
|
||||
|
||||
// Fastest-path; backward branch to count and consume all of the input.
|
||||
|
|
Loading…
Reference in a new issue