Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/powerpc/include/asm.h
39507 views
1
/*-
2
* SPDX-License-Identifier: BSD-4-Clause
3
*
4
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
5
* Copyright (C) 1995, 1996 TooLs GmbH.
6
* All rights reserved.
7
*
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions
10
* are met:
11
* 1. Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
* 3. All advertising materials mentioning features or use of this software
17
* must display the following acknowledgement:
18
* This product includes software developed by TooLs GmbH.
19
* 4. The name of TooLs GmbH may not be used to endorse or promote products
20
* derived from this software without specific prior written permission.
21
*
22
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
*
33
* $NetBSD: asm.h,v 1.6.18.1 2000/07/25 08:37:14 kleink Exp $
34
*/
35
36
#ifndef _MACHINE_ASM_H_
37
#define _MACHINE_ASM_H_
38
39
#include <sys/cdefs.h>
40
41
#if defined(PIC) && !defined(__powerpc64__)
42
#define PIC_PROLOGUE XXX
43
#define PIC_EPILOGUE XXX
44
#define PIC_PLT(x) x@plt
45
#ifdef __STDC__
46
#define PIC_GOT(x) XXX
47
#else /* not __STDC__ */
48
#define PIC_GOT(x) XXX
49
#endif /* __STDC__ */
50
#else
51
#define PIC_PROLOGUE
52
#define PIC_EPILOGUE
53
#define PIC_PLT(x) x
54
#define PIC_GOT(x) x
55
#endif
56
57
#define CNAME(csym) csym
58
#define ASMNAME(asmsym) asmsym
59
#ifdef __powerpc64__
60
#define HIDENAME(asmsym) __CONCAT(_,asmsym)
61
#else
62
#define HIDENAME(asmsym) __CONCAT(.,asmsym)
63
#endif
64
65
#if !defined(_CALL_ELF) || _CALL_ELF == 1
66
#ifdef _KERNEL
67
/* ELFv1 kernel uses global dot symbols */
68
#define DOT_LABEL(name) __CONCAT(.,name)
69
#define TYPE_ENTRY(name) .size name,24; \
70
.type DOT_LABEL(name),@function; \
71
.globl DOT_LABEL(name);
72
#define END_SIZE(name) .size DOT_LABEL(name),.-DOT_LABEL(name);
73
#else /* !_KERNEL */
74
/* ELFv1 user code uses local function entry points */
75
#define DOT_LABEL(name) __CONCAT(.L.,name)
76
#define TYPE_ENTRY(name) .type name,@function;
77
#define END_SIZE(name) .size name,.-DOT_LABEL(name);
78
#endif /* _KERNEL */
79
#else
80
/* ELFv2 doesn't have any of this complication */
81
#define DOT_LABEL(name) name
82
#define TYPE_ENTRY(name) .type name,@function;
83
#define END_SIZE(name) .size name,.-DOT_LABEL(name);
84
#endif
85
86
#define _GLOBAL(name) \
87
.data; \
88
.p2align 2; \
89
.globl name; \
90
name:
91
92
#ifdef __powerpc64__
93
#define TOC_NAME_FOR_REF(name) __CONCAT(.L,name)
94
#define TOC_REF(name) TOC_NAME_FOR_REF(name)@toc
95
#define TOC_ENTRY(name) \
96
.section ".toc","aw"; \
97
TOC_NAME_FOR_REF(name): \
98
.tc name[TC],name
99
#endif
100
101
#ifdef __powerpc64__
102
103
#if !defined(_CALL_ELF) || _CALL_ELF == 1
104
#define _ENTRY(name) \
105
.section ".text"; \
106
.p2align 2; \
107
.globl name; \
108
.section ".opd","aw"; \
109
.p2align 3; \
110
name: \
111
.quad DOT_LABEL(name),.TOC.@tocbase,0; \
112
.previous; \
113
.p2align 4; \
114
TYPE_ENTRY(name) \
115
DOT_LABEL(name): \
116
.cfi_startproc
117
#define _NAKED_ENTRY(name) _ENTRY(name)
118
#else
119
#define _ENTRY(name) \
120
.text; \
121
.p2align 4; \
122
.globl name; \
123
.type name,@function; \
124
name: \
125
.cfi_startproc; \
126
addis %r2, %r12, (.TOC.-name)@ha; \
127
addi %r2, %r2, (.TOC.-name)@l; \
128
.localentry name, .-name;
129
130
/* "Naked" function entry. No TOC prologue for ELFv2. */
131
#define _NAKED_ENTRY(name) \
132
.text; \
133
.p2align 4; \
134
.globl name; \
135
.type name,@function; \
136
name: \
137
.cfi_startproc; \
138
.localentry name, .-name;
139
#endif
140
141
#define _END(name) \
142
.cfi_endproc; \
143
.long 0; \
144
.byte 0,0,0,0,0,0,0,0; \
145
END_SIZE(name)
146
147
#define LOAD_ADDR(reg, var) \
148
lis reg, var@highest; \
149
ori reg, reg, var@higher; \
150
rldicr reg, reg, 32, 31; \
151
oris reg, reg, var@h; \
152
ori reg, reg, var@l;
153
#else /* !__powerpc64__ */
154
#define _ENTRY(name) \
155
.text; \
156
.p2align 4; \
157
.globl name; \
158
.type name,@function; \
159
name: \
160
.cfi_startproc
161
#define _END(name) \
162
.cfi_endproc; \
163
.size name, . - name
164
165
#define _NAKED_ENTRY(name) _ENTRY(name)
166
167
#define LOAD_ADDR(reg, var) \
168
lis reg, var@ha; \
169
ori reg, reg, var@l;
170
#endif /* __powerpc64__ */
171
172
#if defined(PROF) || (defined(_KERNEL) && defined(GPROF))
173
# ifdef __powerpc64__
174
# define _PROF_PROLOGUE mflr 0; \
175
std 3,48(1); \
176
std 4,56(1); \
177
std 5,64(1); \
178
std 0,16(1); \
179
stdu 1,-112(1); \
180
bl _mcount; \
181
nop; \
182
ld 0,112+16(1); \
183
ld 3,112+48(1); \
184
ld 4,112+56(1); \
185
ld 5,112+64(1); \
186
mtlr 0; \
187
addi 1,1,112
188
# else
189
# define _PROF_PROLOGUE mflr 0; stw 0,4(1); bl _mcount
190
# endif
191
#else
192
# define _PROF_PROLOGUE
193
#endif
194
195
#define ASEND(y) _END(ASMNAME(y))
196
#define ASENTRY(y) _ENTRY(ASMNAME(y)); _PROF_PROLOGUE
197
#define END(y) _END(CNAME(y))
198
#define ENTRY(y) _ENTRY(CNAME(y)); _PROF_PROLOGUE
199
#define GLOBAL(y) _GLOBAL(CNAME(y))
200
201
#define ASENTRY_NOPROF(y) _ENTRY(ASMNAME(y))
202
#define ENTRY_NOPROF(y) _ENTRY(CNAME(y))
203
204
/* Load NIA without affecting branch prediction */
205
#define LOAD_LR_NIA bcl 20, 31, .+4
206
207
/*
208
* Magic sequence to return to native endian.
209
* Overwrites r0 and r11.
210
*
211
* The encoding of the instruction "tdi 0, %r0, 0x48" in opposite endian
212
* happens to be "b . + 8". This is useful because we can write a sequence
213
* of instructions that can execute in either endian.
214
*
215
* Use a sequence of handcoded instructions that switches contexts to the
216
* instruction following the sequence, but with the correct PSL_LE bit.
217
*
218
* The same sequence works for both BE and LE because the xori will flip
219
* the bit to the other state, and the code only runs when running in the
220
* wrong endian.
221
*
222
* This sequence is NMI-reentrant.
223
*
224
* Do not change the length of this sequence without looking at the users,
225
* this is used in size-constrained places like the reset vector!
226
*/
227
#define RETURN_TO_NATIVE_ENDIAN \
228
tdi 0, %r0, 0x48; /* Endian swapped: b . + 8 */\
229
b 1f; /* Will fall through to here if correct */\
230
.long 0xa600607d; /* mfmsr %r11 */\
231
.long 0x00000038; /* li %r0, 0 */\
232
.long 0x6401617d; /* mtmsrd %r0, 1 (L=1 EE,RI bits only) */\
233
.long 0x01006b69; /* xori %r11, %r11, 0x1 (PSL_LE) */\
234
.long 0xa602087c; /* mflr %r0 */\
235
.long 0x05009f42; /* LOAD_LR_NIA */\
236
.long 0xa6037b7d; /* 0: mtsrr1 %r11 */\
237
.long 0xa602687d; /* mflr %r11 */\
238
.long 0x18006b39; /* addi %r11, %r11, (1f - 0b) */\
239
.long 0xa6037a7d; /* mtsrr0 %r11 */\
240
.long 0xa603087c; /* mtlr %r0 */\
241
.long 0x2400004c; /* rfid */\
242
1: /* RETURN_TO_NATIVE_ENDIAN */
243
244
#define ASMSTR .asciz
245
246
#define RCSID(x) .text; .asciz x
247
248
#undef __FBSDID
249
#if !defined(lint) && !defined(STRIP_FBSDID)
250
#define __FBSDID(s) .ident s
251
#else
252
#define __FBSDID(s) /* nothing */
253
#endif /* not lint and not STRIP_FBSDID */
254
255
#define WEAK_REFERENCE(sym, alias) \
256
.weak alias; \
257
.equ alias,sym
258
259
#ifdef __STDC__
260
#define WARN_REFERENCES(_sym,_msg) \
261
.section .gnu.warning. ## _sym ; .ascii _msg ; .text
262
#else
263
#define WARN_REFERENCES(_sym,_msg) \
264
.section .gnu.warning./**/_sym ; .ascii _msg ; .text
265
#endif /* __STDC__ */
266
267
#endif /* !_MACHINE_ASM_H_ */
268
269