brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.5 KiB · 4352079 Raw
411 lines · plain
1//  z_AIX_asm.S:  - microtasking routines specifically2//                  written for Power platforms running AIX OS3 4//5////===----------------------------------------------------------------------===//6////7//// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.8//// See https://llvm.org/LICENSE.txt for license information.9//// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception10////11////===----------------------------------------------------------------------===//12//13 14// -----------------------------------------------------------------------15// macros16// -----------------------------------------------------------------------17 18#include "kmp_config.h"19 20#if KMP_OS_AIX21//------------------------------------------------------------------------22// int23// __kmp_invoke_microtask( void (*pkfn) (int *gtid, int *tid, ...),24//                         int gtid, int tid,25//                         int argc, void *p_argv[]26// #if OMPT_SUPPORT27//                         ,28//                         void **exit_frame_ptr29// #endif30//                       ) {31// #if OMPT_SUPPORT32//   *exit_frame_ptr = OMPT_GET_FRAME_ADDRESS(0);33// #endif34//35//   (*pkfn)( & gtid, & tid, p_argv[0], ... );36//37// // FIXME: This is done at call-site and can be removed here.38// #if OMPT_SUPPORT39//   *exit_frame_ptr = 0;40// #endif41//42//   return 1;43// }44//45// parameters:46//   r3: pkfn47//   r4: gtid48//   r5: tid49//   r6: argc50//   r7: p_argv51//   r8: &exit_frame52//53// return:  r3 (always 1/TRUE)54//55 56#if KMP_ARCH_PPC64_XCOFF57 58    .globl  __kmp_invoke_microtask[DS]59    .globl  .__kmp_invoke_microtask60    .align  461    .csect __kmp_invoke_microtask[DS],362    .vbyte  8, .__kmp_invoke_microtask63    .vbyte  8, TOC[TC0]64    .vbyte  8, 065    .csect .text[PR],266    .machine "pwr7"67.__kmp_invoke_microtask:68 69 70// -- Begin __kmp_invoke_microtask71// mark_begin;72 73// We need to allocate a stack frame large enough to hold all of the parameters74// on the stack for the microtask plus what this function needs. That's 4875// bytes under the XCOFF64 ABI, plus max(64, 8*(2 + argc)) for76// the parameters to the microtask (gtid, tid, argc elements of p_argv),77// plus 8 bytes to store the values of r4 and r5, and 8 bytes to store r31.78// With OMP-T support, we need an additional 8 bytes to save r30 to hold79// a copy of r8.80// Stack offsets relative to stack pointer:81//   r31: -8, r30: -16, gtid: -20, tid: -2482 83    mflr 084    std 31, -8(1)      # Save r31 to the stack85    std 0, 16(1)       # Save LR to the linkage area86 87// This is unusual because normally we'd set r31 equal to r1 after the stack88// frame is established. In this case, however, we need to dynamically compute89// the stack frame size, and so we keep a direct copy of r1 to access our90// register save areas and restore the r1 value before returning.91    mr 31, 192 93// Compute the size of the "argc" portion of the parameter save area.94// The parameter save area is always at least 64 bytes long (i.e. 8 regs)95// The microtask has (2 + argc) parameters, so if argc <= 6, we need to96// to allocate 8*6 bytes, not 8*argc.97    li 0, 698    cmpwi 0, 6, 699    iselgt 0, 6, 0     # r0 = (argc > 6)? argc : 6100    sldi 0, 0, 3       # r0 = 8 * max(argc, 6)101 102// Compute the size necessary for the local stack frame.103// 88 = 48 + 4 (for r4) + 4 (for r5) + 8 (for r31) + 8 (for OMP-T r30) +104//      8 (parameter gtid) + 8 (parameter tid)105    li 12, 88106    add 12, 0, 12107    neg 12, 12108 109// We need to make sure that the stack frame stays aligned (to 16 bytes).110    li 0, -16111    and 12, 0, 12112 113// Establish the local stack frame.114    stdux 1, 1, 12115 116#if OMPT_SUPPORT117    std 30, -16(31)    # Save r30 to the stack118    std 1, 0(8)119    mr 30, 8120#endif121 122// Store gtid and tid to the stack because they're passed by reference to the microtask.123    stw 4, -20(31)     # Save gtid to the stack124    stw 5, -24(31)     # Save tid to the stack125 126    mr 12, 6           # r12 = argc127    mr 4, 7            # r4 = p_argv128 129    cmpwi 0, 12, 1130    blt 0, .Lcall      # if (argc < 1) goto .Lcall131 132    ld 5, 0(4)         # r5 = p_argv[0]133 134    cmpwi 0, 12, 2135    blt 0, .Lcall      # if (argc < 2) goto .Lcall136 137    ld 6, 8(4)         # r6 = p_argv[1]138 139    cmpwi 0, 12, 3140    blt 0, .Lcall      # if (argc < 3) goto .Lcall141 142    ld 7, 16(4)        # r7 = p_argv[2]143 144    cmpwi 0, 12, 4145    blt 0, .Lcall      # if (argc < 4) goto .Lcall146 147    ld 8, 24(4)        # r8 = p_argv[3]148 149    cmpwi 0, 12, 5150    blt 0, .Lcall      # if (argc < 5) goto .Lcall151 152    ld 9, 32(4)        # r9 = p_argv[4]153 154    cmpwi 0, 12, 6155    blt 0, .Lcall      # if (argc < 6) goto .Lcall156 157    ld 10, 40(4)       # r10 = p_argv[5]158 159    cmpwi 0, 12, 7160    blt 0, .Lcall      # if (argc < 7) goto .Lcall161 162// There are more than 6 microtask parameters, so we need to store the163// remainder to the stack.164    addi 12, 12, -6    # argc -= 6165    mtctr 12166 167// These are set to 8 bytes before the first desired store address (we're using168// pre-increment loads and stores in the loop below). The parameter save area169// for the microtask begins 48 + 8*8 == 112 bytes above r1 for XCOFF64.170    addi 4, 4, 40      # p_argv = p_argv + 5171                       # (i.e. skip the 5 elements we already processed)172    addi 12, 1, 104    # r12 = stack offset (112 - 8)173 174.Lnext:175    ldu 0, 8(4)176    stdu 0, 8(12)177    bdnz .Lnext178 179.Lcall:180    std 2, 40(1)     # Save the TOC pointer to the linkage area181// Load the actual function address from the function descriptor.182    ld 12, 0(3)      # Function address183    ld 2, 8(3)       # TOC pointer184    ld 11, 16(3)     # Environment pointer185 186    addi 3, 31, -20  # r3 = &gtid187    addi 4, 31, -24  # r4 = &tid188 189    mtctr 12         # CTR = function address190    bctrl            # Branch to CTR191    ld 2, 40(1)      # Restore TOC pointer from linkage area192 193#if OMPT_SUPPORT194    li 3, 0195    std 3, 0(30)196#endif197 198    li 3, 1199 200#if OMPT_SUPPORT201    ld 30, -16(31)   # Restore r30 from the saved value on the stack202#endif203 204    mr 1, 31205    ld 31, -8(1)     # Restore r31 from the saved value on the stack206    ld 0, 16(1)207    mtlr 0           # Restore LR from the linkage area208    blr              # Branch to LR209 210#else  // KMP_ARCH_PPC_XCOFF211 212    .globl  __kmp_invoke_microtask[DS]213    .globl  .__kmp_invoke_microtask214    .align  4215    .csect __kmp_invoke_microtask[DS],2216    .vbyte  4, .__kmp_invoke_microtask217    .vbyte  4, TOC[TC0]218    .vbyte  4, 0219    .csect .text[PR],2220    .machine "pwr7"221.__kmp_invoke_microtask:222 223 224// -- Begin __kmp_invoke_microtask225// mark_begin;226 227// We need to allocate a stack frame large enough to hold all of the parameters228// on the stack for the microtask plus what this function needs. That's 24229// bytes under the XCOFF ABI, plus max(32, 8*(2 + argc)) for230// the parameters to the microtask (gtid, tid, argc elements of p_argv),231// plus 8 bytes to store the values of r4 and r5, and 4 bytes to store r31.232// With OMP-T support, we need an additional 4 bytes to save r30 to hold233// a copy of r8.234// Stack offsets relative to stack pointer:235//   r31: -4, r30: -8, gtid: -12, tid: -16236 237    mflr 0238    stw 31, -4(1)      # Save r31 to the stack239    stw 0, 8(1)        # Save LR to the linkage area240 241// This is unusual because normally we'd set r31 equal to r1 after the stack242// frame is established. In this case, however, we need to dynamically compute243// the stack frame size, and so we keep a direct copy of r1 to access our244// register save areas and restore the r1 value before returning.245    mr 31, 1246 247// Compute the size of the "argc" portion of the parameter save area.248// The parameter save area is always at least 32 bytes long (i.e. 8 regs)249// The microtask has (2 + argc) parameters, so if argc <= 6, we need to250// to allocate 4*6 bytes, not 4*argc.251    li 0, 6252    cmpwi 0, 6, 6253    iselgt 0, 6, 0     # r0 = (argc > 6)? argc : 6254    slwi 0, 0, 2       # r0 = 4 * max(argc, 6)255 256// Compute the size necessary for the local stack frame.257// 56 = 32 + 4 (for r4) + 4 (for r5) + 4 (for r31) + 4 (for OMP-T r30) +258//      4 (parameter gtid) + 4 (parameter tid)259    li 12, 56260    add 12, 0, 12261    neg 12, 12262 263// We need to make sure that the stack frame stays aligned (to 16 bytes).264    li 0, -16265    and 12, 0, 12266 267// Establish the local stack frame.268    stwux 1, 1, 12269 270#if OMPT_SUPPORT271    stw 30, -8(31)     # Save r30 to the stack272    stw 1, 0(8)273    mr 30, 8274#endif275 276// Store gtid and tid to the stack because they're passed by reference to the microtask.277    stw 4, -12(31)     # Save gtid to the stack278    stw 5, -16(31)     # Save tid to the stack279 280    mr 12, 6           # r12 = argc281    mr 4, 7            # r4 = p_argv282 283    cmpwi 0, 12, 1284    blt 0, .Lcall      # if (argc < 1) goto .Lcall285 286    lwz 5, 0(4)        # r5 = p_argv[0]287 288    cmpwi 0, 12, 2289    blt 0, .Lcall      # if (argc < 2) goto .Lcall290 291    lwz 6, 4(4)        # r6 = p_argv[1]292 293    cmpwi 0, 12, 3294    blt 0, .Lcall      # if (argc < 3) goto .Lcall295 296    lwz 7, 8(4)        # r7 = p_argv[2]297 298    cmpwi 0, 12, 4299    blt 0, .Lcall      # if (argc < 4) goto .Lcall300 301    lwz 8, 12(4)       # r8 = p_argv[3]302 303    cmpwi 0, 12, 5304    blt 0, .Lcall      # if (argc < 5) goto .Lcall305 306    lwz 9, 16(4)       # r9 = p_argv[4]307 308    cmpwi 0, 12, 6309    blt 0, .Lcall      # if (argc < 6) goto .Lcall310 311    lwz 10, 20(4)      # r10 = p_argv[5]312 313    cmpwi 0, 12, 7314    blt 0, .Lcall      # if (argc < 7) goto .Lcall315 316// There are more than 6 microtask parameters, so we need to store the317// remainder to the stack.318    addi 12, 12, -6    # argc -= 6319    mtctr 12320 321// These are set to 4 bytes before the first desired store address (we're using322// pre-increment loads and stores in the loop below). The parameter save area323// for the microtask begins 24 + 4*8 == 56 bytes above r1 for XCOFF.324    addi 4, 4, 20      # p_argv = p_argv + 5325                       # (i.e. skip the 5 elements we already processed)326    addi 12, 1, 52     # r12 = stack offset (56 - 4)327 328.Lnext:329    lwzu 0, 4(4)330    stwu 0, 4(12)331    bdnz .Lnext332 333.Lcall:334    stw 2, 20(1)     # Save the TOC pointer to the linkage area335// Load the actual function address from the function descriptor.336    lwz 12, 0(3)     # Function address337    lwz 2, 4(3)      # TOC pointer338    lwz 11, 8(3)     # Environment pointer339 340    addi 3, 31, -12  # r3 = &gtid341    addi 4, 31, -16  # r4 = &tid342 343    mtctr 12         # CTR = function address344    bctrl            # Branch to CTR345    lwz 2, 20(1)     # Restore TOC pointer from linkage area346 347#if OMPT_SUPPORT348    li 3, 0349    stw 3, 0(30)350#endif351 352    li 3, 1353 354#if OMPT_SUPPORT355    lwz 30, -8(31)   # Restore r30 from the saved value on the stack356#endif357 358    mr 1, 31359    lwz 31, -4(1)    # Restore r31 from the saved value on the stack360    lwz 0, 8(1)361    mtlr 0           # Restore LR from the linkage area362    blr              # Branch to LR363 364#endif // KMP_ARCH_PPC64_XCOFF365 366.Lfunc_end0:367    .vbyte  4, 0x00000000           # Traceback table begin368    .byte   0x00                    # Version = 0369    .byte   0x09                    # Language = CPlusPlus370    .byte   0x20                    # -IsGlobalLinkage, -IsOutOfLineEpilogOrPrologue371                                    # +HasTraceBackTableOffset, -IsInternalProcedure372                                    # -HasControlledStorage, -IsTOCless373                                    # -IsFloatingPointPresent374                                    # -IsFloatingPointOperationLogOrAbortEnabled375    .byte   0x61                    # -IsInterruptHandler, +IsFunctionNamePresent, +IsAllocaUsed376                                    # OnConditionDirective = 0, -IsCRSaved, +IsLRSaved377    .byte   0x80                    # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0378#if OMPT_SUPPORT379    .byte   0x02                    # -HasExtensionTable, -HasVectorInfo, NumOfGPRsSaved = 2380    .byte   0x06                    # NumberOfFixedParms = 6381#else382    .byte   0x01                    # -HasExtensionTable, -HasVectorInfo, NumOfGPRsSaved = 1383    .byte   0x05                    # NumberOfFixedParms = 5384#endif385    .byte   0x01                    # NumberOfFPParms = 0, +HasParmsOnStack386    .vbyte  4, 0x00000000           # Parameter type = i, i, i, i, i387    .vbyte  4, .Lfunc_end0-.__kmp_invoke_microtask # Function size388    .vbyte  2, 0x0016               # Function name len = 22389    .byte   "__kmp_invoke_microtask" # Function Name390    .byte   0x1f                    # AllocaRegister = 31391                                    # -- End function392 393// -- End  __kmp_invoke_microtask394 395// Support for unnamed common blocks.396 397    .comm .gomp_critical_user_, 32, 3398#if KMP_ARCH_PPC64_XCOFF399    .csect __kmp_unnamed_critical_addr[RW],3400#else401    .csect __kmp_unnamed_critical_addr[RW],2402#endif403    .globl __kmp_unnamed_critical_addr[RW]404    .ptr .gomp_critical_user_405 406// -- End unnamed common block407 408    .toc409 410#endif // KMP_OS_AIX411