Skip to content

Commit 398fc96

Browse files
Fix Windows ARM64EC build issues and correct SIMD ARM NEON path
1 parent ee4aed0 commit 398fc96

9 files changed

Lines changed: 81 additions & 27 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,4 @@ __pycache__/
6464
# Ignore Bazel generated files
6565
bazel-*
6666
MODULE.bazel.lock
67+
*.vsidx

external/OpenJPH/src/core/openjph/ojph_arch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
// preprocessor directives for architecture
6868
///////////////////////////////////////////////////////////////////////////////
6969
#if defined(__arm__) || defined(__TARGET_ARCH_ARM) \
70-
|| defined(__aarch64__) || defined(_M_ARM64)
70+
|| defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
7171
#define OJPH_ARCH_ARM
7272
#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
7373
#define OJPH_ARCH_I386

external/OpenJPH/src/core/others/ojph_arch.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ namespace ojph {
170170

171171
#else // Linux/FreeBSD/OpenBSD
172172

173-
#if defined(__aarch64__) || defined(_M_ARM64) // 64-bit ARM
173+
#if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC) // 64-bit ARM
174174

175175
#include <sys/auxv.h>
176176
#ifdef OJPH_OS_LINUX

src/lib/OpenEXR/ImfSimd.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313
//
1414

1515
// GCC and Visual Studio SSE2 compiler flags
16-
#if defined __SSE2__ || (_MSC_VER && (_M_IX86 || _M_X64))
16+
#if defined __SSE2__ || (_MSC_VER && (_M_IX86 || _M_X64) && !defined(_M_ARM64EC))
1717
# define IMF_HAVE_SSE2 1
1818
#endif
1919

20-
#if defined __SSE4_1__ || (_MSC_VER && (_M_IX86 || _M_X64))
20+
#if defined __SSE4_1__ || (_MSC_VER && (_M_IX86 || _M_X64) && !defined(_M_ARM64EC))
2121
# define IMF_HAVE_SSE4_1 1
2222
#endif
2323

@@ -42,14 +42,22 @@
4242
# define IMF_HAVE_F16C 1
4343
#endif
4444

45-
#if defined(__ARM_NEON)
45+
#if defined(__ARM_NEON) || defined(_M_ARM64) || defined(_M_ARM64EC)
4646
# define IMF_HAVE_NEON
4747
#endif
4848

4949
#if defined(__aarch64__)
5050
# define IMF_HAVE_NEON_AARCH64 1
5151
#endif
5252

53+
#if defined(_M_ARM64) || defined(_M_ARM64EC)
54+
# define IMF_HAVE_NEON_WINDOWS_ARM64 1
55+
#endif
56+
57+
#if defined(IMF_HAVE_NEON_AARCH64) || defined(IMF_HAVE_NEON_WINDOWS_ARM64)
58+
# define IMF_HAVE_NEON_ARM64 1
59+
#endif
60+
5361
extern "C" {
5462
#ifdef IMF_HAVE_SSE2
5563
# include <emmintrin.h>

src/lib/OpenEXR/ImfZip.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ reconstruct_sse41 (char* buf, size_t outSize)
157157

158158
#endif
159159

160-
#ifdef IMF_HAVE_NEON_AARCH64
160+
#ifdef IMF_HAVE_NEON_ARM64
161161

162162
void
163163
reconstruct_neon (char* buf, size_t outSize)
@@ -258,7 +258,7 @@ interleave_sse2 (const char* source, size_t outSize, char* out)
258258

259259
#endif
260260

261-
#ifdef IMF_HAVE_NEON_AARCH64
261+
#ifdef IMF_HAVE_NEON_ARM64
262262

263263
void
264264
interleave_neon (const char* source, size_t outSize, char* out)
@@ -370,7 +370,7 @@ Zip::initializeFuncs ()
370370
if (cpuId.sse2) { interleave = interleave_sse2; }
371371
#endif
372372

373-
#ifdef IMF_HAVE_NEON_AARCH64
373+
#ifdef IMF_HAVE_NEON_ARM64
374374
reconstruct = reconstruct_neon;
375375
interleave = interleave_neon;
376376
#endif

src/lib/OpenEXRCore/internal_cpuid.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include "OpenEXRConfigInternal.h"
1010

1111
#if defined(i386) || defined(__i386__) || defined(__i386) || \
12-
defined(_M_X86) || defined(__x86_64__) || defined(_M_X64)
12+
defined(_M_X86) || defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC))
1313
# define OPENEXR_ENABLE_X86_SIMD_CHECK 1
1414
#else
1515
# define OPENEXR_ENABLE_X86_SIMD_CHECK 0
@@ -132,7 +132,7 @@ has_native_half (void)
132132
int sse2, avx, f16c;
133133
check_for_x86_simd (&f16c, &avx, &sse2);
134134
return avx && f16c;
135-
#elif defined(__aarch64__)
135+
#elif defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
136136
return 1;
137137
#else
138138
return 0;

