Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Microsoft CL.EXE compiler #137

Merged
merged 7 commits into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
*.ml linguist-language=OCaml

# Shell scripts are required to be LF
*.sh text eol=lf

# https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_character_encoding?view=powershell-7.1
*.ps1 text working-tree-encoding=UTF-16 eol=crlf
*.psm1 text working-tree-encoding=UTF-16 eol=crlf
Expand Down
24 changes: 20 additions & 4 deletions ci/build-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,23 @@ opamrun exec -- ocamlc -config
# Update
opamrun update

# Make your own build logic!
opamrun install --yes --deps-only -t mirage-crypto mirage-crypto-rng mirage-crypto-rng-lwt mirage-crypto-rng-mirage mirage-crypto-pk mirage-crypto-ec
opamrun exec -- dune build -p mirage-crypto,mirage-crypto-rng,mirage-crypto-rng-lwt,mirage-crypto-rng-mirage,mirage-crypto-pk,mirage-crypto-ec
opamrun exec -- dune runtest -p mirage-crypto,mirage-crypto-rng,mirage-crypto-rng-lwt,mirage-crypto-rng-mirage,mirage-crypto-pk,mirage-crypto-ec
# Build logic
# 2024-02-09: Remove mirage-crypto-pk on Windows since no portable GMP library (used by Zarith).
# mirage-crypto-ec has a test dependency on mirage-crypto-pk.
packages_INSTALL="mirage-crypto mirage-crypto-rng mirage-crypto-rng-lwt mirage-crypto-rng-mirage"
packages_BUILD_TOPOLOGICALSORT="mirage-crypto,mirage-crypto-rng,mirage-crypto-rng-lwt,mirage-crypto-rng-mirage"
packages_TEST_TOPOLOGICALSORT="mirage-crypto,mirage-crypto-rng,mirage-crypto-rng-lwt,mirage-crypto-rng-mirage"
case "$dkml_host_abi" in
windows_*)
packages_INSTALL="$packages_INSTALL mirage-crypto-ec"
packages_BUILD_TOPOLOGICALSORT="$packages_BUILD_TOPOLOGICALSORT,mirage-crypto-ec"
hannesm marked this conversation as resolved.
Show resolved Hide resolved
;;
*)
packages_INSTALL="$packages_INSTALL mirage-crypto-pk mirage-crypto-ec"
packages_BUILD_TOPOLOGICALSORT="$packages_BUILD_TOPOLOGICALSORT,mirage-crypto-pk,mirage-crypto-ec"
packages_TEST_TOPOLOGICALSORT="$packages_TEST_TOPOLOGICALSORT,mirage-crypto-pk,mirage-crypto-ec"
esac
# shellcheck disable=SC2086
opamrun install --yes --deps-only --with-test $packages_INSTALL
opamrun exec -- dune build -p "$packages_BUILD_TOPOLOGICALSORT"
opamrun exec -- dune runtest -p "$packages_TEST_TOPOLOGICALSORT"
28 changes: 19 additions & 9 deletions config/cfg.ml
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
let std_flags = ["--std=c11"; "-Wall"; "-Wextra"; "-Wpedantic"; "-O3"]

