1/*
2 * Copyright (C) 2013 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_ARM_ASM_SUPPORT_ARM_S_
18#define ART_RUNTIME_ARCH_ARM_ASM_SUPPORT_ARM_S_
19
20#include "asm_support_arm.h"
21
22// Define special registers.
23
24// Register holding suspend check count down.
25#define rSUSPEND r4
26// Register holding Thread::Current().
27#define rSELF r9
28
29.syntax unified
30.arch armv7-a
31.thumb
32
33// Macro to generate the value of Runtime::Current into rDest clobbering rTemp. As it uses labels
34// then the labels need to be unique. We bind these to the function name in the ENTRY macros.
35.macro RUNTIME_CURRENT name, num, rDest, rTemp
36    .if .Lruntime_current\num\()_used
37         .error
38    .endif
39    .set .Lruntime_current\num\()_used, 1
40    ldr \rDest, .Lgot_\name\()_\num               @ Load offset of the GOT.
41    ldr \rTemp, .Lruntime_instance_\name\()_\num  @ Load GOT offset of Runtime::instance_.
42.Lload_got_\name\()_\num\():
43    add \rDest, pc                                @ Fixup GOT address.
44    ldr \rDest, [\rDest, \rTemp]                  @ Load address of Runtime::instance_.
45    ldr \rDest, [\rDest]                          @ Load Runtime::instance_.
46.endm
47
48// Common ENTRY declaration code for ARM and thumb, an ENTRY should always be paired with an END.
49// Declares the RUNTIME_CURRENT[123] macros that can be used within an ENTRY and will have literals
50// generated at END.
51.macro DEF_ENTRY thumb_or_arm, name
52    \thumb_or_arm
53// Clang ignores .thumb_func and requires an explicit .thumb. Investigate whether we should still
54// carry around the .thumb_func.
55    .ifc \thumb_or_arm, .thumb_func
56        .thumb
57    .endif
58    .type \name, #function
59    .hidden \name  // Hide this as a global symbol, so we do not incur plt calls.
60    .global \name
61    // Cache alignment for function entry.
62    .balign 16
63\name:
64    .cfi_startproc
65    .fnstart
66    // Track whether RUNTIME_CURRENT was used.
67    .set .Lruntime_current1_used, 0
68    .set .Lruntime_current2_used, 0
69    .set .Lruntime_current3_used, 0
70    // The RUNTIME_CURRENT macros that are bound to the \name argument of DEF_ENTRY to ensure
71    // that label names are unique.
72    .macro RUNTIME_CURRENT1 rDest, rTemp
73        RUNTIME_CURRENT \name, 1, \rDest, \rTemp
74    .endm
75    .macro RUNTIME_CURRENT2 rDest, rTemp
76        RUNTIME_CURRENT \name, 2, \rDest, \rTemp
77    .endm
78    .macro RUNTIME_CURRENT3 rDest, rTemp
79        RUNTIME_CURRENT \name, 3, \rDest, \rTemp
80    .endm
81.endm
82
83// A thumb2 style ENTRY.
84.macro ENTRY name
85    DEF_ENTRY .thumb_func, \name
86.endm
87
88// A ARM style ENTRY.
89.macro ARM_ENTRY name
90    DEF_ENTRY .arm, \name
91.endm
92
93// Terminate an ENTRY and generate GOT references.
94.macro END name
95     // Generate offsets of GOT and Runtime::instance_ used in RUNTIME_CURRENT.
96     .if .Lruntime_current1_used
97         .Lgot_\name\()_1:
98             .word   _GLOBAL_OFFSET_TABLE_-(.Lload_got_\name\()_1+4)
99         .Lruntime_instance_\name\()_1:
100             .word   _ZN3art7Runtime9instance_E(GOT)
101     .endif
102     .if .Lruntime_current2_used
103         .Lgot_\name\()_2:
104             .word   _GLOBAL_OFFSET_TABLE_-(.Lload_got_\name\()_2+4)
105         .Lruntime_instance_\name\()_2:
106             .word   _ZN3art7Runtime9instance_E(GOT)
107    .endif
108     .if .Lruntime_current3_used
109         .Lgot_\name\()_3:
110             .word   _GLOBAL_OFFSET_TABLE_-(.Lload_got_\name\()_3+4)
111         .Lruntime_instance_\name\()_3:
112             .word   _ZN3art7Runtime9instance_E(GOT)
113    .endif
114    // Remove the RUNTIME_CURRENTx macros so they get rebound in the next function entry.
115    .purgem RUNTIME_CURRENT1
116    .purgem RUNTIME_CURRENT2
117    .purgem RUNTIME_CURRENT3
118    .fnend
119    .cfi_endproc
120    .size \name, .-\name
121.endm
122
123// Declare an unimplemented ENTRY that will halt a debugger.
124.macro UNIMPLEMENTED name
125    ENTRY \name
126    bkpt
127    bkpt
128    END \name
129.endm
130
131// Macros to poison (negate) the reference for heap poisoning.
132.macro POISON_HEAP_REF rRef
133#ifdef USE_HEAP_POISONING
134    rsb \rRef, \rRef, #0
135#endif  // USE_HEAP_POISONING
136.endm
137
138// Macros to unpoison (negate) the reference for heap poisoning.
139.macro UNPOISON_HEAP_REF rRef
140#ifdef USE_HEAP_POISONING
141    rsb \rRef, \rRef, #0
142#endif  // USE_HEAP_POISONING
143.endm
144
145#endif  // ART_RUNTIME_ARCH_X86_ASM_SUPPORT_X86_S_
146