Merge branch 'dev'

update-fork
MITSUNARI Shigeo 4 years ago
commit b730448fa0
  1. 40
      include/mcl/vint.hpp
  2. 2
      misc/Makefile
  3. 2
      misc/low_test.cpp
  4. 8
      src/fp.cpp
  5. 50
      src/low_func_wasm.hpp

@ -90,35 +90,19 @@ inline uint32_t mulUnit(uint32_t *pH, uint32_t x, uint32_t y)
inline uint64_t mulUnit(uint64_t *pH, uint64_t x, uint64_t y) inline uint64_t mulUnit(uint64_t *pH, uint64_t x, uint64_t y)
{ {
#ifdef MCL_VINT_64BIT_PORTABLE #ifdef MCL_VINT_64BIT_PORTABLE
uint32_t a = uint32_t(x >> 32); const uint64_t mask = 0xffffffff;
uint32_t b = uint32_t(x); uint64_t v = (x & mask) * (y & mask);
uint32_t c = uint32_t(y >> 32); uint64_t L = uint32_t(v);
uint32_t d = uint32_t(y); uint64_t H = v >> 32;
uint64_t ad = (x & mask) * uint32_t(y >> 32);
uint64_t ad = uint64_t(d) * a; uint64_t bc = uint32_t(x >> 32) * (y & mask);
uint64_t bd = uint64_t(d) * b; H += uint32_t(ad);
uint64_t L = uint32_t(bd); H += uint32_t(bc);
ad += bd >> 32; // [ad:L]
uint64_t ac = uint64_t(c) * a;
uint64_t bc = uint64_t(c) * b;
uint64_t H = uint32_t(bc);
ac += bc >> 32; // [ac:H]
/*
adL
acH
*/
uint64_t t = (ac << 32) | H;
ac >>= 32;
H = t + ad;
if (H < t) {
ac++;
}
/*
ac:H:L
*/
L |= H << 32; L |= H << 32;
H = (ac << 32) | uint32_t(H >> 32); H >>= 32;
H += ad >> 32;
H += bc >> 32;
H += (x >> 32) * (y >> 32);
*pH = H; *pH = H;
return L; return L;
#elif defined(_WIN64) && !defined(__INTEL_COMPILER) #elif defined(_WIN64) && !defined(__INTEL_COMPILER)

@ -2,5 +2,5 @@ all: low_test
CFLAGS=-I ../include/ -m32 -Ofast -Wall -Wextra -DNDEBUG CFLAGS=-I ../include/ -m32 -Ofast -Wall -Wextra -DNDEBUG
low_test: low_test.cpp ../src/low_funct.hpp low_test: low_test.cpp ../src/low_func_wasm.hpp
$(CXX) -o low_test low_test.cpp $(CFLAGS) $(CXX) -o low_test low_test.cpp $(CFLAGS)

@ -9,7 +9,7 @@ void dump(const char *msg, const uint32_t *x, size_t n)
} }
printf("\n"); printf("\n");
} }
#include "../src/low_funct.hpp" #include "../src/low_func_wasm.hpp"
#define MCL_USE_VINT #define MCL_USE_VINT
#define MCL_VINT_FIXED_BUFFER #define MCL_VINT_FIXED_BUFFER

@ -4,8 +4,8 @@
#include <cybozu/endian.hpp> #include <cybozu/endian.hpp>
#include <mcl/conversion.hpp> #include <mcl/conversion.hpp>
#if defined(__EMSCRIPTEN__) && MCL_SIZEOF_UNIT == 4 #if defined(__EMSCRIPTEN__) && MCL_SIZEOF_UNIT == 4
#define FOR_WASM #define USE_WASM
#include "low_funct.hpp" #include "low_func_wasm.hpp"
#endif #endif
#if defined(MCL_STATIC_CODE) || defined(MCL_USE_XBYAK) || (defined(MCL_USE_LLVM) && (CYBOZU_HOST == CYBOZU_HOST_INTEL)) #if defined(MCL_STATIC_CODE) || defined(MCL_USE_XBYAK) || (defined(MCL_USE_LLVM) && (CYBOZU_HOST == CYBOZU_HOST_INTEL))
@ -411,7 +411,7 @@ static bool initForMont(Op& op, const Unit *p, Mode mode)
return true; return true;
} }
#ifdef FOR_WASM #ifdef USE_WASM
template<size_t N> template<size_t N>
void setWasmOp(Op& op) void setWasmOp(Op& op)
{ {
@ -570,7 +570,7 @@ bool Op::init(const mpz_class& _p, size_t maxBitSize, int _xi_a, Mode mode, size
default: default:
return false; return false;
} }
#ifdef FOR_WASM #ifdef USE_WASM
if (N == 8) { if (N == 8) {
setWasmOp<8>(*this); setWasmOp<8>(*this);
} else if (N == 12) { } else if (N == 12) {

@ -118,56 +118,6 @@ void mulT(uint32_t z[N * 2], const uint32_t x[N], const uint32_t y[N])
} }
} }
#if 0
// slower than mulT
template<size_t N>
uint32_t mulUnitWithTblT(uint32_t z[N], const uint64_t *tbl_j)
{
uint32_t H = 0;
for (size_t i = 0; i < N; i++) {
uint64_t v = tbl_j[i];
v += H;
z[i] = uint32_t(v);
H = uint32_t(v >> 32);
}
return H;
}
template<size_t N>
uint32_t addMulUnitWithTblT(uint32_t z[N], const uint64_t *tbl_j)
{
uint32_t H = 0;
for (size_t i = 0; i < N; i++) {
uint64_t v = tbl_j[i];
v += H;
v += z[i];
z[i] = uint32_t(v);
H = uint32_t(v >> 32);
}
return H;
}
// y[N * 2] = x[N] * x[N]
template<size_t N>
void sqrT(uint32_t y[N * 2], const uint32_t x[N])
{
uint64_t tbl[N * N]; // x[i]x[j]
for (size_t i = 0; i < N; i++) {
uint64_t xi = x[i];
tbl[i * N + i] = xi * xi;
for (size_t j = i + 1; j < N; j++) {
uint64_t v = xi * x[j];
tbl[i * N + j] = v;
tbl[j * N + i] = v;
}
}
y[N] = mulUnitWithTblT<N>(y, tbl);
for (size_t i = 1; i < N; i++) {
y[N + i] = addMulUnitWithTblT<N>(&y[i], tbl + N * i);
}
}
#endif
/* /*
z[N * 2] = x[N] * y[N] z[N * 2] = x[N] * y[N]
H = N/2 H = N/2
Loading…
Cancel
Save