Skip to content

Commit

Permalink
Support Microsoft CL.EXE compiler (#137)
Browse files Browse the repository at this point in the history
Support Microsoft CL.EXE compiler
  • Loading branch information
jonahbeckford authored Feb 22, 2024
1 parent 9603ebb commit 839558e
Show file tree
Hide file tree
Showing 21 changed files with 181 additions and 35 deletions.
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"
;;
*)
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" ]
| _ -> []
in
let std_flags =
match ccomp_type_opt with
| Some "msvc" -> ["/Wall"]
| _ -> ["--std=c11"; "-Wall"; "-Wextra"; "-Wpedantic"; "-O3"]
in
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)
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__)

# 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;
}

#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)
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

0 comments on commit 839558e

Please sign in to comment.