Skip to content

Commit

Permalink
Support Microsoft CL.EXE compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
jonahbeckford committed Aug 26, 2021
1 parent d056a79 commit 72eaf04
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 23 deletions.
34 changes: 27 additions & 7 deletions config/cfg.ml
Original file line number Diff line number Diff line change
@@ -1,30 +1,50 @@
let std_flags = ["--std=c11"; "-Wall"; "-Wextra"; "-Wpedantic"; "-O3"]
let std_flags = ["-Wall"]

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)]
[("__x86_64__", Switch); ("__i386__", Switch); ("_WIN64", Switch); ("_WIN32", Switch)]
in
match defines with
| (_, Switch true) :: _ -> `x86_64
| _ :: (_, Switch true) :: _ -> `x86
| _ :: _ :: (_, Switch true) :: _ -> `x86_64
| _ :: _ :: _ :: (_, Switch true) :: _ -> `x86
| _ -> `unknown
in
let accelerate_flags =
match arch with
| `x86_64 -> [ "-DACCELERATE"; "-mssse3"; "-maes"; "-mpclmul" ]
match arch, ccomp_type_opt with
| `x86_64, Some ccomp_type when ccomp_type = "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 ccomp_type when ccomp_type = "msvc" -> [ "-DENTROPY" ]
| (`x86_64 | `x86), _ -> [ "-DENTROPY"; "-mrdrnd"; "-mrdseed" ]
| _ -> []
in
let flags = std_flags @ ent_flags in
let lang_flags =
match ccomp_type_opt with
| Some ccomp_type when ccomp_type = "msvc" -> ["/std:c11"]
| _ -> ["--std=c11"]
in
let warn_flags =
match ccomp_type_opt with
| Some ccomp_type when ccomp_type = "msvc" -> []
| _ -> ["-Wextra"; "-Wpedantic"]
in
let optimization_flags =
match ccomp_type_opt with
| Some ccomp_type when ccomp_type = "msvc" -> ["-O2"]
| _ -> ["-O3"]
in
let flags = std_flags @ ent_flags @ lang_flags @ warn_flags @ optimization_flags in
let opt_flags = flags @ accelerate_flags in
Configurator.V1.Flags.write_sexp "cflags_optimized.sexp" opt_flags;
Configurator.V1.Flags.write_sexp "cflags.sexp" flags
4 changes: 2 additions & 2 deletions ec-freestanding/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ ifneq (, $(shell command -v opam))
PKG_CONFIG_PATH ?= $(shell opam var prefix)/lib/pkgconfig
endif

EXISTS := $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --exists ocaml-freestanding; echo $$?)
EXISTS := $(shell PKG_CONFIG_PATH="$(PKG_CONFIG_PATH)" pkg-config --exists ocaml-freestanding; echo $$?)

.PHONY: all clean
all: libmirage_crypto_ec_freestanding_stubs.a
Expand All @@ -12,7 +12,7 @@ libmirage_crypto_ec_freestanding_stubs.a:
touch $@
else
CC ?= cc
FREESTANDING_CFLAGS := $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --cflags ocaml-freestanding)
FREESTANDING_CFLAGS := $(shell PKG_CONFIG_PATH="$(PKG_CONFIG_PATH)" pkg-config --cflags ocaml-freestanding)
DISCOVER_CFLAGS := $(shell sed 's/^(\(.*\))$$/\1/' ../ec/cflags_optimized.sexp | tr -d '"')
CFLAGS := -DNDEBUG -O3 -I../ec/native -I../src/native $(DISCOVER_CFLAGS) $(FREESTANDING_CFLAGS)

Expand Down
4 changes: 2 additions & 2 deletions src-freestanding/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ ifneq (, $(shell command -v opam))
PKG_CONFIG_PATH ?= $(shell opam var prefix)/lib/pkgconfig
endif

EXISTS := $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --exists ocaml-freestanding; echo $$?)
EXISTS := $(shell PKG_CONFIG_PATH="$(PKG_CONFIG_PATH)" pkg-config --exists ocaml-freestanding; echo $$?)

.PHONY: all clean
all: libmirage_crypto_freestanding_stubs.a
Expand All @@ -12,7 +12,7 @@ libmirage_crypto_freestanding_stubs.a:
touch $@
else
CC ?= cc
FREESTANDING_CFLAGS := $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --cflags ocaml-freestanding)
FREESTANDING_CFLAGS := $(shell PKG_CONFIG_PATH="$(PKG_CONFIG_PATH)" pkg-config --cflags ocaml-freestanding)
MIRAGE_CRYPTO_OPT_CFLAGS := $(shell sed 's/^(\(.*\))$$/\1/' ../src/cflags_optimized.sexp | tr -d '"')
CFLAGS := -I../src/native $(MIRAGE_CRYPTO_OPT_CFLAGS) $(FREESTANDING_CFLAGS)

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 @@ -22,6 +22,22 @@
#endif
#endif /* __i386__ || __x86_64__ */

#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 @@ -119,7 +135,7 @@ static inline uint64_t getticks(void)


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
2 changes: 1 addition & 1 deletion src/native/ghash_ctmul.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#include "mirage_crypto.h"
#include <string.h>

#if defined (__i386__) || defined (__arm__)
#if defined (__i386__) || defined (__arm__) || 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
19 changes: 15 additions & 4 deletions src/native/mirage_crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
#include <caml/bigarray.h>

#ifdef ACCELERATE
#include <x86intrin.h>
# ifdef _MSC_VER
# include <intrin.h>
# else
# include <x86intrin.h>
# endif
#define __mc_ACCELERATE__
#define __mc_detect_features__
#endif
Expand Down Expand Up @@ -47,16 +51,23 @@ extern struct _mc_cpu_features mc_detected_cpu_features;

#endif /* __mc_ACCELERATE__ */

#if defined (__x86_64__) || defined (__aarch64__) || defined (__powerpc64__) || (64 == __riscv_xlen) || defined (__s390x__)
#if defined (__x86_64__) || defined (__aarch64__) || defined (__powerpc64__) || (64 == __riscv_xlen) || defined (__s390x__) || (1 == _WIN64)
#define ARCH_64BIT
#elif defined (__i386__) || defined (__arm__) || (32 == __riscv_xlen)
#elif defined (__i386__) || defined (__arm__) || (32 == __riscv_xlen) || (1 == _WIN32)
#define ARCH_32BIT
#else
#error "unsupported platform"
#endif

#ifndef __unused
#define __unused(x) x __attribute__((unused))
# if defined(_MSC_VER) && _MSC_VER >= 1500
# define __unused(x) __pragma( warning (push) ) \
__pragma( warning (disable:4189 ) ) \
x \
__pragma( warning (pop))
# else
# define __unused(x) x __attribute__((unused))
# endif
#endif
#define __unit() value __unused(_)

Expand Down
5 changes: 4 additions & 1 deletion src/native/poly1305-donna.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ typedef struct poly1305_context {
unsigned char opaque[136];
} poly1305_context;

#ifdef ARCH_64BIT
/* 64-bit Windows sets ARCH_64BIT but poly1305-donna-64 requires 128-bit integers
* that are not supported by the Microsoft compiler. Drop down to 32-bit for MSVC.
*/
#if defined(ARCH_64BIT) && !defined(_MSC_VER)
#include "poly1305-donna-64.h"
#else
#include "poly1305-donna-32.h"
Expand Down

0 comments on commit 72eaf04

Please sign in to comment.