1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_RUNTIME_ARCH_MIPS64_ASM_SUPPORT_MIPS64_S_
18#define ART_RUNTIME_ARCH_MIPS64_ASM_SUPPORT_MIPS64_S_
19
20#include "asm_support_mips64.h"
21
22// Define special registers.
23
24// Register holding suspend check count down.
25#define rSUSPEND $s0
26// Register holding Thread::Current().
27#define rSELF $s1
28
29
30    // Declare a function called name, doesn't set up $gp.
31.macro ENTRY_NO_GP_CUSTOM_CFA name, cfa_offset
32    .type \name, %function
33    .global \name
34    // Cache alignment for function entry.
35    .balign 16
36\name:
37    .cfi_startproc
38     // Ensure we get a sane starting CFA.
39    .cfi_def_cfa $sp, \cfa_offset
40.endm
41
42    // Declare a function called name, doesn't set up $gp.
43.macro ENTRY_NO_GP name
44    ENTRY_NO_GP_CUSTOM_CFA \name, 0
45.endm
46
47    // Declare a function called name, sets up $gp.
48    // This macro modifies t8.
49.macro ENTRY name
50    ENTRY_NO_GP \name
51    // Set up $gp and store the previous $gp value to $t8. It will be pushed to the
52    // stack after the frame has been constructed.
53    .cpsetup $t9, $t8, \name
54    // Declare a local convenience label to be branched to when $gp is already set up.
55.L\name\()_gp_set:
56.endm
57
58.macro END name
59    .cfi_endproc
60    .size \name, .-\name
61.endm
62
63.macro UNIMPLEMENTED name
64    ENTRY \name
65    break
66    break
67    END \name
68.endm
69
70// Macros to poison (negate) the reference for heap poisoning.
71.macro POISON_HEAP_REF rRef
72#ifdef USE_HEAP_POISONING
73    dsubu \rRef, $zero, \rRef
74    dext  \rRef, \rRef, 0, 32
75#endif  // USE_HEAP_POISONING
76.endm
77
78// Macros to unpoison (negate) the reference for heap poisoning.
79.macro UNPOISON_HEAP_REF rRef
80#ifdef USE_HEAP_POISONING
81    dsubu \rRef, $zero, \rRef
82    dext  \rRef, \rRef, 0, 32
83#endif  // USE_HEAP_POISONING
84.endm
85
86// Byte size of the instructions (un)poisoning heap references.
87#ifdef USE_HEAP_POISONING
88#define HEAP_POISON_INSTR_SIZE 8
89#else
90#define HEAP_POISON_INSTR_SIZE 0
91#endif  // USE_HEAP_POISONING
92
93// Based on contents of creg select the minimum integer
94// At the end of the macro the original value of creg is lost
95.macro MINint dreg,rreg,sreg,creg
96  .set push
97  .set noat
98  .ifc \dreg, \rreg
99  selnez \dreg, \rreg, \creg
100  seleqz \creg, \sreg, \creg
101  .else
102  seleqz \dreg, \sreg, \creg
103  selnez \creg, \rreg, \creg
104  .endif
105  or     \dreg, \dreg, \creg
106  .set pop
107.endm
108
109// Find minimum of two signed registers
110.macro MINs dreg,rreg,sreg
111  .set push
112  .set noat
113  slt    $at, \rreg, \sreg
114  MINint \dreg, \rreg, \sreg, $at
115  .set pop
116.endm
117
118// Find minimum of two unsigned registers
119.macro MINu dreg,rreg,sreg
120  .set push
121  .set noat
122  sltu   $at, \rreg, \sreg
123  MINint \dreg, \rreg, \sreg, $at
124  .set pop
125.endm
126
127#endif  // ART_RUNTIME_ARCH_MIPS64_ASM_SUPPORT_MIPS64_S_
128