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