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