1*3cab2bb3Spatrick//===-- xray_trampoline_mips64.s --------------------------------*- ASM -*-===// 2*3cab2bb3Spatrick// 3*3cab2bb3Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*3cab2bb3Spatrick// See https://llvm.org/LICENSE.txt for license information. 5*3cab2bb3Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*3cab2bb3Spatrick// 7*3cab2bb3Spatrick//===----------------------------------------------------------------------===// 8*3cab2bb3Spatrick// 9*3cab2bb3Spatrick// This file is a part of XRay, a dynamic runtime instrumentation system. 10*3cab2bb3Spatrick// 11*3cab2bb3Spatrick// This implements the MIPS64-specific assembler for the trampolines. 12*3cab2bb3Spatrick// 13*3cab2bb3Spatrick//===----------------------------------------------------------------------===// 14*3cab2bb3Spatrick 15*3cab2bb3Spatrick .text 16*3cab2bb3Spatrick .file "xray_trampoline_mips64.S" 17*3cab2bb3Spatrick .globl __xray_FunctionEntry 18*3cab2bb3Spatrick .p2align 2 19*3cab2bb3Spatrick .type __xray_FunctionEntry,@function 20*3cab2bb3Spatrick__xray_FunctionEntry: 21*3cab2bb3Spatrick .cfi_startproc 22*3cab2bb3Spatrick // Save argument registers before doing any actual work. 23*3cab2bb3Spatrick .cfi_def_cfa_offset 144 24*3cab2bb3Spatrick daddiu $sp, $sp, -144 25*3cab2bb3Spatrick sd $ra, 136($sp) 26*3cab2bb3Spatrick .cfi_offset 31, -8 27*3cab2bb3Spatrick sd $gp, 128($sp) 28*3cab2bb3Spatrick sd $a7, 120($sp) 29*3cab2bb3Spatrick sd $a6, 112($sp) 30*3cab2bb3Spatrick sd $a5, 104($sp) 31*3cab2bb3Spatrick sd $a4, 96($sp) 32*3cab2bb3Spatrick sd $a3, 88($sp) 33*3cab2bb3Spatrick sd $a2, 80($sp) 34*3cab2bb3Spatrick sd $a1, 72($sp) 35*3cab2bb3Spatrick sd $a0, 64($sp) 36*3cab2bb3Spatrick sdc1 $f19, 56($sp) 37*3cab2bb3Spatrick sdc1 $f18, 48($sp) 38*3cab2bb3Spatrick sdc1 $f17, 40($sp) 39*3cab2bb3Spatrick sdc1 $f16, 32($sp) 40*3cab2bb3Spatrick sdc1 $f15, 24($sp) 41*3cab2bb3Spatrick sdc1 $f14, 16($sp) 42*3cab2bb3Spatrick sdc1 $f13, 8($sp) 43*3cab2bb3Spatrick sdc1 $f12, 0($sp) 44*3cab2bb3Spatrick 45*3cab2bb3Spatrick lui $gp, %hi(%neg(%gp_rel(__xray_FunctionEntry))) 46*3cab2bb3Spatrick daddu $gp, $gp, $t9 47*3cab2bb3Spatrick daddiu $gp ,$gp, %lo(%neg(%gp_rel(__xray_FunctionEntry))) 48*3cab2bb3Spatrick 49*3cab2bb3Spatrick dla $t9, _ZN6__xray19XRayPatchedFunctionE 50*3cab2bb3Spatrick ld $t9, 0($t9) 51*3cab2bb3Spatrick 52*3cab2bb3Spatrick beqz $t9, FunctionEntry_restore 53*3cab2bb3Spatrick 54*3cab2bb3Spatrick // a1=0 means that we are tracing an entry event 55*3cab2bb3Spatrick move $a1, $zero 56*3cab2bb3Spatrick // Function ID is in t0 (the first parameter). 57*3cab2bb3Spatrick move $a0, $t0 58*3cab2bb3Spatrick jalr $t9 59*3cab2bb3Spatrick 60*3cab2bb3SpatrickFunctionEntry_restore: 61*3cab2bb3Spatrick // Restore argument registers 62*3cab2bb3Spatrick ldc1 $f12, 0($sp) 63*3cab2bb3Spatrick ldc1 $f13, 8($sp) 64*3cab2bb3Spatrick ldc1 $f14, 16($sp) 65*3cab2bb3Spatrick ldc1 $f15, 24($sp) 66*3cab2bb3Spatrick ldc1 $f16, 32($sp) 67*3cab2bb3Spatrick ldc1 $f17, 40($sp) 68*3cab2bb3Spatrick ldc1 $f18, 48($sp) 69*3cab2bb3Spatrick ldc1 $f19, 56($sp) 70*3cab2bb3Spatrick ld $a0, 64($sp) 71*3cab2bb3Spatrick ld $a1, 72($sp) 72*3cab2bb3Spatrick ld $a2, 80($sp) 73*3cab2bb3Spatrick ld $a3, 88($sp) 74*3cab2bb3Spatrick ld $a4, 96($sp) 75*3cab2bb3Spatrick ld $a5, 104($sp) 76*3cab2bb3Spatrick ld $a6, 112($sp) 77*3cab2bb3Spatrick ld $a7, 120($sp) 78*3cab2bb3Spatrick ld $gp, 128($sp) 79*3cab2bb3Spatrick ld $ra, 136($sp) 80*3cab2bb3Spatrick daddiu $sp, $sp, 144 81*3cab2bb3Spatrick jr $ra 82*3cab2bb3SpatrickFunctionEntry_end: 83*3cab2bb3Spatrick .size __xray_FunctionEntry, FunctionEntry_end-__xray_FunctionEntry 84*3cab2bb3Spatrick .cfi_endproc 85*3cab2bb3Spatrick 86*3cab2bb3Spatrick .text 87*3cab2bb3Spatrick .globl __xray_FunctionExit 88*3cab2bb3Spatrick .p2align 2 89*3cab2bb3Spatrick .type __xray_FunctionExit,@function 90*3cab2bb3Spatrick__xray_FunctionExit: 91*3cab2bb3Spatrick .cfi_startproc 92*3cab2bb3Spatrick // Save return registers before doing any actual work. 93*3cab2bb3Spatrick .cfi_def_cfa_offset 64 94*3cab2bb3Spatrick daddiu $sp, $sp, -64 95*3cab2bb3Spatrick sd $ra, 56($sp) 96*3cab2bb3Spatrick .cfi_offset 31, -8 97*3cab2bb3Spatrick sd $gp, 48($sp) 98*3cab2bb3Spatrick sd $a0, 40($sp) 99*3cab2bb3Spatrick sd $v1, 32($sp) 100*3cab2bb3Spatrick sd $v0, 24($sp) 101*3cab2bb3Spatrick sdc1 $f2, 16($sp) 102*3cab2bb3Spatrick sdc1 $f1, 8($sp) 103*3cab2bb3Spatrick sdc1 $f0, 0($sp) 104*3cab2bb3Spatrick 105*3cab2bb3Spatrick lui $gp, %hi(%neg(%gp_rel(__xray_FunctionExit))) 106*3cab2bb3Spatrick daddu $gp, $gp, $t9 107*3cab2bb3Spatrick daddiu $gp ,$gp, %lo(%neg(%gp_rel(__xray_FunctionExit))) 108*3cab2bb3Spatrick 109*3cab2bb3Spatrick dla $t9, _ZN6__xray19XRayPatchedFunctionE 110*3cab2bb3Spatrick ld $t9, 0($t9) 111*3cab2bb3Spatrick 112*3cab2bb3Spatrick beqz $t9, FunctionExit_restore 113*3cab2bb3Spatrick 114*3cab2bb3Spatrick // a1=1 means that we are tracing an exit event 115*3cab2bb3Spatrick li $a1, 1 116*3cab2bb3Spatrick // Function ID is in t0 (the first parameter). 117*3cab2bb3Spatrick move $a0, $t0 118*3cab2bb3Spatrick jalr $t9 119*3cab2bb3Spatrick 120*3cab2bb3SpatrickFunctionExit_restore: 121*3cab2bb3Spatrick // Restore return registers 122*3cab2bb3Spatrick ldc1 $f0, 0($sp) 123*3cab2bb3Spatrick ldc1 $f1, 8($sp) 124*3cab2bb3Spatrick ldc1 $f2, 16($sp) 125*3cab2bb3Spatrick ld $v0, 24($sp) 126*3cab2bb3Spatrick ld $v1, 32($sp) 127*3cab2bb3Spatrick ld $a0, 40($sp) 128*3cab2bb3Spatrick ld $gp, 48($sp) 129*3cab2bb3Spatrick ld $ra, 56($sp) 130*3cab2bb3Spatrick daddiu $sp, $sp, 64 131*3cab2bb3Spatrick jr $ra 132*3cab2bb3Spatrick 133*3cab2bb3SpatrickFunctionExit_end: 134*3cab2bb3Spatrick .size __xray_FunctionExit, FunctionExit_end-__xray_FunctionExit 135*3cab2bb3Spatrick .cfi_endproc 136