src/lib/OpenEXRCore/internal_dwa_simd.h

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
// aligned. Unaligned pointers may risk seg-faulting.
1919
//
2020

21-
#if defined __SSE2__ || (_MSC_VER && (_M_IX86 || _M_X64))
21+
#if defined __SSE2__ || (_MSC_VER && (_M_IX86 || _M_X64) && !defined(_M_ARM64EC))
2222
# define IMF_HAVE_SSE2 1
2323
# include <emmintrin.h>
2424
# include <mmintrin.h>
@@ -35,6 +35,22 @@
3535
# define IMF_HAVE_NEON_AARCH64 1
3636
#endif
3737

38+
#if defined(_M_ARM64) || defined(_M_ARM64EC)
39+
# define IMF_HAVE_NEON_WINDOWS_ARM64 1
40+
#endif
41+
42+
#if defined(IMF_HAVE_NEON_AARCH64) || defined(IMF_HAVE_NEON_WINDOWS_ARM64)
43+
# define IMF_HAVE_NEON_ARM64 1
44+
#endif
45+
46+
#if defined(IMF_HAVE_NEON_ARM64)
47+
# if defined(_MSC_VER)
48+
# define NEON_RESTRICT __restrict
49+
# else
50+
# define NEON_RESTRICT __restrict__
51+
# endif
52+
#endif
53+
3854
#include "internal_coding.h"
3955

4056
#if defined(OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX) && \
@@ -357,7 +373,7 @@ convertFloatToHalf64_scalar (uint16_t* dst, float* src)
357373
dst[i] = float_to_half (src[i]);
358374
}
359375

360-
#ifdef IMF_HAVE_NEON_AARCH64
376+
#ifdef IMF_HAVE_NEON_ARM64
361377

362378
void
363379
convertFloatToHalf64_neon (uint16_t* dst, float* src)
@@ -786,36 +802,50 @@ fromHalfZigZag_f16c (uint16_t* src, float* dst)
786802
#endif /* defined IMF_HAVE_GCC_INLINEASM_X86_64 */
787803
}
788804

789-
#ifdef IMF_HAVE_NEON_AARCH64
805+
#ifdef IMF_HAVE_NEON_ARM64
790806

