Skip to content
Snippets Groups Projects
Commit d04d4da6 authored by Bine Brank's avatar Bine Brank
Browse files

bitwise ops

parent 6aa8e7d5
Branches
Tags v0.4
No related merge requests found
def Settings( **kwargs ):
return {
'flags': [ '-x', 'c++', '-march=armv8-a_sve', 'O3', '-Wall', '-Wextra', '-Werror'],
}
...@@ -12,6 +12,7 @@ HEADERS = simd.hpp \ ...@@ -12,6 +12,7 @@ HEADERS = simd.hpp \
matrix_type.hpp matrix_overloading.hpp \ matrix_type.hpp matrix_overloading.hpp \
arithmetics/generic/generic_vector_ops.hpp arithmetics/generic/generic.hpp arithmetics/generic/generic_matrix_ops.hpp \ arithmetics/generic/generic_vector_ops.hpp arithmetics/generic/generic.hpp arithmetics/generic/generic_matrix_ops.hpp \
arithmetics/sve/sve_vector_ops.hpp backend/sve/sve_backend.hpp arithmetics/sve/sve.hpp arithmetics/sve/sve_matrix_ops.hpp \ arithmetics/sve/sve_vector_ops.hpp backend/sve/sve_backend.hpp arithmetics/sve/sve.hpp arithmetics/sve/sve_matrix_ops.hpp \
backend/sve/sve_complex_double.hpp backend/sve/sve_complex_float.hpp backend/sve/sve_double.hpp backend/sve/sve_float.hpp \
loadstore/sve/sve_load.hpp loadstore/sve/sve_load.hpp
all: ${TARGET} all: ${TARGET}
......
...@@ -94,6 +94,13 @@ struct svetype<complex<double>>{ ...@@ -94,6 +94,13 @@ struct svetype<complex<double>>{
return {re, im}; return {re, im};
} }
static inline vec and_z(svbool_t pg, vec op1, vec op2)
{
svuint64_t re = svand_z(pg, svreinterpret_u64(op1.v0), svreinterpret_u64(op2.v0));
svuint64_t im = svand_z(pg, svreinterpret_u64(op1.v1), svreinterpret_u64(op2.v1));
return {svreinterpret_f64(re), svreinterpret_f64(im)};
}
static inline vec orr_z(svbool_t pg, vec op1, vec op2) static inline vec orr_z(svbool_t pg, vec op1, vec op2)
{ {
svuint64_t re = svorr_z(pg, svreinterpret_u64(op1.v0), svreinterpret_u64(op2.v0)); svuint64_t re = svorr_z(pg, svreinterpret_u64(op1.v0), svreinterpret_u64(op2.v0));
...@@ -101,6 +108,20 @@ struct svetype<complex<double>>{ ...@@ -101,6 +108,20 @@ struct svetype<complex<double>>{
return {svreinterpret_f64(re), svreinterpret_f64(im)}; return {svreinterpret_f64(re), svreinterpret_f64(im)};
} }
static inline vec eor_z(svbool_t pg, vec op1, vec op2)
{
svuint64_t re = sveor_z(pg, svreinterpret_u64(op1.v0), svreinterpret_u64(op2.v0));
svuint64_t im = sveor_z(pg, svreinterpret_u64(op1.v1), svreinterpret_u64(op2.v1));
return {svreinterpret_f64(re), svreinterpret_f64(im)};
}
static inline vec not_z(svbool_t pg, vec op1, vec op2)
{
svuint64_t re = svnot_z(pg, svreinterpret_u64(op1.v0), svreinterpret_u64(op2.v0));
svuint64_t im = svnot_z(pg, svreinterpret_u64(op1.v1), svreinterpret_u64(op2.v1));
return {svreinterpret_f64(re), svreinterpret_f64(im)};
}
// vector vector operations // vector vector operations
static inline vec add_z(svbool_t pg, vec op1, vec op2) static inline vec add_z(svbool_t pg, vec op1, vec op2)
{ {
......
...@@ -94,6 +94,13 @@ struct svetype<complex<float>>{ ...@@ -94,6 +94,13 @@ struct svetype<complex<float>>{
return {re, im}; return {re, im};
} }
static inline vec and_z(svbool_t pg, vec op1, vec op2)
{
svuint32_t re = svand_z(pg, svreinterpret_u32(op1.v0), svreinterpret_u32(op2.v0));
svuint32_t im = svand_z(pg, svreinterpret_u32(op1.v1), svreinterpret_u32(op2.v1));
return {svreinterpret_f32(re), svreinterpret_f32(im)};
}
static inline vec orr_z(svbool_t pg, vec op1, vec op2) static inline vec orr_z(svbool_t pg, vec op1, vec op2)
{ {
svuint32_t re = svorr_z(pg, svreinterpret_u32(op1.v0), svreinterpret_u32(op2.v0)); svuint32_t re = svorr_z(pg, svreinterpret_u32(op1.v0), svreinterpret_u32(op2.v0));
...@@ -101,6 +108,20 @@ struct svetype<complex<float>>{ ...@@ -101,6 +108,20 @@ struct svetype<complex<float>>{
return {svreinterpret_f32(re), svreinterpret_f32(im)}; return {svreinterpret_f32(re), svreinterpret_f32(im)};
} }
static inline vec eor_z(svbool_t pg, vec op1, vec op2)
{
svuint32_t re = sveor_z(pg, svreinterpret_u32(op1.v0), svreinterpret_u32(op2.v0));
svuint32_t im = sveor_z(pg, svreinterpret_u32(op1.v1), svreinterpret_u32(op2.v1));
return {svreinterpret_f32(re), svreinterpret_f32(im)};
}
static inline vec not_z(svbool_t pg, vec op1, vec op2)
{
svuint32_t re = svnot_z(pg, svreinterpret_u32(op1.v0), svreinterpret_u32(op2.v0));
svuint32_t im = svnot_z(pg, svreinterpret_u32(op1.v1), svreinterpret_u32(op2.v1));
return {svreinterpret_f32(re), svreinterpret_f32(im)};
}
// vector vector operations // vector vector operations
static inline vec add_z(svbool_t pg, vec op1, vec op2) static inline vec add_z(svbool_t pg, vec op1, vec op2)
{ {
......
...@@ -78,9 +78,18 @@ struct svetype<double>{ ...@@ -78,9 +78,18 @@ struct svetype<double>{
static inline vec conj_z(svbool_t pg, vec op1) static inline vec conj_z(svbool_t pg, vec op1)
{ return op1; } { return op1; }
static inline vec and_z(svbool_t pg, vec op1, vec op2)
{ return svreinterpret_f64(svand_z(pg, svreinterpret_u64(op1), svreinterpret_u64(op2))); }
static inline vec orr_z(svbool_t pg, vec op1, vec op2) static inline vec orr_z(svbool_t pg, vec op1, vec op2)
{ return svreinterpret_f64(svorr_z(pg, svreinterpret_u64(op1), svreinterpret_u64(op2))); } { return svreinterpret_f64(svorr_z(pg, svreinterpret_u64(op1), svreinterpret_u64(op2))); }
static inline vec eor_z(svbool_t pg, vec op1, vec op2)
{ return svreinterpret_f64(sveor_z(pg, svreinterpret_u64(op1), svreinterpret_u64(op2))); }
static inline vec not_z(svbool_t pg, vec op1, vec op2)
{ return svreinterpret_f64(svnot_z(pg, svreinterpret_u64(op1), svreinterpret_u64(op2))); }
// vector vector operations // vector vector operations
static inline vec add_z(svbool_t pg, vec op1, vec op2) static inline vec add_z(svbool_t pg, vec op1, vec op2)
{ return svadd_f64_z(pg, op1, op2); } { return svadd_f64_z(pg, op1, op2); }
......
...@@ -79,9 +79,18 @@ struct svetype<float>{ ...@@ -79,9 +79,18 @@ struct svetype<float>{
static inline vec conj_z(svbool_t pg, vec op1) static inline vec conj_z(svbool_t pg, vec op1)
{ return op1; } { return op1; }
static inline vec and_z(svbool_t pg, vec op1, vec op2)
{ return svreinterpret_f32(svand_z(pg, svreinterpret_u32(op1), svreinterpret_u32(op2))); }
static inline vec orr_z(svbool_t pg, vec op1, vec op2) static inline vec orr_z(svbool_t pg, vec op1, vec op2)
{ return svreinterpret_f32(svorr_z(pg, svreinterpret_u32(op1), svreinterpret_u32(op2))); } { return svreinterpret_f32(svorr_z(pg, svreinterpret_u32(op1), svreinterpret_u32(op2))); }
static inline vec eor_z(svbool_t pg, vec op1, vec op2)
{ return svreinterpret_f32(sveor_z(pg, svreinterpret_u32(op1), svreinterpret_u32(op2))); }
static inline vec not_z(svbool_t pg, vec op1, vec op2)
{ return svreinterpret_f32(svnot_z(pg, svreinterpret_u32(op1), svreinterpret_u32(op2))); }
// vector vector operations // vector vector operations
static inline vec add_z(svbool_t pg, vec op1, vec op2) static inline vec add_z(svbool_t pg, vec op1, vec op2)
{ return svadd_f32_z(pg, op1, op2); } { return svadd_f32_z(pg, op1, op2); }
......
...@@ -76,9 +76,18 @@ struct svetype<int>{ ...@@ -76,9 +76,18 @@ struct svetype<int>{
static inline vec mulscal_z(svbool_t pg, vec op1, scal op2) static inline vec mulscal_z(svbool_t pg, vec op1, scal op2)
{ return svmul_n_s32_z(pg, op1, op2); } { return svmul_n_s32_z(pg, op1, op2); }
static inline vec and_z(svbool_t pg, vec op1, vec op2)
{ return svand_z(pg, op1, op2); }
static inline vec orr_z(svbool_t pg, vec op1, vec op2) static inline vec orr_z(svbool_t pg, vec op1, vec op2)
{ return svorr_z(pg, op1, op2); } { return svorr_z(pg, op1, op2); }
static inline vec eor_z(svbool_t pg, vec op1, vec op2)
{ return sveor_z(pg, op1, op2); }
static inline vec not_z(svbool_t pg, vec op1, vec op2)
{ return svnot_z(pg, op1, op2); }
// vector vector operations // vector vector operations
static inline vec add_z(svbool_t pg, vec op1, vec op2) static inline vec add_z(svbool_t pg, vec op1, vec op2)
{ return svadd_s32_z(pg, op1, op2); } { return svadd_s32_z(pg, op1, op2); }
......
...@@ -40,6 +40,25 @@ ...@@ -40,6 +40,25 @@
#define VECTOR_FOR(i, w, inc) \ #define VECTOR_FOR(i, w, inc) \
for (unsigned int i = 0; i < w; i += inc) for (unsigned int i = 0; i < w; i += inc)
// bitwise and two vectors
struct bitwise_and_vector_vector{
template <typename T>
inline vector_t<T> operator()(const vector_t<T> &a, const vector_t<T> &b)
{
assert(a.size == b.size);
vector_t<T> vres(a.size);
std::cout << "[Generic vector (bitwise and) used]" << endl;
VECTOR_FOR(i, vres.size, 1)
{
vres.elem[i] = a.elem[i] & b.elem[i];
}
return vres;
}
};
// bitwise or two vectors // bitwise or two vectors
struct bitwise_or_vector_vector{ struct bitwise_or_vector_vector{
template <typename T> template <typename T>
...@@ -59,6 +78,63 @@ struct bitwise_or_vector_vector{ ...@@ -59,6 +78,63 @@ struct bitwise_or_vector_vector{
} }
}; };
// bitwise xor two vectors
struct bitwise_xor_vector_vector{
template <typename T>
inline vector_t<T> operator()(const vector_t<T> &a, const vector_t<T> &b)
{
assert(a.size == b.size);
vector_t<T> vres(a.size);
std::cout << "[Generic vector (bitwise xor) used]" << endl;
VECTOR_FOR(i, vres.size, 1)
{
vres.elem[i] = a.elem[i] ^ b.elem[i];
}
return vres;
}
};
// bitwise not two vectors
struct bitwise_not_vector_vector{
template <typename T>
inline vector_t<T> operator()(const vector_t<T> &a, const vector_t<T> &b)
{
assert(a.size == b.size);
vector_t<T> vres(a.size);
std::cout << "[Generic vector (bitwise not) used]" << endl;
VECTOR_FOR(i, vres.size, 1)
{
vres.elem[i] = a.elem[i] ~ b.elem[i];
}
return vres;
}
};
// bitwise logical shift left two vectors
struct bitwise_logical_shift_left_vector_vector{ template <typename T>
inline vector_t<T> operator()(const vector_t<T> &a, const int &b)
{
assert(a.size == b.size);
vector_t<T> vres(a.size);
std::cout << "[Generic vector (bitwise not) used]" << endl;
VECTOR_FOR(i, vres.size, 1)
{
vres.elem[i] = a.elem[i] << b;
}
return vres;
}
};
#endif // GEN_BIT_OPS_HPP #endif // GEN_BIT_OPS_HPP
...@@ -37,6 +37,36 @@ ...@@ -37,6 +37,36 @@
#include "sve_bitwise.hpp" #include "sve_bitwise.hpp"
// bitwise_and two vectors
struct bitwise_and_vector_vector{
template <typename T>
inline vector_t<T> operator()(const vector_t<T> &a, const vector_t<T> &b)
{
assert(a.size == b.size);
int64_t i = 0;
vector_t<T> vres(a.size);
svbool_t ig = svetype<T>::svwhile(i, vres.size);
std::cout << "[SVE vector (bitwise and) used]" << endl;
do
{
typename svetype<T>::vec x0 = svetype<T>::vload(ig, (const T *) &a.elem[i]);
typename svetype<T>::vec x1 = svetype<T>::vload(ig, (const T *) &b.elem[i]);
typename svetype<T>::vec res = svetype<T>::and_z(ig, x0, x1);
svetype<T>::vstore(ig, (T *) &vres.elem[i], res);
i += svetype<T>::count();
ig = svetype<T>::svwhile(i, vres.size);
}
while (svptest_any(svetype<T>::svtrue(), ig));
return vres;
}
};
// bitwise_or two vectors // bitwise_or two vectors
struct bitwise_or_vector_vector{ struct bitwise_or_vector_vector{
template <typename T> template <typename T>
...@@ -48,7 +78,7 @@ struct bitwise_or_vector_vector{ ...@@ -48,7 +78,7 @@ struct bitwise_or_vector_vector{
vector_t<T> vres(a.size); vector_t<T> vres(a.size);
svbool_t ig = svetype<T>::svwhile(i, vres.size); svbool_t ig = svetype<T>::svwhile(i, vres.size);
std::cout << "[SVE vector (SUM) used]" << endl; std::cout << "[SVE vector (bitwise or) used]" << endl;
do do
{ {
typename svetype<T>::vec x0 = svetype<T>::vload(ig, (const T *) &a.elem[i]); typename svetype<T>::vec x0 = svetype<T>::vload(ig, (const T *) &a.elem[i]);
...@@ -67,6 +97,96 @@ struct bitwise_or_vector_vector{ ...@@ -67,6 +97,96 @@ struct bitwise_or_vector_vector{
} }
}; };
// bitwise_xor two vectors
struct bitwise_xor_vector_vector{
template <typename T>
inline vector_t<T> operator()(const vector_t<T> &a, const vector_t<T> &b)
{
assert(a.size == b.size);
int64_t i = 0;
vector_t<T> vres(a.size);
svbool_t ig = svetype<T>::svwhile(i, vres.size);
std::cout << "[SVE vector (bitwise xor) used]" << endl;
do
{
typename svetype<T>::vec x0 = svetype<T>::vload(ig, (const T *) &a.elem[i]);
typename svetype<T>::vec x1 = svetype<T>::vload(ig, (const T *) &b.elem[i]);
typename svetype<T>::vec res = svetype<T>::eor_z(ig, x0, x1);
svetype<T>::vstore(ig, (T *) &vres.elem[i], res);
i += svetype<T>::count();
ig = svetype<T>::svwhile(i, vres.size);
}
while (svptest_any(svetype<T>::svtrue(), ig));
return vres;
}
};
// bitwise_not two vectors
struct bitwise_not_vector_vector{
template <typename T>
inline vector_t<T> operator()(const vector_t<T> &a, const vector_t<T> &b)
{
assert(a.size == b.size);
int64_t i = 0;
vector_t<T> vres(a.size);
svbool_t ig = svetype<T>::svwhile(i, vres.size);
std::cout << "[SVE vector (bitwise not) used]" << endl;
do
{
typename svetype<T>::vec x0 = svetype<T>::vload(ig, (const T *) &a.elem[i]);
typename svetype<T>::vec x1 = svetype<T>::vload(ig, (const T *) &b.elem[i]);
typename svetype<T>::vec res = svetype<T>::not_z(ig, x0, x1);
svetype<T>::vstore(ig, (T *) &vres.elem[i], res);
i += svetype<T>::count();
ig = svetype<T>::svwhile(i, vres.size);
}
while (svptest_any(svetype<T>::svtrue(), ig));
return vres;
}
};
// bitwise_not two vectors
struct bitwise_not_vector_vector{
template <typename T>
inline vector_t<T> operator()(const vector_t<T> &a, const vector_t<T> &b)
{
assert(a.size == b.size);
int64_t i = 0;
vector_t<T> vres(a.size);
svbool_t ig = svetype<T>::svwhile(i, vres.size);
std::cout << "[SVE vector (bitwise not) used]" << endl;
do
{
typename svetype<T>::vec x0 = svetype<T>::vload(ig, (const T *) &a.elem[i]);
typename svetype<T>::vec x1 = svetype<T>::vload(ig, (const T *) &b.elem[i]);
typename svetype<T>::vec res = svetype<T>::not_z(ig, x0, x1);
svetype<T>::vstore(ig, (T *) &vres.elem[i], res);
i += svetype<T>::count();
ig = svetype<T>::svwhile(i, vres.size);
}
while (svptest_any(svetype<T>::svtrue(), ig));
return vres;
}
};
#endif #endif
#endif // SVE_BIT_OPS_HPP #endif // SVE_BIT_OPS_HPP
......
...@@ -72,6 +72,4 @@ using namespace std; ...@@ -72,6 +72,4 @@ using namespace std;
#include "vector_overloading.hpp" #include "vector_overloading.hpp"
#include "matrix_overloading.hpp" #include "matrix_overloading.hpp"
#endif // SIMD_HPP #endif // SIMD_HPP
File added
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment