xref: /freebsd/sys/powerpc/include/asm.h (revision 2ff63af9b88c7413b7d71715b5532625752a248e)
160727d8bSWarner Losh /*-
251369649SPedro F. Giffuni  * SPDX-License-Identifier: BSD-4-Clause
351369649SPedro F. Giffuni  *
46a76a4e1SBenno Rice  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
56a76a4e1SBenno Rice  * Copyright (C) 1995, 1996 TooLs GmbH.
66a76a4e1SBenno Rice  * All rights reserved.
76a76a4e1SBenno Rice  *
86a76a4e1SBenno Rice  * Redistribution and use in source and binary forms, with or without
96a76a4e1SBenno Rice  * modification, are permitted provided that the following conditions
106a76a4e1SBenno Rice  * are met:
116a76a4e1SBenno Rice  * 1. Redistributions of source code must retain the above copyright
126a76a4e1SBenno Rice  *    notice, this list of conditions and the following disclaimer.
136a76a4e1SBenno Rice  * 2. Redistributions in binary form must reproduce the above copyright
146a76a4e1SBenno Rice  *    notice, this list of conditions and the following disclaimer in the
156a76a4e1SBenno Rice  *    documentation and/or other materials provided with the distribution.
166a76a4e1SBenno Rice  * 3. All advertising materials mentioning features or use of this software
176a76a4e1SBenno Rice  *    must display the following acknowledgement:
186a76a4e1SBenno Rice  *	This product includes software developed by TooLs GmbH.
196a76a4e1SBenno Rice  * 4. The name of TooLs GmbH may not be used to endorse or promote products
206a76a4e1SBenno Rice  *    derived from this software without specific prior written permission.
216a76a4e1SBenno Rice  *
226a76a4e1SBenno Rice  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
236a76a4e1SBenno Rice  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
246a76a4e1SBenno Rice  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
256a76a4e1SBenno Rice  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
266a76a4e1SBenno Rice  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
276a76a4e1SBenno Rice  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
286a76a4e1SBenno Rice  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
296a76a4e1SBenno Rice  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
306a76a4e1SBenno Rice  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
316a76a4e1SBenno Rice  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
326a76a4e1SBenno Rice  *
336a76a4e1SBenno Rice  *	$NetBSD: asm.h,v 1.6.18.1 2000/07/25 08:37:14 kleink Exp $
346a76a4e1SBenno Rice  */
356a76a4e1SBenno Rice 
366a76a4e1SBenno Rice #ifndef _MACHINE_ASM_H_
376a76a4e1SBenno Rice #define	_MACHINE_ASM_H_
386a76a4e1SBenno Rice 
3987c48ca3SAndrew Gallatin #include <sys/cdefs.h>
4087c48ca3SAndrew Gallatin 
41294246bbSEd Maste #if defined(PIC) && !defined(__powerpc64__)
426a76a4e1SBenno Rice #define	PIC_PROLOGUE	XXX
436a76a4e1SBenno Rice #define	PIC_EPILOGUE	XXX
446a76a4e1SBenno Rice #define	PIC_PLT(x)	x@plt
456a76a4e1SBenno Rice #ifdef	__STDC__
466a76a4e1SBenno Rice #define	PIC_GOT(x)	XXX
476a76a4e1SBenno Rice #else	/* not __STDC__ */
486a76a4e1SBenno Rice #define	PIC_GOT(x)	XXX
496a76a4e1SBenno Rice #endif	/* __STDC__ */
506a76a4e1SBenno Rice #else
516a76a4e1SBenno Rice #define	PIC_PROLOGUE
526a76a4e1SBenno Rice #define	PIC_EPILOGUE
536a76a4e1SBenno Rice #define	PIC_PLT(x)	x
546a76a4e1SBenno Rice #define PIC_GOT(x)	x
556a76a4e1SBenno Rice #endif
566a76a4e1SBenno Rice 
5796269f7eSBenno Rice #define	CNAME(csym)		csym
5896269f7eSBenno Rice #define	ASMNAME(asmsym)		asmsym
59c3e289e1SNathan Whitehorn #ifdef __powerpc64__
60c3e289e1SNathan Whitehorn #define	HIDENAME(asmsym)	__CONCAT(_,asmsym)
61c3e289e1SNathan Whitehorn #else
6296269f7eSBenno Rice #define	HIDENAME(asmsym)	__CONCAT(.,asmsym)
63c3e289e1SNathan Whitehorn #endif
646a76a4e1SBenno Rice 
6529ba9b61SNathan Whitehorn #if !defined(_CALL_ELF) || _CALL_ELF == 1
66d59a23dcSAndreas Tobler #ifdef _KERNEL
6729ba9b61SNathan Whitehorn /* ELFv1 kernel uses global dot symbols */
68d59a23dcSAndreas Tobler #define	DOT_LABEL(name)		__CONCAT(.,name)
69d59a23dcSAndreas Tobler #define	TYPE_ENTRY(name)	.size	name,24; \
70d59a23dcSAndreas Tobler 				.type	DOT_LABEL(name),@function; \
71d59a23dcSAndreas Tobler 				.globl	DOT_LABEL(name);
72d59a23dcSAndreas Tobler #define	END_SIZE(name)		.size	DOT_LABEL(name),.-DOT_LABEL(name);
73d59a23dcSAndreas Tobler #else /* !_KERNEL */
7429ba9b61SNathan Whitehorn /* ELFv1 user code uses local function entry points */
75d59a23dcSAndreas Tobler #define	DOT_LABEL(name)		__CONCAT(.L.,name)
76d59a23dcSAndreas Tobler #define	TYPE_ENTRY(name)	.type	name,@function;
77d59a23dcSAndreas Tobler #define	END_SIZE(name)		.size	name,.-DOT_LABEL(name);
78d59a23dcSAndreas Tobler #endif /* _KERNEL */
7929ba9b61SNathan Whitehorn #else
8029ba9b61SNathan Whitehorn /* ELFv2 doesn't have any of this complication */
8129ba9b61SNathan Whitehorn #define	DOT_LABEL(name)		name
8229ba9b61SNathan Whitehorn #define	TYPE_ENTRY(name)	.type	name,@function;
8329ba9b61SNathan Whitehorn #define	END_SIZE(name)		.size	name,.-DOT_LABEL(name);
8429ba9b61SNathan Whitehorn #endif
85d59a23dcSAndreas Tobler 
86d59a23dcSAndreas Tobler #define	_GLOBAL(name) \
87d59a23dcSAndreas Tobler 	.data; \
88d59a23dcSAndreas Tobler 	.p2align 2; \
89d59a23dcSAndreas Tobler 	.globl	name; \
90d59a23dcSAndreas Tobler 	name:
916a76a4e1SBenno Rice 
92c3e289e1SNathan Whitehorn #ifdef __powerpc64__
936b3e2169SJustin Hibbits #define TOC_NAME_FOR_REF(name)	__CONCAT(.L,name)
946b3e2169SJustin Hibbits #define	TOC_REF(name)	TOC_NAME_FOR_REF(name)@toc
959cecb88cSNathan Whitehorn #define TOC_ENTRY(name) \
969cecb88cSNathan Whitehorn 	.section ".toc","aw"; \
976b3e2169SJustin Hibbits 	TOC_NAME_FOR_REF(name): \
989cecb88cSNathan Whitehorn         .tc name[TC],name
99fd6820bbSNathan Whitehorn #endif
1009cecb88cSNathan Whitehorn 
1017c259020SNathan Whitehorn #ifdef __powerpc64__
1027c259020SNathan Whitehorn 
1037c259020SNathan Whitehorn #if !defined(_CALL_ELF) || _CALL_ELF == 1
104d59a23dcSAndreas Tobler #define	_ENTRY(name) \
105d59a23dcSAndreas Tobler 	.section ".text"; \
106d59a23dcSAndreas Tobler 	.p2align 2; \
107d59a23dcSAndreas Tobler 	.globl	name; \
108d59a23dcSAndreas Tobler 	.section ".opd","aw"; \
109d59a23dcSAndreas Tobler 	.p2align 3; \
110d59a23dcSAndreas Tobler name: \
111d59a23dcSAndreas Tobler 	.quad	DOT_LABEL(name),.TOC.@tocbase,0; \
112d59a23dcSAndreas Tobler 	.previous; \
113d59a23dcSAndreas Tobler 	.p2align 4; \
114d59a23dcSAndreas Tobler 	TYPE_ENTRY(name) \
115*78599c32SConrad Meyer DOT_LABEL(name): \
116*78599c32SConrad Meyer 	.cfi_startproc
117d3111144SJustin Hibbits #define	_NAKED_ENTRY(name)	_ENTRY(name)
1187c259020SNathan Whitehorn #else
1197c259020SNathan Whitehorn #define	_ENTRY(name) \
1207c259020SNathan Whitehorn 	.text; \
1217c259020SNathan Whitehorn 	.p2align 4; \
1227c259020SNathan Whitehorn 	.globl	name; \
1237c259020SNathan Whitehorn 	.type	name,@function; \
1247c259020SNathan Whitehorn name: \
125*78599c32SConrad Meyer 	.cfi_startproc; \
1267c259020SNathan Whitehorn 	addis	%r2, %r12, (.TOC.-name)@ha; \
1277c259020SNathan Whitehorn 	addi	%r2, %r2, (.TOC.-name)@l; \
1287c259020SNathan Whitehorn 	.localentry name, .-name;
129d3111144SJustin Hibbits 
130d3111144SJustin Hibbits /* "Naked" function entry.  No TOC prologue for ELFv2. */
131d3111144SJustin Hibbits #define	_NAKED_ENTRY(name) \
132d3111144SJustin Hibbits 	.text; \
133d3111144SJustin Hibbits 	.p2align 4; \
134d3111144SJustin Hibbits 	.globl	name; \
135d3111144SJustin Hibbits 	.type	name,@function; \
136d3111144SJustin Hibbits name: \
137*78599c32SConrad Meyer 	.cfi_startproc; \
138d3111144SJustin Hibbits 	.localentry name, .-name;
1397c259020SNathan Whitehorn #endif
140d59a23dcSAndreas Tobler 
141d59a23dcSAndreas Tobler #define	_END(name) \
142*78599c32SConrad Meyer 	.cfi_endproc; \
143d59a23dcSAndreas Tobler 	.long	0; \
144d59a23dcSAndreas Tobler 	.byte	0,0,0,0,0,0,0,0; \
145d59a23dcSAndreas Tobler 	END_SIZE(name)
146e683c328SJustin Hibbits 
147e683c328SJustin Hibbits #define	LOAD_ADDR(reg, var) \
148e683c328SJustin Hibbits 	lis	reg, var@highest; \
149e683c328SJustin Hibbits 	ori	reg, reg, var@higher; \
150e683c328SJustin Hibbits 	rldicr	reg, reg, 32, 31; \
151e683c328SJustin Hibbits 	oris	reg, reg, var@h; \
152e683c328SJustin Hibbits 	ori	reg, reg, var@l;
153d59a23dcSAndreas Tobler #else /* !__powerpc64__ */
154d59a23dcSAndreas Tobler #define	_ENTRY(name) \
155d59a23dcSAndreas Tobler 	.text; \
156d59a23dcSAndreas Tobler 	.p2align 4; \
157d59a23dcSAndreas Tobler 	.globl	name; \
158d59a23dcSAndreas Tobler 	.type	name,@function; \
159*78599c32SConrad Meyer name: \
160*78599c32SConrad Meyer 	.cfi_startproc
161*78599c32SConrad Meyer #define	_END(name) \
162*78599c32SConrad Meyer 	.cfi_endproc; \
163*78599c32SConrad Meyer 	.size	name, . - name
164e683c328SJustin Hibbits 
165d3111144SJustin Hibbits #define _NAKED_ENTRY(name)	_ENTRY(name)
166d3111144SJustin Hibbits 
167e683c328SJustin Hibbits #define	LOAD_ADDR(reg, var) \
168e683c328SJustin Hibbits 	lis	reg, var@ha; \
169e683c328SJustin Hibbits 	ori	reg, reg, var@l;
170d59a23dcSAndreas Tobler #endif /* __powerpc64__ */
1716a76a4e1SBenno Rice 
172dc54fa1dSMarcel Moolenaar #if defined(PROF) || (defined(_KERNEL) && defined(GPROF))
1739eab2f14SAndreas Tobler # ifdef __powerpc64__
1749eab2f14SAndreas Tobler #   define	_PROF_PROLOGUE	mflr 0;					\
1759eab2f14SAndreas Tobler 				std 3,48(1);				\
1769eab2f14SAndreas Tobler 				std 4,56(1);				\
1779eab2f14SAndreas Tobler 				std 5,64(1);				\
1789eab2f14SAndreas Tobler 				std 0,16(1);				\
1799eab2f14SAndreas Tobler 				stdu 1,-112(1);				\
1809eab2f14SAndreas Tobler 				bl _mcount;				\
1819eab2f14SAndreas Tobler 				nop;					\
1829eab2f14SAndreas Tobler 				ld 0,112+16(1);				\
1839eab2f14SAndreas Tobler 				ld 3,112+48(1);				\
1849eab2f14SAndreas Tobler 				ld 4,112+56(1);				\
1859eab2f14SAndreas Tobler 				ld 5,112+64(1);				\
1869eab2f14SAndreas Tobler 				mtlr 0;					\
1879eab2f14SAndreas Tobler 				addi 1,1,112
1889eab2f14SAndreas Tobler # else
1896a76a4e1SBenno Rice #   define	_PROF_PROLOGUE	mflr 0; stw 0,4(1); bl _mcount
1909eab2f14SAndreas Tobler # endif
1916a76a4e1SBenno Rice #else
1926a76a4e1SBenno Rice # define	_PROF_PROLOGUE
1936a76a4e1SBenno Rice #endif
1946a76a4e1SBenno Rice 
195*78599c32SConrad Meyer #define	ASEND(y)	_END(ASMNAME(y))
19696269f7eSBenno Rice #define	ASENTRY(y)	_ENTRY(ASMNAME(y)); _PROF_PROLOGUE
197d59a23dcSAndreas Tobler #define	END(y)		_END(CNAME(y))
1989eab2f14SAndreas Tobler #define	ENTRY(y)	_ENTRY(CNAME(y)); _PROF_PROLOGUE
19996269f7eSBenno Rice #define	GLOBAL(y)	_GLOBAL(CNAME(y))
2006a76a4e1SBenno Rice 
2019eab2f14SAndreas Tobler #define	ASENTRY_NOPROF(y)	_ENTRY(ASMNAME(y))
2029eab2f14SAndreas Tobler #define	ENTRY_NOPROF(y)		_ENTRY(CNAME(y))
2039eab2f14SAndreas Tobler 
204691b35f3SBrandon Bergren /* Load NIA without affecting branch prediction */
205691b35f3SBrandon Bergren #define	LOAD_LR_NIA	bcl	20, 31, .+4
206691b35f3SBrandon Bergren 
207691b35f3SBrandon Bergren /*
208691b35f3SBrandon Bergren  * Magic sequence to return to native endian.
209691b35f3SBrandon Bergren  * Overwrites r0 and r11.
210691b35f3SBrandon Bergren  *
211691b35f3SBrandon Bergren  * The encoding of the instruction "tdi 0, %r0, 0x48" in opposite endian
212691b35f3SBrandon Bergren  * happens to be "b . + 8". This is useful because we can write a sequence
213691b35f3SBrandon Bergren  * of instructions that can execute in either endian.
214691b35f3SBrandon Bergren  *
215691b35f3SBrandon Bergren  * Use a sequence of handcoded instructions that switches contexts to the
216691b35f3SBrandon Bergren  * instruction following the sequence, but with the correct PSL_LE bit.
217691b35f3SBrandon Bergren  *
218691b35f3SBrandon Bergren  * The same sequence works for both BE and LE because the xori will flip
219691b35f3SBrandon Bergren  * the bit to the other state, and the code only runs when running in the
220691b35f3SBrandon Bergren  * wrong endian.
221691b35f3SBrandon Bergren  *
222691b35f3SBrandon Bergren  * This sequence is NMI-reentrant.
2230d356a53SBrandon Bergren  *
2240d356a53SBrandon Bergren  * Do not change the length of this sequence without looking at the users,
2250d356a53SBrandon Bergren  * this is used in size-constrained places like the reset vector!
226691b35f3SBrandon Bergren  */
227691b35f3SBrandon Bergren #define	RETURN_TO_NATIVE_ENDIAN						  \
228691b35f3SBrandon Bergren 	tdi	0, %r0, 0x48;	/* Endian swapped: b . + 8		*/\
229691b35f3SBrandon Bergren 	b	1f;		/* Will fall through to here if correct */\
230691b35f3SBrandon Bergren 	.long	0xa600607d;	/* mfmsr %r11				*/\
231691b35f3SBrandon Bergren 	.long	0x00000038;	/* li %r0, 0				*/\
232691b35f3SBrandon Bergren 	.long	0x6401617d;	/* mtmsrd %r0, 1 (L=1 EE,RI bits only)	*/\
233691b35f3SBrandon Bergren 	.long	0x01006b69;	/* xori %r11, %r11, 0x1 (PSL_LE)	*/\
234691b35f3SBrandon Bergren 	.long	0xa602087c;	/* mflr %r0				*/\
235691b35f3SBrandon Bergren 	.long	0x05009f42;	/* LOAD_LR_NIA				*/\
236691b35f3SBrandon Bergren 	.long	0xa6037b7d;	/* 0: mtsrr1 %r11			*/\
237691b35f3SBrandon Bergren 	.long	0xa602687d;	/* mflr	%r11				*/\
238691b35f3SBrandon Bergren 	.long	0x18006b39;	/* addi	%r11, %r11, (1f - 0b)		*/\
239691b35f3SBrandon Bergren 	.long	0xa6037a7d;	/* mtsrr0 %r11				*/\
240691b35f3SBrandon Bergren 	.long	0xa603087c;	/* mtlr %r0				*/\
241691b35f3SBrandon Bergren 	.long	0x2400004c;	/* rfid					*/\
242691b35f3SBrandon Bergren 1:	/* RETURN_TO_NATIVE_ENDIAN */
243691b35f3SBrandon Bergren 
2446a76a4e1SBenno Rice #define	ASMSTR		.asciz
2456a76a4e1SBenno Rice 
2466a76a4e1SBenno Rice #define	RCSID(x)	.text; .asciz x
2476a76a4e1SBenno Rice 
2487b4359b4SBenno Rice #undef __FBSDID
2497b4359b4SBenno Rice #if !defined(lint) && !defined(STRIP_FBSDID)
2507b4359b4SBenno Rice #define __FBSDID(s)	.ident s
2517b4359b4SBenno Rice #else
2527b4359b4SBenno Rice #define __FBSDID(s)	/* nothing */
2537b4359b4SBenno Rice #endif /* not lint and not STRIP_FBSDID */
2547b4359b4SBenno Rice 
25554558cdcSAndreas Tobler #define	WEAK_REFERENCE(sym, alias)				\
2566a76a4e1SBenno Rice 	.weak alias;						\
25754558cdcSAndreas Tobler 	.equ alias,sym
2586a76a4e1SBenno Rice 
2596a76a4e1SBenno Rice #ifdef __STDC__
2606a76a4e1SBenno Rice #define	WARN_REFERENCES(_sym,_msg)				\
2616a76a4e1SBenno Rice 	.section .gnu.warning. ## _sym ; .ascii _msg ; .text
2626a76a4e1SBenno Rice #else
2636a76a4e1SBenno Rice #define	WARN_REFERENCES(_sym,_msg)				\
2646a76a4e1SBenno Rice 	.section .gnu.warning./**/_sym ; .ascii _msg ; .text
2656a76a4e1SBenno Rice #endif /* __STDC__ */
2666a76a4e1SBenno Rice 
2676a76a4e1SBenno Rice #endif /* !_MACHINE_ASM_H_ */
268