791807
void
792-
fromHalfZigZag_neon (uint16_t* __restrict__ src, float* __restrict__ dst)
808+
fromHalfZigZag_neon (uint16_t* NEON_RESTRICT src, float* NEON_RESTRICT dst)
793809
{
810+
# if defined(_MSC_VER)
811+
static const uint8_t res_tbl_data[4][16] = {
812+
{0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42},
813+
{3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53},
814+
{10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60},
815+
{21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63}};
816+
817+
uint8x16_t res_tbl[4];
818+
for (int i = 0; i < 4; i++)
819+
{
820+
res_tbl[i] = vld1q_u8 (res_tbl_data[i]);
821+
}
822+
823+
# else
794824
uint8x16_t res_tbl[4] = {
795825
{0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42},
796826
{3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53},
797827
{10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60},
798828
{21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63}};
829+
# endif
799830

800831
uint8x16x4_t vec_input_l, vec_input_h;
801-
802832
for (int i = 0; i < 4; i++)
803833
{
804834
uint8x16x2_t vec_in_u8 = vld2q_u8 ((uint8_t*) (src + 16 * i));
805835
vec_input_l.val[i] = vec_in_u8.val[0];
806836
vec_input_h.val[i] = vec_in_u8.val[1];
807837
}
808-
809838
# pragma unroll(4)
810839
for (int i = 0; i < 4; i++)
811840
{
812-
uint8x16_t res_vec_l, res_vec_h;
813-
res_vec_l = vqtbl4q_u8 (vec_input_l, res_tbl[i]);
814-
res_vec_h = vqtbl4q_u8 (vec_input_h, res_tbl[i]);
841+
uint8x16_t res_vec_l = vqtbl4q_u8 (vec_input_l, res_tbl[i]);
842+
uint8x16_t res_vec_h = vqtbl4q_u8 (vec_input_h, res_tbl[i]);
843+
815844
float16x8_t res_vec_l_f16 =
816845
vreinterpretq_f16_u8 (vzip1q_u8 (res_vec_l, res_vec_h));
817846
float16x8_t res_vec_h_f16 =
818847
vreinterpretq_f16_u8 (vzip2q_u8 (res_vec_l, res_vec_h));
848+
819849
vst1q_f32 (dst + i * 16, vcvt_f32_f16 (vget_low_f16 (res_vec_l_f16)));
820850
vst1q_f32 (dst + i * 16 + 4, vcvt_high_f32_f16 (res_vec_l_f16));
821851
vst1q_f32 (
@@ -824,7 +854,7 @@ fromHalfZigZag_neon (uint16_t* __restrict__ src, float* __restrict__ dst)
824854
}
825855
}
826856

827-
#endif // IMF_HAVE_NEON_AARCH64
857+
#endif //IMF_HAVE_NEON_ARM64
828858

829859
//
830860
// Inverse 8x8 DCT, only inverting the DC. This assumes that
@@ -2315,7 +2345,7 @@ initializeFuncs (void)
23152345
if (done) return;
23162346
done = 1;
23172347

2318-
#ifdef IMF_HAVE_NEON_AARCH64
2348+
#ifdef IMF_HAVE_NEON_ARM64
23192349
{
23202350
convertFloatToHalf64 = convertFloatToHalf64_neon;
23212351
fromHalfZigZag = fromHalfZigZag_neon;

src/lib/OpenEXRCore/internal_zip.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,33 @@
1515

1616
#include "openexr_compression.h"
1717

18-
#if defined __SSE2__ || (_MSC_VER >= 1300 && (_M_IX86 || _M_X64))
18+
#if defined __SSE2__ || (_MSC_VER >= 1300 && (_M_IX86 || _M_X64) && !defined(_M_ARM64EC))
1919
# define IMF_HAVE_SSE2 1
2020
# include <emmintrin.h>
2121
# include <mmintrin.h>
2222
#endif
23-
#if defined __SSE4_1__ || (_MSC_VER >= 1300 && (_M_IX86 || _M_X64))
23+
#if defined __SSE4_1__ || (_MSC_VER >= 1300 && (_M_IX86 || _M_X64) && !defined(_M_ARM64EC))
2424
# define IMF_HAVE_SSE4_1 1
2525
# include <smmintrin.h>
2626
#endif
2727
#if defined(__aarch64__)
2828
# define IMF_HAVE_NEON_AARCH64 1
29-
# include <arm_neon.h>
29+
#endif
30+
31+
#if defined(_M_ARM64) || defined(_M_ARM64EC)
32+
# define IMF_HAVE_NEON_WINDOWS_ARM64 1
33+
#endif
34+
35+
#if defined(IMF_HAVE_NEON_AARCH64) || defined(IMF_HAVE_NEON_WINDOWS_ARM64)
36+
# define IMF_HAVE_NEON_ARM64 1
37+
#endif
38+
39+
#if defined(IMF_HAVE_NEON_ARM64)
40+
# if defined(_MSC_VER)
41+
# include <arm64_neon.h>
42+
# else
43+
# include <arm_neon.h>
44+
# endif
3045
#endif
3146

3247
/**************************************/
@@ -77,7 +92,7 @@ reconstruct (uint8_t* buf, const uint64_t outSize)
7792
prev = d;
7893
}
7994
}
80-
#elif defined(IMF_HAVE_NEON_AARCH64)
95+
#elif defined(IMF_HAVE_NEON_ARM64)
8196
static void
8297
reconstruct (uint8_t* buf, const uint64_t outSize)
8398
{
@@ -174,7 +189,7 @@ interleave (uint8_t* out, const uint8_t* const source, const uint64_t outSize)
174189
*(sOut++) = (i % 2 == 0) ? *(t1++) : *(t2++);
175190
}
176191

177-
#elif defined(IMF_HAVE_NEON_AARCH64)
192+
#elif defined(IMF_HAVE_NEON_ARM64)
178193
static void
179194
interleave (uint8_t* out, const uint8_t* const source, const uint64_t outSize)
180195
{

src/test/OpenEXRCoreTest/base_units.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ testCPUIdent (const std::string& tempdir)
396396
EXRCORE_TEST (false);
397397
}
398398

399-
#if defined(__x86_64__) || defined(_M_X64)
399+
#if defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC))
400400
if (has_native_half () != (hf16c && havx))
401401
{
402402
std::cerr << "CPU Id test has native half mismatch" << std::endl;

0 commit comments

Comments
 (0)