diff options
Diffstat (limited to 'runtime/src/z_Linux_asm.S')
-rw-r--r-- | runtime/src/z_Linux_asm.S | 263 |
1 files changed, 235 insertions, 28 deletions
diff --git a/runtime/src/z_Linux_asm.S b/runtime/src/z_Linux_asm.S index 0d8885eca1c74..b491fcf186aaa 100644 --- a/runtime/src/z_Linux_asm.S +++ b/runtime/src/z_Linux_asm.S @@ -495,13 +495,21 @@ __kmp_unnamed_critical_addr: # endif /* !KMP_ASM_INTRINS */ //------------------------------------------------------------------------ -// typedef void (*microtask_t)( int *gtid, int *tid, ... ); -// // int -// __kmp_invoke_microtask( microtask_t pkfn, int gtid, int tid, -// int argc, void *p_argv[] ) { -// (*pkfn)( & gtid, & gtid, argv[0], ... ); -// return 1; +// __kmp_invoke_microtask( void (*pkfn) (int gtid, int tid, ...), +// int gtid, int tid, +// int argc, void *p_argv[] +// #if OMPT_SUPPORT +// , +// void **exit_frame_ptr +// #endif +// ) { +// #if OMPT_SUPPORT +// *exit_frame_ptr = OMPT_GET_FRAME_ADDRESS(0); +// #endif +// +// (*pkfn)( & gtid, & tid, argv[0], ... ); +// return 1; // } // -- Begin __kmp_invoke_microtask @@ -991,14 +999,21 @@ KMP_LABEL(invoke_3): # endif /* !KMP_ASM_INTRINS */ //------------------------------------------------------------------------ -// typedef void (*microtask_t)( int *gtid, int *tid, ... ); -// // int // __kmp_invoke_microtask( void (*pkfn) (int gtid, int tid, ...), -// int gtid, int tid, -// int argc, void *p_argv[] ) { -// (*pkfn)( & gtid, & tid, argv[0], ... ); -// return 1; +// int gtid, int tid, +// int argc, void *p_argv[] +// #if OMPT_SUPPORT +// , +// void **exit_frame_ptr +// #endif +// ) { +// #if OMPT_SUPPORT +// *exit_frame_ptr = OMPT_GET_FRAME_ADDRESS(0); +// #endif +// +// (*pkfn)( & gtid, & tid, argv[0], ... ); +// return 1; // } // // note: at call to pkfn must have %rsp 128-byte aligned for compiler @@ -1192,15 +1207,27 @@ KMP_LABEL(kmp_1_exit): #if (KMP_OS_LINUX || KMP_OS_DARWIN) && KMP_ARCH_AARCH64 //------------------------------------------------------------------------ -// -// typedef void (*microtask_t)( int *gtid, int *tid, ... ); -// // int // __kmp_invoke_microtask( void (*pkfn) (int gtid, int tid, ...), -// int gtid, int tid, -// int argc, void *p_argv[] ) { -// (*pkfn)( & gtid, & tid, argv[0], ... ); -// return 1; +// int gtid, int tid, +// int argc, void *p_argv[] +// #if OMPT_SUPPORT +// , +// void **exit_frame_ptr +// #endif +// ) { +// #if OMPT_SUPPORT +// *exit_frame_ptr = OMPT_GET_FRAME_ADDRESS(0); +// #endif +// +// (*pkfn)( & gtid, & tid, argv[0], ... ); +// +// // FIXME: This is done at call-site and can be removed here. +// #if OMPT_SUPPORT +// *exit_frame_ptr = 0; +// #endif +// +// return 1; // } // // parameters: @@ -1306,15 +1333,27 @@ KMP_LABEL(kmp_1): #if KMP_ARCH_PPC64 //------------------------------------------------------------------------ -// -// typedef void (*microtask_t)( int *gtid, int *tid, ... ); -// // int // __kmp_invoke_microtask( void (*pkfn) (int gtid, int tid, ...), -// int gtid, int tid, -// int argc, void *p_argv[] ) { -// (*pkfn)( & gtid, & tid, argv[0], ... ); -// return 1; +// int gtid, int tid, +// int argc, void *p_argv[] +// #if OMPT_SUPPORT +// , +// void **exit_frame_ptr +// #endif +// ) { +// #if OMPT_SUPPORT +// *exit_frame_ptr = OMPT_GET_FRAME_ADDRESS(0); +// #endif +// +// (*pkfn)( & gtid, & tid, argv[0], ... ); +// +// // FIXME: This is done at call-site and can be removed here. +// #if OMPT_SUPPORT +// *exit_frame_ptr = 0; +// #endif +// +// return 1; // } // // parameters: @@ -1524,6 +1563,173 @@ __kmp_invoke_microtask: #endif /* KMP_ARCH_PPC64 */ +#if KMP_ARCH_RISCV64 + +//------------------------------------------------------------------------ +// +// typedef void (*microtask_t)(int *gtid, int *tid, ...); +// +// int __kmp_invoke_microtask(microtask_t pkfn, int gtid, int tid, int argc, +// void *p_argv[] +// #if OMPT_SUPPORT +// , +// void **exit_frame_ptr +// #endif +// ) { +// #if OMPT_SUPPORT +// *exit_frame_ptr = OMPT_GET_FRAME_ADDRESS(0); +// #endif +// +// (*pkfn)(>id, &tid, argv[0], ...); +// +// return 1; +// } +// +// Parameters: +// a0: pkfn +// a1: gtid +// a2: tid +// a3: argc +// a4: p_argv +// a5: exit_frame_ptr +// +// Locals: +// __gtid: gtid param pushed on stack so can pass >id to pkfn +// __tid: tid param pushed on stack so can pass &tid to pkfn +// +// Temp. registers: +// +// t0: used to calculate the dynamic stack size / used to hold pkfn address +// t1: used as temporary for stack placement calculation +// t2: used as temporary for stack arguments +// t3: used as temporary for number of remaining pkfn parms +// t4: used to traverse p_argv array +// +// return: a0 (always 1/TRUE) +// + +__gtid = -20 +__tid = -24 + +// -- Begin __kmp_invoke_microtask +// mark_begin; + .text + .globl __kmp_invoke_microtask + .p2align 1 + .type __kmp_invoke_microtask,@function +__kmp_invoke_microtask: + .cfi_startproc + + // First, save ra and fp + addi sp, sp, -16 + sd ra, 8(sp) + sd fp, 0(sp) + addi fp, sp, 16 + .cfi_def_cfa fp, 0 + .cfi_offset ra, -8 + .cfi_offset fp, -16 + + // Compute the dynamic stack size: + // + // - We need 8 bytes for storing 'gtid' and 'tid', so we can pass them by + // reference + // - We need 8 bytes for each argument that cannot be passed to the 'pkfn' + // function by register. Given that we have 8 of such registers (a[0-7]) + // and two + 'argc' arguments (consider >id and &tid), we need to + // reserve max(0, argc - 6)*8 extra bytes + // + // The total number of bytes is then max(0, argc - 6)*8 + 8 + + // Compute max(0, argc - 6) using the following bithack: + // max(0, x) = x - (x & (x >> 31)), where x := argc - 6 + // Source: http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax + addi t0, a3, -6 + srai t1, t0, 31 + and t1, t0, t1 + sub t0, t0, t1 + + addi t0, t0, 1 + + slli t0, t0, 3 + sub sp, sp, t0 + + // Align the stack to 16 bytes + andi sp, sp, -16 + + mv t0, a0 + mv t3, a3 + mv t4, a4 + +#if OMPT_SUPPORT + // Save frame pointer into exit_frame + sd fp, 0(a5) +#endif + + // Prepare arguments for the pkfn function (first 8 using a0-a7 registers) + + sw a1, __gtid(fp) + sw a2, __tid(fp) + + addi a0, fp, __gtid + addi a1, fp, __tid + + beqz t3, .L_kmp_3 + ld a2, 0(t4) + + addi t3, t3, -1 + beqz t3, .L_kmp_3 + ld a3, 8(t4) + + addi t3, t3, -1 + beqz t3, .L_kmp_3 + ld a4, 16(t4) + + addi t3, t3, -1 + beqz t3, .L_kmp_3 + ld a5, 24(t4) + + addi t3, t3, -1 + beqz t3, .L_kmp_3 + ld a6, 32(t4) + + addi t3, t3, -1 + beqz t3, .L_kmp_3 + ld a7, 40(t4) + + // Prepare any additional argument passed through the stack + addi t4, t4, 48 + mv t1, sp + j .L_kmp_2 +.L_kmp_1: + ld t2, 0(t4) + sd t2, 0(t1) + addi t4, t4, 8 + addi t1, t1, 8 +.L_kmp_2: + addi t3, t3, -1 + bnez t3, .L_kmp_1 + +.L_kmp_3: + // Call pkfn function + jalr t0 + + // Restore stack and return + + addi a0, zero, 1 + + addi sp, fp, -16 + ld fp, 0(sp) + ld ra, 8(sp) + addi sp, sp, 16 + ret +.Lfunc_end0: + .size __kmp_invoke_microtask, .Lfunc_end0-__kmp_invoke_microtask + .cfi_endproc + +// -- End __kmp_invoke_microtask + +#endif /* KMP_ARCH_RISCV64 */ + #if KMP_ARCH_ARM || KMP_ARCH_MIPS .data .comm .gomp_critical_user_,32,8 @@ -1535,7 +1741,7 @@ __kmp_unnamed_critical_addr: .size __kmp_unnamed_critical_addr,4 #endif /* KMP_ARCH_ARM */ -#if KMP_ARCH_PPC64 || KMP_ARCH_AARCH64 || KMP_ARCH_MIPS64 +#if KMP_ARCH_PPC64 || KMP_ARCH_AARCH64 || KMP_ARCH_MIPS64 || KMP_ARCH_RISCV64 .data .comm .gomp_critical_user_,32,8 .data @@ -1544,7 +1750,8 @@ __kmp_unnamed_critical_addr: __kmp_unnamed_critical_addr: .8byte .gomp_critical_user_ .size __kmp_unnamed_critical_addr,8 -#endif /* KMP_ARCH_PPC64 || KMP_ARCH_AARCH64 */ +#endif /* KMP_ARCH_PPC64 || KMP_ARCH_AARCH64 || KMP_ARCH_MIPS64 || + KMP_ARCH_RISCV64 */ #if KMP_OS_LINUX # if KMP_ARCH_ARM |