]>
Commit | Line | Data |
---|---|---|
e75154a6 | 1 | /* Assembler macros for i386. |
d4697bc9 | 2 | Copyright (C) 1991-2014 Free Software Foundation, Inc. |
2c6fe0bd UD |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
2c6fe0bd UD |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 13 | Lesser General Public License for more details. |
2c6fe0bd | 14 | |
41bdb6e2 | 15 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 PE |
16 | License along with the GNU C Library; if not, see |
17 | <http://www.gnu.org/licenses/>. */ | |
e75154a6 RM |
18 | |
19 | #include <sysdeps/generic/sysdep.h> | |
20 | ||
314054ea JM |
21 | #include <features.h> /* For __GNUC_PREREQ. */ |
22 | ||
23 | /* It is desirable that the names of PIC thunks match those used by | |
d4a54ac6 JM |
24 | GCC so that multiple copies are eliminated by the linker. Because |
25 | GCC 4.6 and earlier use __i686 in the names, it is necessary to | |
26 | override that predefined macro. */ | |
27 | #if defined __i686 && defined __ASSEMBLER__ | |
28 | #undef __i686 | |
29 | #define __i686 __i686 | |
30 | #endif | |
314054ea JM |
31 | |
32 | #ifdef __ASSEMBLER__ | |
33 | # if __GNUC_PREREQ (4, 7) | |
34 | # define GET_PC_THUNK(reg) __x86.get_pc_thunk.reg | |
35 | # else | |
36 | # define GET_PC_THUNK(reg) __i686.get_pc_thunk.reg | |
37 | # endif | |
b1da7dd9 | 38 | #else |
314054ea JM |
39 | # if __GNUC_PREREQ (4, 7) |
40 | # define GET_PC_THUNK_STR(reg) "__x86.get_pc_thunk." #reg | |
41 | # else | |
42 | # define GET_PC_THUNK_STR(reg) "__i686.get_pc_thunk." #reg | |
43 | # endif | |
b1da7dd9 JM |
44 | #endif |
45 | ||
66715f83 | 46 | #ifdef __ASSEMBLER__ |
e75154a6 RM |
47 | |
48 | /* Syntactic details of assembler. */ | |
49 | ||
e75154a6 RM |
50 | /* ELF uses byte-counts for .align, most others use log2 of count of bytes. */ |
51 | #define ALIGNARG(log2) 1<<log2 | |
ae828bc6 | 52 | #define ASM_SIZE_DIRECTIVE(name) .size name,.-name; |
e75154a6 | 53 | |
e75154a6 | 54 | |
ae828bc6 UD |
55 | /* Define an entry point visible from C. |
56 | ||
57 | There is currently a bug in gdb which prevents us from specifying | |
58 | incomplete stabs information. Fake some entries here which specify | |
59 | the current source file. */ | |
e75154a6 | 60 | #define ENTRY(name) \ |
b67e9372 MP |
61 | .globl C_SYMBOL_NAME(name); \ |
62 | .type C_SYMBOL_NAME(name),@function; \ | |
e75154a6 RM |
63 | .align ALIGNARG(4); \ |
64 | C_LABEL(name) \ | |
62d01985 | 65 | cfi_startproc; \ |
e75154a6 RM |
66 | CALL_MCOUNT |
67 | ||
6ed0492f UD |
68 | #undef END |
69 | #define END(name) \ | |
62d01985 | 70 | cfi_endproc; \ |
ca98e171 | 71 | ASM_SIZE_DIRECTIVE(name) |
ae828bc6 | 72 | |
3af48cbd L |
73 | #define ENTRY_CHK(name) ENTRY (name) |
74 | #define END_CHK(name) END (name) | |
75 | ||
e75154a6 RM |
76 | /* If compiled for profiling, call `mcount' at the start of each function. */ |
77 | #ifdef PROF | |
78 | /* The mcount code relies on a normal frame pointer being on the stack | |
79 | to locate our caller, so push one just for its benefit. */ | |
80 | #define CALL_MCOUNT \ | |
cb8d9c93 | 81 | pushl %ebp; cfi_adjust_cfa_offset (4); movl %esp, %ebp; \ |
62d01985 UD |
82 | cfi_def_cfa_register (ebp); call JUMPTARGET(mcount); \ |
83 | popl %ebp; cfi_def_cfa (esp, 4); | |
e75154a6 RM |
84 | #else |
85 | #define CALL_MCOUNT /* Do nothing. */ | |
86 | #endif | |
87 | ||
e75154a6 RM |
88 | /* Since C identifiers are not normally prefixed with an underscore |
89 | on this system, the asm identifier `syscall_error' intrudes on the | |
90 | C name space. Make sure we use an innocuous name. */ | |
91 | #define syscall_error __syscall_error | |
92 | #define mcount _mcount | |
e75154a6 RM |
93 | |
94 | #define PSEUDO(name, syscall_name, args) \ | |
e75154a6 | 95 | .globl syscall_error; \ |
ffa8d2a0 RM |
96 | lose: SYSCALL_PIC_SETUP \ |
97 | jmp JUMPTARGET(syscall_error); \ | |
e75154a6 RM |
98 | ENTRY (name) \ |
99 | DO_CALL (syscall_name, args); \ | |
100 | jb lose | |
101 | ||
cccda09f UD |
102 | #undef PSEUDO_END |
103 | #define PSEUDO_END(name) \ | |
6ed0492f | 104 | END (name) |
cccda09f | 105 | |
11bf311e | 106 | # define SETUP_PIC_REG(reg) \ |
b1da7dd9 JM |
107 | .ifndef GET_PC_THUNK(reg); \ |
108 | .section .gnu.linkonce.t.GET_PC_THUNK(reg),"ax",@progbits; \ | |
109 | .globl GET_PC_THUNK(reg); \ | |
110 | .hidden GET_PC_THUNK(reg); \ | |
9a1d9254 | 111 | .p2align 4; \ |
b1da7dd9 JM |
112 | .type GET_PC_THUNK(reg),@function; \ |
113 | GET_PC_THUNK(reg): \ | |
1f708405 RM |
114 | movl (%esp), %e##reg; \ |
115 | ret; \ | |
b1da7dd9 | 116 | .size GET_PC_THUNK(reg), . - GET_PC_THUNK(reg); \ |
1f708405 RM |
117 | .previous; \ |
118 | .endif; \ | |
b1da7dd9 | 119 | call GET_PC_THUNK(reg) |
1f708405 RM |
120 | |
121 | # define LOAD_PIC_REG(reg) \ | |
122 | SETUP_PIC_REG(reg); addl $_GLOBAL_OFFSET_TABLE_, %e##reg | |
123 | ||
9a1d9254 JM |
124 | #undef JUMPTARGET |
125 | #ifdef PIC | |
126 | #define JUMPTARGET(name) name##@PLT | |
127 | #define SYSCALL_PIC_SETUP \ | |
128 | pushl %ebx; \ | |
129 | cfi_adjust_cfa_offset (4); \ | |
130 | call 0f; \ | |
131 | 0: popl %ebx; \ | |
132 | cfi_adjust_cfa_offset (-4); \ | |
1f150908 | 133 | addl $_GLOBAL_OFFSET_TABLE_+[.-0b], %ebx; |
9a1d9254 | 134 | |
e75154a6 RM |
135 | #else |
136 | #define JUMPTARGET(name) name | |
137 | #define SYSCALL_PIC_SETUP /* Nothing. */ | |
138 | #endif | |
139 | ||
ac16e905 UD |
140 | /* Local label name for asm code. */ |
141 | #ifndef L | |
ffa8d2a0 | 142 | #define L(name) .L##name |
ffa8d2a0 | 143 | #endif |
ac16e905 | 144 | |
ceaa0c5d UD |
145 | #define atom_text_section .section ".text.atom", "ax" |
146 | ||
d8e0ca50 JM |
147 | #else /* __ASSEMBLER__ */ |
148 | ||
149 | # define SETUP_PIC_REG_STR(reg) \ | |
150 | ".ifndef " GET_PC_THUNK_STR (reg) "\n" \ | |
151 | ".section .gnu.linkonce.t." GET_PC_THUNK_STR (reg) ",\"ax\",@progbits\n" \ | |
152 | ".globl " GET_PC_THUNK_STR (reg) "\n" \ | |
153 | ".hidden " GET_PC_THUNK_STR (reg) "\n" \ | |
154 | ".p2align 4\n" \ | |
155 | ".type " GET_PC_THUNK_STR (reg) ",@function\n" \ | |
156 | GET_PC_THUNK_STR (reg) ":" \ | |
157 | "movl (%%esp), %%e" #reg "\n" \ | |
158 | "ret\n" \ | |
159 | ".size " GET_PC_THUNK_STR (reg) ", . - " GET_PC_THUNK_STR (reg) "\n" \ | |
160 | ".previous\n" \ | |
161 | ".endif\n" \ | |
162 | "call " GET_PC_THUNK_STR (reg) | |
163 | ||
164 | # define LOAD_PIC_REG_STR(reg) \ | |
165 | SETUP_PIC_REG_STR (reg) "\naddl $_GLOBAL_OFFSET_TABLE_, %%e" #reg | |
166 | ||
66715f83 | 167 | #endif /* __ASSEMBLER__ */ |