summaryrefslogtreecommitdiffstats
path: root/runtime/arch/arm/asm_support_arm.S
blob: 049bd4f2ab222b19ccbcb5991eeffa6a53bf2c41 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_RUNTIME_ARCH_ARM_ASM_SUPPORT_ARM_S_
#define ART_RUNTIME_ARCH_ARM_ASM_SUPPORT_ARM_S_

#include "asm_support_arm.h"

// Define special registers.

// Register holding suspend check count down.
#define rSUSPEND r4
// Register holding Thread::Current().
#define rSELF r9

.syntax unified
.arch armv7-a
.thumb

// Macro to generate the value of Runtime::Current into rDest clobbering rTemp. As it uses labels
// then the labels need to be unique. We bind these to the function name in the ENTRY macros.
.macro RUNTIME_CURRENT name, num, rDest, rTemp
    .if .Lruntime_current\num\()_used
         .error
    .endif
    .set .Lruntime_current\num\()_used, 1
    ldr \rDest, .Lgot_\name\()_\num               @ Load offset of the GOT.
    ldr \rTemp, .Lruntime_instance_\name\()_\num  @ Load GOT offset of Runtime::instance_.
.Lload_got_\name\()_\num\():
    add \rDest, pc                                @ Fixup GOT address.
    ldr \rDest, [\rDest, \rTemp]                  @ Load address of Runtime::instance_.
    ldr \rDest, [\rDest]                          @ Load Runtime::instance_.
.endm

// Common ENTRY declaration code for ARM and thumb, an ENTRY should always be paired with an END.
// Declares the RUNTIME_CURRENT[123] macros that can be used within an ENTRY and will have literals
// generated at END.
.macro DEF_ENTRY thumb_or_arm, name
    \thumb_or_arm
// Clang ignores .thumb_func and requires an explicit .thumb. Investigate whether we should still
// carry around the .thumb_func.
    .ifc \thumb_or_arm, .thumb_func
        .thumb
    .endif
    .type \name, #function
    .hidden \name  // Hide this as a global symbol, so we do not incur plt calls.
    .global \name
    // Cache alignment for function entry.
    .balign 16
\name:
    .cfi_startproc
    .fnstart
    // Track whether RUNTIME_CURRENT was used.
    .set .Lruntime_current1_used, 0
    .set .Lruntime_current2_used, 0
    .set .Lruntime_current3_used, 0
    // The RUNTIME_CURRENT macros that are bound to the \name argument of DEF_ENTRY to ensure
    // that label names are unique.
    .macro RUNTIME_CURRENT1 rDest, rTemp
        RUNTIME_CURRENT \name, 1, \rDest, \rTemp
    .endm
    .macro RUNTIME_CURRENT2 rDest, rTemp
        RUNTIME_CURRENT \name, 2, \rDest, \rTemp
    .endm
    .macro RUNTIME_CURRENT3 rDest, rTemp
        RUNTIME_CURRENT \name, 3, \rDest, \rTemp
    .endm
.endm

// A thumb2 style ENTRY.
.macro ENTRY name
    DEF_ENTRY .thumb_func, \name
.endm

// A ARM style ENTRY.
.macro ARM_ENTRY name
    DEF_ENTRY .arm, \name
.endm

// Terminate an ENTRY and generate GOT references.
.macro END name
     // Generate offsets of GOT and Runtime::instance_ used in RUNTIME_CURRENT.
     .if .Lruntime_current1_used
         .Lgot_\name\()_1:
             .word   _GLOBAL_OFFSET_TABLE_-(.Lload_got_\name\()_1+4)
         .Lruntime_instance_\name\()_1:
             .word   _ZN3art7Runtime9instance_E(GOT)
     .endif
     .if .Lruntime_current2_used
         .Lgot_\name\()_2:
             .word   _GLOBAL_OFFSET_TABLE_-(.Lload_got_\name\()_2+4)
         .Lruntime_instance_\name\()_2:
             .word   _ZN3art7Runtime9instance_E(GOT)
    .endif
     .if .Lruntime_current3_used
         .Lgot_\name\()_3:
             .word   _GLOBAL_OFFSET_TABLE_-(.Lload_got_\name\()_3+4)
         .Lruntime_instance_\name\()_3:
             .word   _ZN3art7Runtime9instance_E(GOT)
    .endif
    // Remove the RUNTIME_CURRENTx macros so they get rebound in the next function entry.
    .purgem RUNTIME_CURRENT1
    .purgem RUNTIME_CURRENT2
    .purgem RUNTIME_CURRENT3
    .fnend
    .cfi_endproc
    .size \name, .-\name
.endm

// Declare an unimplemented ENTRY that will halt a debugger.
.macro UNIMPLEMENTED name
    ENTRY \name
    bkpt
    bkpt
    END \name
.endm

#endif  // ART_RUNTIME_ARCH_X86_ASM_SUPPORT_X86_S_