xref: /freebsd/contrib/llvm-project/compiler-rt/lib/xray/xray_trampoline_mips.S (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric//===-- xray_trampoline_mips.s ----------------------------------*- ASM -*-===//
2*0b57cec5SDimitry Andric//
3*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric//
7*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric//
9*0b57cec5SDimitry Andric// This file is a part of XRay, a dynamic runtime instrumentation system.
10*0b57cec5SDimitry Andric//
11*0b57cec5SDimitry Andric// This implements the MIPS-specific assembler for the trampolines.
12*0b57cec5SDimitry Andric//
13*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
14*0b57cec5SDimitry Andric
15*0b57cec5SDimitry Andric  .text
16*0b57cec5SDimitry Andric  .file "xray_trampoline_mips.S"
17*0b57cec5SDimitry Andric  .globl __xray_FunctionEntry
18*0b57cec5SDimitry Andric  .p2align 2
19*0b57cec5SDimitry Andric  .type __xray_FunctionEntry,@function
20*0b57cec5SDimitry Andric__xray_FunctionEntry:
21*0b57cec5SDimitry Andric  .cfi_startproc
22*0b57cec5SDimitry Andric  .set noreorder
23*0b57cec5SDimitry Andric  .cpload $t9
24*0b57cec5SDimitry Andric  .set reorder
25*0b57cec5SDimitry Andric  // Save argument registers before doing any actual work
26*0b57cec5SDimitry Andric  .cfi_def_cfa_offset 36
27*0b57cec5SDimitry Andric  addiu  $sp, $sp, -36
28*0b57cec5SDimitry Andric  sw     $ra, 32($sp)
29*0b57cec5SDimitry Andric  .cfi_offset 31, -4
30*0b57cec5SDimitry Andric  sw     $a3, 28($sp)
31*0b57cec5SDimitry Andric  sw     $a2, 24($sp)
32*0b57cec5SDimitry Andric  sw     $a1, 20($sp)
33*0b57cec5SDimitry Andric  sw     $a0, 16($sp)
34*0b57cec5SDimitry Andric  sdc1	 $f14, 8($sp)
35*0b57cec5SDimitry Andric  sdc1	 $f12, 0($sp)
36*0b57cec5SDimitry Andric
37*0b57cec5SDimitry Andric  la     $t9, _ZN6__xray19XRayPatchedFunctionE
38*0b57cec5SDimitry Andric  lw     $t9, 0($t9)
39*0b57cec5SDimitry Andric
40*0b57cec5SDimitry Andric  beqz   $t9, FunctionEntry_restore
41*0b57cec5SDimitry Andric
42*0b57cec5SDimitry Andric  // a1=0 means that we are tracing an entry event
43*0b57cec5SDimitry Andric  move   $a1, $zero
44*0b57cec5SDimitry Andric  // Function ID is in t0 (the first parameter).
45*0b57cec5SDimitry Andric  move   $a0, $t0
46*0b57cec5SDimitry Andric  jalr   $t9
47*0b57cec5SDimitry Andric
48*0b57cec5SDimitry AndricFunctionEntry_restore:
49*0b57cec5SDimitry Andric  // Restore argument registers
50*0b57cec5SDimitry Andric  ldc1   $f12, 0($sp)
51*0b57cec5SDimitry Andric  ldc1   $f14, 8($sp)
52*0b57cec5SDimitry Andric  lw     $a0, 16($sp)
53*0b57cec5SDimitry Andric  lw     $a1, 20($sp)
54*0b57cec5SDimitry Andric  lw     $a2, 24($sp)
55*0b57cec5SDimitry Andric  lw     $a3, 28($sp)
56*0b57cec5SDimitry Andric  lw     $ra, 32($sp)
57*0b57cec5SDimitry Andric  addiu	 $sp, $sp, 36
58*0b57cec5SDimitry Andric  jr     $ra
59*0b57cec5SDimitry AndricFunctionEntry_end:
60*0b57cec5SDimitry Andric  .size __xray_FunctionEntry, FunctionEntry_end-__xray_FunctionEntry
61*0b57cec5SDimitry Andric  .cfi_endproc
62*0b57cec5SDimitry Andric
63*0b57cec5SDimitry Andric  .text
64*0b57cec5SDimitry Andric  .globl __xray_FunctionExit
65*0b57cec5SDimitry Andric  .p2align 2
66*0b57cec5SDimitry Andric  .type __xray_FunctionExit,@function
67*0b57cec5SDimitry Andric__xray_FunctionExit:
68*0b57cec5SDimitry Andric  .cfi_startproc
69*0b57cec5SDimitry Andric  .set noreorder
70*0b57cec5SDimitry Andric  .cpload $t9
71*0b57cec5SDimitry Andric  .set reorder
72*0b57cec5SDimitry Andric  // Save return registers before doing any actual work.
73*0b57cec5SDimitry Andric  .cfi_def_cfa_offset 36
74*0b57cec5SDimitry Andric  addiu  $sp, $sp, -36
75*0b57cec5SDimitry Andric  sw     $ra, 32($sp)
76*0b57cec5SDimitry Andric  .cfi_offset 31, -4
77*0b57cec5SDimitry Andric  sw     $a1, 28($sp)
78*0b57cec5SDimitry Andric  sw     $a0, 24($sp)
79*0b57cec5SDimitry Andric  sw     $v1, 20($sp)
80*0b57cec5SDimitry Andric  sw     $v0, 16($sp)
81*0b57cec5SDimitry Andric  sdc1   $f2, 8($sp)
82*0b57cec5SDimitry Andric  sdc1   $f0, 0($sp)
83*0b57cec5SDimitry Andric
84*0b57cec5SDimitry Andric  la     $t9, _ZN6__xray19XRayPatchedFunctionE
85*0b57cec5SDimitry Andric  lw     $t9, 0($t9)
86*0b57cec5SDimitry Andric
87*0b57cec5SDimitry Andric  beqz	 $t9, FunctionExit_restore
88*0b57cec5SDimitry Andric
89*0b57cec5SDimitry Andric  // a1=1 means that we are tracing an exit event
90*0b57cec5SDimitry Andric  li     $a1, 1
91*0b57cec5SDimitry Andric  // Function ID is in t0 (the first parameter).
92*0b57cec5SDimitry Andric  move   $a0, $t0
93*0b57cec5SDimitry Andric  jalr   $t9
94*0b57cec5SDimitry Andric
95*0b57cec5SDimitry AndricFunctionExit_restore:
96*0b57cec5SDimitry Andric  // Restore return registers
97*0b57cec5SDimitry Andric  ldc1   $f0, 0($sp)
98*0b57cec5SDimitry Andric  ldc1   $f2, 8($sp)
99*0b57cec5SDimitry Andric  lw     $v0, 16($sp)
100*0b57cec5SDimitry Andric  lw     $v1, 20($sp)
101*0b57cec5SDimitry Andric  lw     $a0, 24($sp)
102*0b57cec5SDimitry Andric  lw     $a1, 28($sp)
103*0b57cec5SDimitry Andric  lw     $ra, 32($sp)
104*0b57cec5SDimitry Andric  addiu  $sp, $sp, 36
105*0b57cec5SDimitry Andric  jr     $ra
106*0b57cec5SDimitry Andric
107*0b57cec5SDimitry AndricFunctionExit_end:
108*0b57cec5SDimitry Andric  .size __xray_FunctionExit, FunctionExit_end-__xray_FunctionExit
109*0b57cec5SDimitry Andric  .cfi_endproc
110