/*-1* SPDX-License-Identifier: BSD-4-Clause2*3* Copyright (C) 1995, 1996 Wolfgang Solfrank.4* Copyright (C) 1995, 1996 TooLs GmbH.5* All rights reserved.6*7* Redistribution and use in source and binary forms, with or without8* modification, are permitted provided that the following conditions9* are met:10* 1. Redistributions of source code must retain the above copyright11* notice, this list of conditions and the following disclaimer.12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15* 3. All advertising materials mentioning features or use of this software16* must display the following acknowledgement:17* This product includes software developed by TooLs GmbH.18* 4. The name of TooLs GmbH may not be used to endorse or promote products19* derived from this software without specific prior written permission.20*21* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR22* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES23* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.24* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,25* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,26* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;27* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,28* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR29* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF30* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.31*32* $NetBSD: asm.h,v 1.6.18.1 2000/07/25 08:37:14 kleink Exp $33*/3435#ifndef _MACHINE_ASM_H_36#define _MACHINE_ASM_H_3738#include <sys/cdefs.h>3940#if defined(PIC) && !defined(__powerpc64__)41#define PIC_PROLOGUE XXX42#define PIC_EPILOGUE XXX43#define PIC_PLT(x) x@plt44#ifdef __STDC__45#define PIC_GOT(x) XXX46#else /* not __STDC__ */47#define PIC_GOT(x) XXX48#endif /* __STDC__ */49#else50#define PIC_PROLOGUE51#define PIC_EPILOGUE52#define PIC_PLT(x) x53#define PIC_GOT(x) x54#endif5556#define CNAME(csym) csym57#define ASMNAME(asmsym) asmsym58#ifdef __powerpc64__59#define HIDENAME(asmsym) __CONCAT(_,asmsym)60#else61#define HIDENAME(asmsym) __CONCAT(.,asmsym)62#endif6364#if !defined(_CALL_ELF) || _CALL_ELF == 165#ifdef _KERNEL66/* ELFv1 kernel uses global dot symbols */67#define DOT_LABEL(name) __CONCAT(.,name)68#define TYPE_ENTRY(name) .size name,24; \69.type DOT_LABEL(name),@function; \70.globl DOT_LABEL(name);71#define END_SIZE(name) .size DOT_LABEL(name),.-DOT_LABEL(name);72#else /* !_KERNEL */73/* ELFv1 user code uses local function entry points */74#define DOT_LABEL(name) __CONCAT(.L.,name)75#define TYPE_ENTRY(name) .type name,@function;76#define END_SIZE(name) .size name,.-DOT_LABEL(name);77#endif /* _KERNEL */78#else79/* ELFv2 doesn't have any of this complication */80#define DOT_LABEL(name) name81#define TYPE_ENTRY(name) .type name,@function;82#define END_SIZE(name) .size name,.-DOT_LABEL(name);83#endif8485#define _GLOBAL(name) \86.data; \87.p2align 2; \88.globl name; \89name:9091#ifdef __powerpc64__92#define TOC_NAME_FOR_REF(name) __CONCAT(.L,name)93#define TOC_REF(name) TOC_NAME_FOR_REF(name)@toc94#define TOC_ENTRY(name) \95.section ".toc","aw"; \96TOC_NAME_FOR_REF(name): \97.tc name[TC],name98#endif99100#ifdef __powerpc64__101102#if !defined(_CALL_ELF) || _CALL_ELF == 1103#define _ENTRY(name) \104.section ".text"; \105.p2align 2; \106.globl name; \107.section ".opd","aw"; \108.p2align 3; \109name: \110.quad DOT_LABEL(name),.TOC.@tocbase,0; \111.previous; \112.p2align 4; \113TYPE_ENTRY(name) \114DOT_LABEL(name): \115.cfi_startproc116#define _NAKED_ENTRY(name) _ENTRY(name)117#else118#define _ENTRY(name) \119.text; \120.p2align 4; \121.globl name; \122.type name,@function; \123name: \124.cfi_startproc; \125addis %r2, %r12, (.TOC.-name)@ha; \126addi %r2, %r2, (.TOC.-name)@l; \127.localentry name, .-name;128129/* "Naked" function entry. No TOC prologue for ELFv2. */130#define _NAKED_ENTRY(name) \131.text; \132.p2align 4; \133.globl name; \134.type name,@function; \135name: \136.cfi_startproc; \137.localentry name, .-name;138#endif139140#define _END(name) \141.cfi_endproc; \142.long 0; \143.byte 0,0,0,0,0,0,0,0; \144END_SIZE(name)145146#define LOAD_ADDR(reg, var) \147lis reg, var@highest; \148ori reg, reg, var@higher; \149rldicr reg, reg, 32, 31; \150oris reg, reg, var@h; \151ori reg, reg, var@l;152#else /* !__powerpc64__ */153#define _ENTRY(name) \154.text; \155.p2align 4; \156.globl name; \157.type name,@function; \158name: \159.cfi_startproc160#define _END(name) \161.cfi_endproc; \162.size name, . - name163164#define _NAKED_ENTRY(name) _ENTRY(name)165166#define LOAD_ADDR(reg, var) \167lis reg, var@ha; \168ori reg, reg, var@l;169#endif /* __powerpc64__ */170171#if defined(PROF) || (defined(_KERNEL) && defined(GPROF))172# ifdef __powerpc64__173# define _PROF_PROLOGUE mflr 0; \174std 3,48(1); \175std 4,56(1); \176std 5,64(1); \177std 0,16(1); \178stdu 1,-112(1); \179bl _mcount; \180nop; \181ld 0,112+16(1); \182ld 3,112+48(1); \183ld 4,112+56(1); \184ld 5,112+64(1); \185mtlr 0; \186addi 1,1,112187# else188# define _PROF_PROLOGUE mflr 0; stw 0,4(1); bl _mcount189# endif190#else191# define _PROF_PROLOGUE192#endif193194#define ASEND(y) _END(ASMNAME(y))195#define ASENTRY(y) _ENTRY(ASMNAME(y)); _PROF_PROLOGUE196#define END(y) _END(CNAME(y))197#define ENTRY(y) _ENTRY(CNAME(y)); _PROF_PROLOGUE198#define GLOBAL(y) _GLOBAL(CNAME(y))199200#define ASENTRY_NOPROF(y) _ENTRY(ASMNAME(y))201#define ENTRY_NOPROF(y) _ENTRY(CNAME(y))202203/* Load NIA without affecting branch prediction */204#define LOAD_LR_NIA bcl 20, 31, .+4205206/*207* Magic sequence to return to native endian.208* Overwrites r0 and r11.209*210* The encoding of the instruction "tdi 0, %r0, 0x48" in opposite endian211* happens to be "b . + 8". This is useful because we can write a sequence212* of instructions that can execute in either endian.213*214* Use a sequence of handcoded instructions that switches contexts to the215* instruction following the sequence, but with the correct PSL_LE bit.216*217* The same sequence works for both BE and LE because the xori will flip218* the bit to the other state, and the code only runs when running in the219* wrong endian.220*221* This sequence is NMI-reentrant.222*223* Do not change the length of this sequence without looking at the users,224* this is used in size-constrained places like the reset vector!225*/226#define RETURN_TO_NATIVE_ENDIAN \227tdi 0, %r0, 0x48; /* Endian swapped: b . + 8 */\228b 1f; /* Will fall through to here if correct */\229.long 0xa600607d; /* mfmsr %r11 */\230.long 0x00000038; /* li %r0, 0 */\231.long 0x6401617d; /* mtmsrd %r0, 1 (L=1 EE,RI bits only) */\232.long 0x01006b69; /* xori %r11, %r11, 0x1 (PSL_LE) */\233.long 0xa602087c; /* mflr %r0 */\234.long 0x05009f42; /* LOAD_LR_NIA */\235.long 0xa6037b7d; /* 0: mtsrr1 %r11 */\236.long 0xa602687d; /* mflr %r11 */\237.long 0x18006b39; /* addi %r11, %r11, (1f - 0b) */\238.long 0xa6037a7d; /* mtsrr0 %r11 */\239.long 0xa603087c; /* mtlr %r0 */\240.long 0x2400004c; /* rfid */\2411: /* RETURN_TO_NATIVE_ENDIAN */242243#define ASMSTR .asciz244245#define RCSID(x) .text; .asciz x246247#undef __FBSDID248#if !defined(lint) && !defined(STRIP_FBSDID)249#define __FBSDID(s) .ident s250#else251#define __FBSDID(s) /* nothing */252#endif /* not lint and not STRIP_FBSDID */253254#define WEAK_REFERENCE(sym, alias) \255.weak alias; \256.equ alias,sym257258#ifdef __STDC__259#define WARN_REFERENCES(_sym,_msg) \260.section .gnu.warning. ## _sym ; .ascii _msg ; .text261#else262#define WARN_REFERENCES(_sym,_msg) \263.section .gnu.warning./**/_sym ; .ascii _msg ; .text264#endif /* __STDC__ */265266#endif /* !_MACHINE_ASM_H_ */267268269