summaryrefslogtreecommitdiffstats
path: root/runtime/arch/x86/asm_support_x86.S
blob: 642d9a3dd468f1010d9af4efb9e57eb7b1730a6e (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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
 * 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_X86_ASM_SUPPORT_X86_S_
#define ART_RUNTIME_ARCH_X86_ASM_SUPPORT_X86_S_

#include "asm_support_x86.h"

#if defined(__clang__) && (__clang_major__ < 4) && (__clang_minor__ < 5)
    // Clang's as(1) doesn't let you name macro parameters prior to 3.5.
    #define MACRO0(macro_name) .macro macro_name
    #define MACRO1(macro_name, macro_arg1) .macro macro_name
    #define MACRO2(macro_name, macro_arg1, macro_args2) .macro macro_name
    #define MACRO3(macro_name, macro_arg1, macro_args2, macro_args3) .macro macro_name
    #define END_MACRO .endmacro

    // Clang's as(1) uses $0, $1, and so on for macro arguments.
    #define VAR(name,index) SYMBOL($index)
    #define PLT_VAR(name, index) SYMBOL($index)
    #define REG_VAR(name,index) %$index
    #define CALL_MACRO(name,index) $index
    #define FUNCTION_TYPE(name,index) .type $index, @function
    #define SIZE(name,index) .size $index, .-$index

    //  The use of $x for arguments mean that literals need to be represented with $$x in macros.
    #define LITERAL(value) $value
    #define MACRO_LITERAL(value) $$value
#else
    // Regular gas(1) lets you name macro parameters.
    #define MACRO0(macro_name) .macro macro_name
    #define MACRO1(macro_name, macro_arg1) .macro macro_name macro_arg1
    #define MACRO2(macro_name, macro_arg1, macro_arg2) .macro macro_name macro_arg1, macro_arg2
    #define MACRO3(macro_name, macro_arg1, macro_arg2, macro_arg3) .macro macro_name macro_arg1, macro_arg2, macro_arg3
    #define END_MACRO .endm

    // Regular gas(1) uses \argument_name for macro arguments.
    // We need to turn on alternate macro syntax so we can use & instead or the preprocessor
    // will screw us by inserting a space between the \ and the name. Even in this mode there's
    // no special meaning to $, so literals are still just $x. The use of altmacro means % is a
    // special character meaning care needs to be taken when passing registers as macro arguments.
    .altmacro
    #define VAR(name,index) name&
    #define PLT_VAR(name, index) name&@PLT
    #define REG_VAR(name,index) %name
    #define CALL_MACRO(name,index) name&
    #define FUNCTION_TYPE(name,index) .type name&, @function
    #define SIZE(name,index) .size name, .-name

    #define LITERAL(value) $value
    #define MACRO_LITERAL(value) $value
#endif

    // CFI support.
#if !defined(__APPLE__)
    #define CFI_STARTPROC .cfi_startproc
    #define CFI_ENDPROC .cfi_endproc
    #define CFI_ADJUST_CFA_OFFSET(size) .cfi_adjust_cfa_offset size
    #define CFI_DEF_CFA(reg,size) .cfi_def_cfa reg,size
    #define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg
    #define CFI_RESTORE(reg) .cfi_restore reg
    #define CFI_REL_OFFSET(reg,size) .cfi_rel_offset reg,size
#else
    // Mac OS' doesn't like cfi_* directives.
    #define CFI_STARTPROC
    #define CFI_ENDPROC
    #define CFI_ADJUST_CFA_OFFSET(size)
    #define CFI_DEF_CFA(reg,size)
    #define CFI_DEF_CFA_REGISTER(reg)
    #define CFI_RESTORE(reg)
    #define CFI_REL_OFFSET(reg,size)
#endif

    // Symbols.
#if !defined(__APPLE__)
    #define SYMBOL(name) name
    #define PLT_SYMBOL(name) name
#else
    // Mac OS' symbols have an _ prefix.
    #define SYMBOL(name) _ ## name
    #define PLT_SYMBOL(name) _ ## name
#endif

    /* Cache alignment for function entry */
MACRO0(ALIGN_FUNCTION_ENTRY)
    .balign 16
END_MACRO

MACRO1(DEFINE_FUNCTION, c_name)
    FUNCTION_TYPE(\c_name, 0)
    .globl VAR(c_name, 0)
    ALIGN_FUNCTION_ENTRY
VAR(c_name, 0):
    CFI_STARTPROC
    // Ensure we get a sane starting CFA.
    CFI_DEF_CFA(esp, 4)
END_MACRO

MACRO1(END_FUNCTION, c_name)
    CFI_ENDPROC
    SIZE(\c_name, 0)
END_MACRO

MACRO1(PUSH, reg)
    pushl REG_VAR(reg, 0)
    CFI_ADJUST_CFA_OFFSET(4)
    CFI_REL_OFFSET(REG_VAR(reg, 0), 0)
END_MACRO

MACRO1(POP, reg)
    popl REG_VAR(reg,0)
    CFI_ADJUST_CFA_OFFSET(-4)
    CFI_RESTORE(REG_VAR(reg,0))
END_MACRO

MACRO1(UNIMPLEMENTED,name)
    FUNCTION_TYPE(\name, 0)
    .globl VAR(name, 0)
    ALIGN_FUNCTION_ENTRY
VAR(name, 0):
    CFI_STARTPROC
    int3
    int3
    CFI_ENDPROC
    SIZE(\name, 0)
END_MACRO

MACRO0(SETUP_GOT_NOSAVE)
    call __x86.get_pc_thunk.bx
    addl $_GLOBAL_OFFSET_TABLE_, %ebx
END_MACRO

MACRO0(SETUP_GOT)
    PUSH  ebx
    SETUP_GOT_NOSAVE
END_MACRO

MACRO0(UNDO_SETUP_GOT)
    POP  ebx
END_MACRO

#endif  // ART_RUNTIME_ARCH_X86_ASM_SUPPORT_X86_S_