Skip to content

Commit 83e12ad

Browse files
committed
[openmp] Add initial ARM64EC support
Treat ARM64EC as an AArch64 target for the most part. Since the vararg calling convention differs, add a dedicated implementation based on the AArch64 variant. The differences include: - Only the first four parameters are passed via registers - x4 contains a pointer to the first stack argument - x5 contains the size of arguments passed via the stack - The call is preceded by a call to __os_arm64x_check_icall, which optionally sets up an indirect call via an exit thunk if the target is x86_64 code
1 parent a7aca81 commit 83e12ad

File tree

3 files changed

+109
-6
lines changed

3 files changed

+109
-6
lines changed

openmp/runtime/cmake/LibompGetArchitecture.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ function(libomp_get_architecture return_arch)
1717
set(detect_arch_src_txt "
1818
#if defined(__KNC__)
1919
#error ARCHITECTURE=mic
20+
#elif defined(__aarch64__) || defined(_M_ARM64) || defined(__arm64ec__) || defined(_M_ARM64EC)
21+
#error ARCHITECTURE=aarch64
2022
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
2123
#error ARCHITECTURE=x86_64
2224
#elif defined(__i386) || defined(__i386__) || defined(__IA32__) || defined(_M_I86) || defined(_M_IX86) || defined(__X86__) || defined(_X86_)
@@ -37,8 +39,6 @@ function(libomp_get_architecture return_arch)
3739
#error ARCHITECTURE=arm
3840
#elif defined(__ARM64_ARCH_8_32__)
3941
#error ARCHITECTURE=aarch64_32
40-
#elif defined(__aarch64__) || defined(_M_ARM64)
41-
#error ARCHITECTURE=aarch64
4242
#elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__)
4343
#error ARCHITECTURE=ppc64le
4444
#elif defined(__powerpc64__)

openmp/runtime/src/kmp_platform.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,15 +132,15 @@
132132
#define KMP_ARCH_SPARC 0
133133

134134
#if KMP_OS_WINDOWS
135-
#if defined(_M_AMD64) || defined(__x86_64)
136-
#undef KMP_ARCH_X86_64
137-
#define KMP_ARCH_X86_64 1
138-
#elif defined(__aarch64__) || defined(_M_ARM64)
135+
#if defined(__aarch64__) || defined(_M_ARM64) || defined(__arm64ec__) || defined(_M_ARM64EC)
139136
#undef KMP_ARCH_AARCH64
140137
#define KMP_ARCH_AARCH64 1
141138
#elif defined(__arm__) || defined(_M_ARM)
142139
#undef KMP_ARCH_ARMV7
143140
#define KMP_ARCH_ARMV7 1
141+
#elif defined(_M_AMD64) || defined(__x86_64)
142+
#undef KMP_ARCH_X86_64
143+
#define KMP_ARCH_X86_64 1
144144
#else
145145
#undef KMP_ARCH_X86
146146
#define KMP_ARCH_X86 1

openmp/runtime/src/z_Linux_asm.S

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ KMP_PREFIX_UNDERSCORE($0):
159159
.globl KMP_PREFIX_UNDERSCORE(\proc)
160160
KMP_PREFIX_UNDERSCORE(\proc):
161161
.endm
162+
162163
# else // KMP_OS_DARWIN || KMP_OS_WINDOWS
163164
# define KMP_PREFIX_UNDERSCORE(x) x // no extra underscore for Linux* OS symbols
164165
// Format labels so that they don't override function names in gdb's backtraces
@@ -1301,6 +1302,106 @@ KMP_LABEL(kmp_no_args):
13011302
// '
13021303
#if (KMP_OS_LINUX || KMP_OS_DARWIN || KMP_OS_WINDOWS) && (KMP_ARCH_AARCH64 || KMP_ARCH_AARCH64_32)
13031304

1305+
#ifdef __arm64ec__
1306+
1307+
//------------------------------------------------------------------------
1308+
// int
1309+
// __kmp_invoke_microtask( void (*pkfn) (int gtid, int tid, ...),
1310+
// int gtid, int tid,
1311+
// int argc, void *p_argv[]) {
1312+
// (*pkfn)( & gtid, & tid, argv[0], ... );
1313+
// return 1;
1314+
// }
1315+
//
1316+
// parameters:
1317+
// x0: pkfn
1318+
// w1: gtid
1319+
// w2: tid
1320+
// w3: argc
1321+
// x4: p_argv
1322+
//
1323+
// locals:
1324+
// __gtid: gtid parm pushed on stack so can pass &gtid to pkfn
1325+
// __tid: tid parm pushed on stack so can pass &tid to pkfn
1326+
//
1327+
// reg temps:
1328+
// x8: used as temporary for stack placement calculation
1329+
// w9: used as temporary for number of pkfn parms
1330+
// x10: used to traverse p_argv array
1331+
// x11: used to hold pkfn address
1332+
// x12: used as temporary for stack parameters
1333+
// x19: used to preserve exit_frame_ptr, callee-save
1334+
//
1335+
// return: w0 (always 1/TRUE)
1336+
//
1337+
1338+
__gtid = 4
1339+
__tid = 8
1340+
1341+
// -- Begin __kmp_invoke_microtask
1342+
// mark_begin;
1343+
.section .text,"xr",discard,"#__kmp_invoke_microtask"
1344+
.globl "#__kmp_invoke_microtask"
1345+
ALIGN 2
1346+
"#__kmp_invoke_microtask":
1347+
stp x29, x30, [sp, #-16]!
1348+
mov x29, sp
1349+
1350+
mov w9, #1
1351+
add w9, w9, w3, lsr #1
1352+
sub sp, sp, w9, uxtw #4
1353+
mov x8, sp
1354+
1355+
mov x11, x0
1356+
str w1, [x29, #-__gtid]
1357+
str w2, [x29, #-__tid]
1358+
mov w9, w3
1359+
mov x10, x4
1360+
1361+
sub x0, x29, #__gtid
1362+
sub x1, x29, #__tid
1363+
mov x4, sp
1364+
mov w5, #0
1365+
1366+
cbz w9, KMP_LABEL(kmp_1)
1367+
ldr x2, [x10]
1368+
1369+
sub w9, w9, #1
1370+
cbz w9, KMP_LABEL(kmp_1)
1371+
ldr x3, [x10, #8]!
1372+
1373+
sub w5, w9, #1
1374+
lsl w5, w5, #3
1375+
1376+
KMP_LABEL(kmp_0):
1377+
cbz w9, KMP_LABEL(kmp_1)
1378+
ldr x12, [x10, #8]!
1379+
str x12, [x8], #8
1380+
sub w9, w9, #1
1381+
b KMP_LABEL(kmp_0)
1382+
KMP_LABEL(kmp_1):
1383+
adrp x10, $iexit_thunk$cdecl$v$varargs
1384+
add x10, x10, :lo12:$iexit_thunk$cdecl$v$varargs
1385+
adrp x8, __os_arm64x_check_icall
1386+
ldr x8, [x8, :lo12:__os_arm64x_check_icall]
1387+
blr x8
1388+
blr x11
1389+
mov w0, #1
1390+
mov sp, x29
1391+
ldp x29, x30, [sp], #16
1392+
ret
1393+
1394+
.weak_anti_dep __kmp_invoke_microtask
1395+
.set __kmp_invoke_microtask, "#__kmp_invoke_microtask"
1396+
1397+
.section .hybmp$x,"yi"
1398+
.symidx "#__kmp_invoke_microtask"
1399+
.symidx $ientry_thunk$cdecl$i8$i8i8i8i8i8
1400+
.word 1
1401+
// -- End __kmp_invoke_microtask
1402+
1403+
#else
1404+
13041405
//------------------------------------------------------------------------
13051406
// int
13061407
// __kmp_invoke_microtask( void (*pkfn) (int gtid, int tid, ...),
@@ -1425,6 +1526,8 @@ KMP_LABEL(kmp_1):
14251526
DEBUG_INFO __kmp_invoke_microtask
14261527
// -- End __kmp_invoke_microtask
14271528

1529+
#endif
1530+
14281531
#endif /* (KMP_OS_LINUX || KMP_OS_DARWIN || KMP_OS_WINDOWS) && (KMP_ARCH_AARCH64 || KMP_ARCH_AARCH64_32) */
14291532

14301533
#if (KMP_OS_LINUX || KMP_OS_DARWIN || KMP_OS_WINDOWS) && KMP_ARCH_ARM

0 commit comments

Comments
 (0)