let () =
let c = Configurator.V1.create "mirage-crypto" in
let ccomp_type_opt = Configurator.V1.ocaml_config_var c "ccomp_type" in
let arch =
let defines =
Configurator.V1.C_define.import
c
~includes:[]
[("__x86_64__", Switch); ("__i386__", Switch); ("__powerpc64__", Switch);
("__s390x__", Switch); ("__aarch64__", Switch)]
("__s390x__", Switch); ("__aarch64__", Switch);
("_WIN64", Switch); ("_WIN32", Switch)]
in
match defines with
| (_, Switch true) :: _ -> `x86_64
| _ :: (_, Switch true) :: _ -> `x86
| _ :: _ :: (_, Switch true) :: _ -> `ppc64
| _ :: _ :: _ :: (_, Switch true) :: _ -> `s390x
| _ :: _ :: _ :: _ :: (_, Switch true) :: _ -> `arm64
| _ :: _ :: _ :: _ :: _ :: (_, Switch true) :: _ -> `x86_64
| _ :: _ :: _ :: _ :: _ :: _ :: (_, Switch true) :: _ -> `x86
| _ -> `unknown
in
let os =
Expand All @@ -30,19 +32,27 @@ let () =
| _ -> `unknown
in
let accelerate_flags =
match arch with
| `x86_64 -> [ "-DACCELERATE"; "-mssse3"; "-maes"; "-mpclmul" ]
match arch, ccomp_type_opt with
| `x86_64, Some "msvc" -> [ "-DACCELERATE" ]
| `x86_64, _ -> [ "-DACCELERATE"; "-mssse3"; "-maes"; "-mpclmul" ]
| _ -> []
in
let ent_flags =
match arch with
| `x86_64 | `x86 -> [ "-DENTROPY"; "-mrdrnd"; "-mrdseed" ]
match arch, ccomp_type_opt with
| (`x86_64 | `x86), Some "msvc" -> [ "-DENTROPY" ]
| (`x86_64 | `x86), _ -> [ "-DENTROPY"; "-mrdrnd"; "-mrdseed" ]
| _ -> []
hannesm marked this conversation as resolved.
Show resolved Hide resolved
in
let std_flags =
match ccomp_type_opt with
| Some "msvc" -> ["/Wall"]
| _ -> ["-Wall"]
in
jonahbeckford marked this conversation as resolved.
Show resolved Hide resolved
let warn_flags =
(* See #178, there may be false positives on ppc&s390 with no-stringop-overflow *)
match arch with
| `ppc64 | `s390x -> [ "-Wno-stringop-overflow"; "-Werror" ]
match arch, ccomp_type_opt with
| _, Some "msvc" -> [ "/WX" ]
| (`ppc64, _) | (`s390x, _) -> [ "-Wno-stringop-overflow"; "-Werror" ]
| _ -> [ "-Werror" ]
in
let no_instcombine_on_macos = match arch, os with
Expand Down
5 changes: 4 additions & 1 deletion ec/native/curve25519_stubs.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include "mirage_crypto.h"

#ifdef ARCH_64BIT
/* Microsoft compiler does not support 128-bit integers. Drop down to
* 32-bit for MSVC.
*/
#if defined(ARCH_64BIT) && !defined(_MSC_VER)
#include "curve25519_64.h"
#define WORD uint64_t
#define LIMBS 5
Expand Down
5 changes: 4 additions & 1 deletion ec/native/np224_stubs.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include "mirage_crypto.h"

#ifdef ARCH_64BIT
/* Microsoft compiler does not support 128-bit integers. Drop down to
* 32-bit for MSVC.
*/
#if defined(ARCH_64BIT) && !defined(_MSC_VER)
#include "np224_64.h"
#define LIMBS 4
#define WORD uint64_t
Expand Down
5 changes: 4 additions & 1 deletion ec/native/np256_stubs.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include "mirage_crypto.h"

#ifdef ARCH_64BIT
/* Microsoft compiler does not support 128-bit integers. Drop down to
* 32-bit for MSVC.
*/
#if defined(ARCH_64BIT) && !defined(_MSC_VER)
#include "np256_64.h"
#define LIMBS 4
#define WORD uint64_t
Expand Down
5 changes: 4 additions & 1 deletion ec/native/np384_stubs.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include "mirage_crypto.h"

#ifdef ARCH_64BIT
/* Microsoft compiler does not support 128-bit integers. Drop down to
* 32-bit for MSVC.
*/
#if defined(ARCH_64BIT) && !defined(_MSC_VER)
#include "np384_64.h"
#define LIMBS 6
#define WORD uint64_t
Expand Down
5 changes: 4 additions & 1 deletion ec/native/np521_stubs.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include "mirage_crypto.h"

#ifdef ARCH_64BIT
/* Microsoft compiler does not support 128-bit integers. Drop down to
* 32-bit for MSVC.
*/
#if defined(ARCH_64BIT) && !defined(_MSC_VER)
#include "np521_64.h"
#define LIMBS 9
#define WORD uint64_t
Expand Down
5 changes: 4 additions & 1 deletion ec/native/p224_stubs.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include "mirage_crypto.h"

#ifdef ARCH_64BIT
/* Microsoft compiler does not support 128-bit integers. Drop down to
* 32-bit for MSVC.
*/
#if defined(ARCH_64BIT) && !defined(_MSC_VER)
#include "p224_64.h"
#define LIMBS 4
#define WORD uint64_t
Expand Down
5 changes: 4 additions & 1 deletion ec/native/p256_stubs.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include "mirage_crypto.h"

#ifdef ARCH_64BIT
/* Microsoft compiler does not support 128-bit integers. Drop down to
* 32-bit for MSVC.
*/
#if defined(ARCH_64BIT) && !defined(_MSC_VER)
#include "p256_64.h"
#define LIMBS 4
#define WORD uint64_t
Expand Down
5 changes: 4 additions & 1 deletion ec/native/p384_stubs.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include "mirage_crypto.h"

#ifdef ARCH_64BIT
/* Microsoft compiler does not support 128-bit integers. Drop down to
* 32-bit for MSVC.
*/
#if defined(ARCH_64BIT) && !defined(_MSC_VER)
#include "p384_64.h"
#define LIMBS 6
#define WORD uint64_t
Expand Down
5 changes: 4 additions & 1 deletion ec/native/p521_stubs.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include "mirage_crypto.h"

#ifdef ARCH_64BIT
/* Microsoft compiler does not support 128-bit integers. Drop down to
* 32-bit for MSVC.
*/
#if defined(ARCH_64BIT) && !defined(_MSC_VER)
#include "p521_64.h"
#define LIMBS 9
#define WORD uint64_t
Expand Down
4 changes: 3 additions & 1 deletion rng/unix/mc_getrandom_stubs.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include <unistd.h>
#ifndef _MSC_VER
# include <unistd.h>
#endif

#include <caml/mlvalues.h>
#include <caml/memory.h>
Expand Down
9 changes: 8 additions & 1 deletion src/native/aes_aesni.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ static int _mc_aesni_rk_size (uint8_t rounds) {
return (rounds + 1) * 16 + 15;
}

#if defined(__x86_64__)
#if defined(__x86_64__) || defined(_WIN64)
hannesm marked this conversation as resolved.
Show resolved Hide resolved
static inline __m128i* __rk (const void *rk) {
return (__m128i *) (((uint64_t)rk + 15) & -16);
}
Expand All @@ -48,10 +48,17 @@ static inline __m128i __mix (__m128i r1, __m128i r2) {

#define __assist(r1, r2, mode) (__mix (r1, _mm_shuffle_epi32 (r2, mode)))

#ifdef _MSC_VER
static inline void __pack (__m128i *o1, __m128i *o2, __m128i r1, __m128i r2, __m128i r3) {
*o1 = _mm_castpd_si128 (_mm_shuffle_pd (_mm_castsi128_pd (r1), _mm_castsi128_pd (r2), 0));
*o2 = _mm_castpd_si128 (_mm_shuffle_pd (_mm_castsi128_pd (r2), _mm_castsi128_pd (r3), 1));
}
#else
static inline void __pack (__m128i *o1, __m128i *o2, __m128i r1, __m128i r2, __m128i r3) {
*o1 = (__m128i) _mm_shuffle_pd ((__m128d) r1, (__m128d) r2, 0);
*o2 = (__m128i) _mm_shuffle_pd ((__m128d) r2, (__m128d) r3, 1);
}
#endif

static inline void _mc_aesni_derive_e_key (const uint8_t *key, uint8_t *rk0, uint8_t rounds) {

Expand Down
4 changes: 2 additions & 2 deletions src/native/bitfn.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ static inline void array_copy64(uint64_t *d, uint64_t *s, uint32_t nb)
while (nb--) *d++ = *s++;
}

#ifdef __BYTE_ORDER__
#if __ORDER_LITTLE_ENDIAN__ == __BYTE_ORDER__
#if defined(_MSC_VER) || defined(__BYTE_ORDER__)
#if defined(_MSC_VER) || (__ORDER_LITTLE_ENDIAN__ == __BYTE_ORDER__)
hannesm marked this conversation as resolved.
Show resolved Hide resolved

# define be32_to_cpu(a) bitfn_swap32(a)
# define cpu_to_be32(a) bitfn_swap32(a)
Expand Down
46 changes: 45 additions & 1 deletion src/native/detect_cpu_features.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,53 @@

#ifdef __mc_detect_features__

#include <cpuid.h>
#ifndef _MSC_VER
# include <cpuid.h>
#endif

struct _mc_cpu_features mc_detected_cpu_features = { 0 };

#ifdef _MSC_VER
#define bit_PCLMUL ((int)1 << 1)
#define bit_SSSE3 ((int)1 << 9)
#define bit_AES ((int)1 << 25)
#define bit_RDRND ((int)1 << 30)
#define bit_RDSEED ((int)1 << 18)

CAMLprim value
mc_detect_cpu_features (__unit ()) {
int cpuInfo[4] = {-1};
int ebx;
int ecx;

__cpuid(cpuInfo, 0x00000000);
int max = cpuInfo[0];
if (max < 1) return Val_unit;

__cpuid(cpuInfo, 0x00000001);
ecx = cpuInfo[2];

if (ecx & bit_PCLMUL)
mc_detected_cpu_features.pclmul = 1;
if (ecx & bit_SSSE3)
mc_detected_cpu_features.ssse3 = 1;
if (ecx & bit_AES)
mc_detected_cpu_features.aesni = 1;
if (ecx & bit_RDRND)
mc_detected_cpu_features.rdrand = 1;

if (max > 7) {
__cpuid(cpuInfo, 0x00000007);
ebx = cpuInfo[1];
if (ebx & bit_RDSEED)
mc_detected_cpu_features.rdseed = 1;
}

return Val_unit;
}
hannesm marked this conversation as resolved.
Show resolved Hide resolved

#else

CAMLprim value
mc_detect_cpu_features (__unit ()) {
unsigned int sig = 0, eax = 0, ebx = 0, ecx = 0, edx = 0;
Expand All @@ -32,6 +75,7 @@ mc_detect_cpu_features (__unit ()) {

return Val_unit;
}
#endif /* _MSC_VER */

#else /* __mc_detect_features__ */

Expand Down
18 changes: 17 additions & 1 deletion src/native/entropy_cpu_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,22 @@
output.
*/

#if defined (_MSC_VER)
#include <immintrin.h>

#if defined (_WIN64)
#define random_t unsigned long long
#define _rdseed_step _rdseed64_step
#define _rdrand_step _rdrand64_step

#elif defined (_WIN32)
#define random_t unsigned int
#define _rdseed_step _rdseed32_step
#define _rdrand_step _rdrand32_step
#endif

#endif /* _MSC_VER */

#if defined (__arm__)
/*
* The ideal timing source on ARM are the performance counters, but these are
Expand Down Expand Up @@ -153,7 +169,7 @@ static inline unsigned long get_count(void) {
#endif

CAMLprim value mc_cycle_counter (value __unused(unit)) {
#if defined (__i386__) || defined (__x86_64__)
#if defined (__i386__) || defined (__x86_64__) || defined (_MSC_VER)
hannesm marked this conversation as resolved.
Show resolved Hide resolved
return Val_long (__rdtsc ());
#elif defined (__arm__) || defined (__aarch64__)
return Val_long (read_virtual_count ());
Expand Down
5 changes: 4 additions & 1 deletion src/native/ghash_ctmul.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@
#include "mirage_crypto.h"
#include <string.h>

#if defined (ARCH_32BIT)
/* Microsoft compiler does not support 128-bit integers. Drop down to
* 32-bit for MSVC.
*/
#if defined (ARCH_32BIT) || defined(_MSC_VER)

/*
* We cannot really autodetect whether multiplications are "slow" or
Expand Down
6 changes: 5 additions & 1 deletion src/native/ghash_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
* !LARGE_TABLES -> 8K per key, ~3x slower. */
#define __MC_GHASH_LARGE_TABLES

#ifdef ARCH_64BIT
/* 64-bit Windows sets ARCH_64BIT but 128-bit integers are not supported
* by the Microsoft compiler. Drop down to 32-bit for MSVC;
* ghash_ctmul.c will implement ghash for MSVC.
*/
#if defined(ARCH_64BIT) && !defined(_MSC_VER)

#define __set_uint128_t(w1, w0) (((__uint128_t) w1 << 64) | w0)

Expand Down
Loading
Loading