diff --git a/Cargo.toml b/Cargo.toml index 3562f0d..6c7ea30 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -72,6 +72,7 @@ u64_backend = [] # The AVX2 backend uses u32x8s with u64x4 products. # It uses the u64 code for serial operations. avx2_backend = ["nightly", "u64_backend", "packed_simd"] +ifma_backend = ["nightly", "u64_backend", "packed_simd", "yolocrypto"] # Signals that we're in the main build stage. This is off by default, # to signal stage 1 of the build, where build.rs loads the library diff --git a/build.rs b/build.rs index 38b577a..e684b37 100644 --- a/build.rs +++ b/build.rs @@ -1,3 +1,5 @@ +#![cfg_attr(feature = "ifma_backend", feature(simd_ffi))] +#![cfg_attr(feature = "ifma_backend", feature(link_llvm_intrinsics))] #![cfg_attr(all(feature = "alloc", not(feature = "std")), feature(alloc))] #![cfg_attr(feature = "nightly", feature(cfg_target_feature))] #![allow(unused_variables)] @@ -13,7 +15,7 @@ extern crate digest; extern crate rand; extern crate subtle; -#[cfg(all(feature = "nightly", feature = "avx2_backend"))] +#[cfg(all(feature = "nightly", any(feature = "avx2_backend", feature = "ifma_backend")))] extern crate packed_simd; use std::env; diff --git a/src/backend/mod.rs b/src/backend/mod.rs index be537e6..82eeb5b 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -21,7 +21,11 @@ //! `32bit` since identifiers can't start with letters, and the backends //! do use `u32`/`u64`, so this seems like a least-bad option. -#[cfg(not(any(feature = "u32_backend", feature = "u64_backend", feature = "avx2_backend")))] +#[cfg(not(any( + feature = "u32_backend", + feature = "u64_backend", + feature = "avx2_backend" +)))] compile_error!( "no curve25519-dalek backend cargo feature enabled! \ please enable one of: u32_backend, u64_backend, avx2_backend" @@ -29,5 +33,8 @@ compile_error!( pub mod serial; -#[cfg(all(feature = "avx2_backend", target_feature = "avx2"))] +#[cfg(any( + all(feature = "ifma_backend", target_feature = "avx512ifma"), + all(feature = "avx2_backend", target_feature = "avx2"), +))] pub mod vector; diff --git a/src/backend/vector/ifma/field.rs b/src/backend/vector/ifma/field.rs new file mode 100644 index 0000000..6ff36b7 --- /dev/null +++ b/src/backend/vector/ifma/field.rs @@ -0,0 +1,40 @@ +// -*- mode: rust; coding: utf-8; -*- +// +// This file is part of curve25519-dalek. +// Copyright (c) 2018 Henry de Valence +// See LICENSE for licensing information. +// +// Authors: +// - Henry de Valence + +use core::ops::{Add, Mul, Neg}; +use packed_simd::{i32x8, u32x8, u64x4, IntoBits}; + +use backend::serial::u64::field::FieldElement51; + +#[allow(improper_ctypes)] +extern "C" { + #[link_name = "llvm.x86.avx512.vpmadd52l.uq.256"] + fn madd52lo(z: u64x4, x: u64x4, y: u64x4) -> u64x4; + #[link_name = "llvm.x86.avx512.vpmadd52h.uq.256"] + fn madd52hi(z: u64x4, x: u64x4, y: u64x4) -> u64x4; +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn vpmadd52luq() { + let x = u64x4::splat(2); + let y = u64x4::splat(3); + let mut z = u64x4::splat(5); + + z = unsafe { madd52lo(z, x, y) }; + + assert_eq!(z, u64x4::splat(5 + 2*3)); + } + +} + + diff --git a/src/backend/vector/ifma/mod.rs b/src/backend/vector/ifma/mod.rs new file mode 100644 index 0000000..4238412 --- /dev/null +++ b/src/backend/vector/ifma/mod.rs @@ -0,0 +1,11 @@ +// -*- mode: rust; -*- +// +// This file is part of curve25519-dalek. +// Copyright (c) 2018 Henry de Valence +// See LICENSE for licensing information. +// +// Authors: +// - Henry de Valence + +pub(crate) mod field; + diff --git a/src/backend/vector/mod.rs b/src/backend/vector/mod.rs index 7c5609d..e7749f2 100644 --- a/src/backend/vector/mod.rs +++ b/src/backend/vector/mod.rs @@ -28,5 +28,8 @@ pub(crate) use self::avx2::{ constants::BASEPOINT_ODD_LOOKUP_TABLE, edwards::CachedPoint, edwards::ExtendedPoint, }; +#[cfg(all(feature = "ifma_backend", target_feature = "avx512ifma"))] +pub mod ifma; + pub mod scalar_mul; diff --git a/src/lib.rs b/src/lib.rs index 13b7f9c..07a91be 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,9 @@ #![no_std] +#![cfg_attr(feature = "ifma_backend", feature(simd_ffi))] +#![cfg_attr(feature = "ifma_backend", feature(link_llvm_intrinsics))] + #![cfg_attr(all(feature = "alloc", not(feature = "std")), feature(alloc))] #![cfg_attr(feature = "nightly", feature(cfg_target_feature))] #![cfg_attr(feature = "nightly", feature(external_doc))] @@ -38,7 +41,7 @@ extern crate alloc; #[macro_use] extern crate std; -#[cfg(all(feature = "nightly", feature = "avx2_backend"))] +#[cfg(all(feature = "nightly", any(feature = "avx2_backend", feature = "ifma_backend")))] extern crate packed_simd; extern crate rand;