1*bfc185c1Svisa /* $OpenBSD: asm.h,v 1.27 2021/05/01 16:11:10 visa Exp $ */ 2f58c7388Spefo 3f58c7388Spefo /* 4f58c7388Spefo * Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com) 5f58c7388Spefo * 6f58c7388Spefo * Redistribution and use in source and binary forms, with or without 7f58c7388Spefo * modification, are permitted provided that the following conditions 8f58c7388Spefo * are met: 9f58c7388Spefo * 1. Redistributions of source code must retain the above copyright 10f58c7388Spefo * notice, this list of conditions and the following disclaimer. 11f58c7388Spefo * 2. Redistributions in binary form must reproduce the above copyright 12f58c7388Spefo * notice, this list of conditions and the following disclaimer in the 13f58c7388Spefo * documentation and/or other materials provided with the distribution. 14f58c7388Spefo * 15f58c7388Spefo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16f58c7388Spefo * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17f58c7388Spefo * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18f58c7388Spefo * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 19f58c7388Spefo * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20f58c7388Spefo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21f58c7388Spefo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22f58c7388Spefo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23f58c7388Spefo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24f58c7388Spefo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25f58c7388Spefo * SUCH DAMAGE. 26f58c7388Spefo * 27f58c7388Spefo */ 282fa72412Spirofti #ifndef _MIPS64_ASM_H_ 292fa72412Spirofti #define _MIPS64_ASM_H_ 30f58c7388Spefo 31f58c7388Spefo #include <machine/regdef.h> 32f58c7388Spefo 33f58c7388Spefo #define _MIPS_ISA_MIPS1 1 /* R2000/R3000 */ 34f58c7388Spefo #define _MIPS_ISA_MIPS2 2 /* R4000/R6000 */ 35f58c7388Spefo #define _MIPS_ISA_MIPS3 3 /* R4000 */ 36f58c7388Spefo #define _MIPS_ISA_MIPS4 4 /* TFP (R1x000) */ 370fa15b16Svisa #define _MIPS_ISA_MIPS32 32 /* MIPS32 */ 380fa15b16Svisa #define _MIPS_ISA_MIPS64 64 /* MIPS64 */ 39f58c7388Spefo 40f58c7388Spefo #if !defined(ABICALLS) && !defined(_NO_ABICALLS) 41f58c7388Spefo #define ABICALLS .abicalls 42f58c7388Spefo #endif 43f58c7388Spefo 44f58c7388Spefo #if defined(ABICALLS) && !defined(_KERNEL) 45f58c7388Spefo ABICALLS 46f58c7388Spefo #endif 47f58c7388Spefo 48f58c7388Spefo #define _C_LABEL(x) x /* XXX Obsolete but keep for a while */ 49f58c7388Spefo 50f58c7388Spefo #if !defined(__MIPSEL__) && !defined(__MIPSEB__) 51f58c7388Spefo #error "__MIPSEL__ or __MIPSEB__ must be defined" 52f58c7388Spefo #endif 53f58c7388Spefo /* 54f58c7388Spefo * Define how to access unaligned data word 55f58c7388Spefo */ 56f58c7388Spefo #if defined(__MIPSEL__) 57f58c7388Spefo #define LWLO lwl 58f58c7388Spefo #define LWHI lwr 59f58c7388Spefo #define SWLO swl 60f58c7388Spefo #define SWHI swr 61f58c7388Spefo #define LDLO ldl 62f58c7388Spefo #define LDHI ldr 63f58c7388Spefo #define SDLO sdl 64f58c7388Spefo #define SDHI sdr 65f58c7388Spefo #endif 66f58c7388Spefo #if defined(__MIPSEB__) 67f58c7388Spefo #define LWLO lwr 68f58c7388Spefo #define LWHI lwl 69f58c7388Spefo #define SWLO swr 70f58c7388Spefo #define SWHI swl 71f58c7388Spefo #define LDLO ldr 72f58c7388Spefo #define LDHI ldl 73f58c7388Spefo #define SDLO sdr 74f58c7388Spefo #define SDHI sdl 75f58c7388Spefo #endif 76f58c7388Spefo 77f58c7388Spefo /* 78f58c7388Spefo * Define programming environment for ABI. 79f58c7388Spefo */ 80f58c7388Spefo #if defined(ABICALLS) && !defined(_KERNEL) && !defined(_STANDALONE) 81f58c7388Spefo 82f58c7388Spefo #ifndef _MIPS_SIM 83f58c7388Spefo #define _MIPS_SIM 1 84f58c7388Spefo #define _ABIO32 1 85f58c7388Spefo #endif 86f58c7388Spefo #ifndef _MIPS_ISA 87f58c7388Spefo #define _MIPS_ISA 2 88f58c7388Spefo #define _MIPS_ISA_MIPS2 2 89f58c7388Spefo #endif 90f58c7388Spefo 91f58c7388Spefo #if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32) 92f58c7388Spefo #define NARGSAVE 4 93f58c7388Spefo 94f58c7388Spefo #define SETUP_GP \ 95f58c7388Spefo .set noreorder; \ 96f58c7388Spefo .cpload t9; \ 97f58c7388Spefo .set reorder; 98f58c7388Spefo 99f58c7388Spefo #define SAVE_GP(x) \ 100f58c7388Spefo .cprestore x 101f58c7388Spefo 1024a63270fSpefo #define SETUP_GP64(gpoff, name) 1034a63270fSpefo #define RESTORE_GP64 104f58c7388Spefo #endif 105f58c7388Spefo 106f58c7388Spefo #if (_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32) 107f58c7388Spefo #define NARGSAVE 0 108f58c7388Spefo 109f58c7388Spefo #define SETUP_GP 110f58c7388Spefo #define SAVE_GP(x) 1114a63270fSpefo #define SETUP_GP64(gpoff, name) \ 1124a63270fSpefo .cpsetup t9, gpoff, name 1134a63270fSpefo #define RESTORE_GP64 \ 1144a63270fSpefo .cpreturn 115f58c7388Spefo #endif 116f58c7388Spefo 1174a63270fSpefo #define MKFSIZ(narg,locals) (((narg+locals)*REGSZ+31)&(~31)) 1184a63270fSpefo 119f58c7388Spefo #else /* defined(ABICALLS) && !defined(_KERNEL) */ 120f58c7388Spefo 121f58c7388Spefo #define NARGSAVE 4 122f58c7388Spefo #define SETUP_GP 123f58c7388Spefo #define SAVE_GP(x) 124f58c7388Spefo 125f58c7388Spefo #define ALIGNSZ 16 /* Stack layout alignment */ 126f58c7388Spefo #define FRAMESZ(sz) (((sz) + (ALIGNSZ-1)) & ~(ALIGNSZ-1)) 127f58c7388Spefo 1284a63270fSpefo #endif 1294a63270fSpefo 130f58c7388Spefo /* 131f58c7388Spefo * Basic register operations based on selected ISA 132f58c7388Spefo */ 1330fa15b16Svisa #if (_MIPS_ISA == _MIPS_ISA_MIPS1 || _MIPS_ISA == _MIPS_ISA_MIPS2 || \ 1340fa15b16Svisa _MIPS_ISA == _MIPS_ISA_MIPS32) 135f58c7388Spefo #define REGSZ 4 /* 32 bit mode register size */ 136f58c7388Spefo #define LOGREGSZ 2 /* log rsize */ 137f58c7388Spefo #define REG_S sw 138f58c7388Spefo #define REG_L lw 139f58c7388Spefo #define CF_SZ 24 /* Call frame size */ 140f58c7388Spefo #define CF_ARGSZ 16 /* Call frame arg size */ 141f58c7388Spefo #define CF_RA_OFFS 20 /* Call ra save offset */ 142f58c7388Spefo #endif 143f58c7388Spefo 1440fa15b16Svisa #if (_MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4 || \ 1450fa15b16Svisa _MIPS_ISA == _MIPS_ISA_MIPS64) 146f58c7388Spefo #define REGSZ 8 /* 64 bit mode register size */ 147f58c7388Spefo #define LOGREGSZ 3 /* log rsize */ 148f58c7388Spefo #define REG_S sd 149f58c7388Spefo #define REG_L ld 150f58c7388Spefo #define CF_SZ 48 /* Call frame size (multiple of ALIGNSZ) */ 151f58c7388Spefo #define CF_ARGSZ 32 /* Call frame arg size */ 152f58c7388Spefo #define CF_RA_OFFS 40 /* Call ra save offset */ 153f58c7388Spefo #endif 154f58c7388Spefo 155195da3bdSmiod #ifndef __LP64__ 156195da3bdSmiod #define PTR_L lw 157195da3bdSmiod #define PTR_S sw 158195da3bdSmiod #define PTR_SUB sub 159195da3bdSmiod #define PTR_ADD add 160195da3bdSmiod #define PTR_SUBU subu 161195da3bdSmiod #define PTR_ADDU addu 162195da3bdSmiod #define LI li 163195da3bdSmiod #define LA la 164195da3bdSmiod #define PTR_SLL sll 165195da3bdSmiod #define PTR_SRL srl 166195da3bdSmiod #define PTR_VAL .word 167195da3bdSmiod #else 168f58c7388Spefo #define PTR_L ld 169f58c7388Spefo #define PTR_S sd 170f58c7388Spefo #define PTR_ADD dadd 171f58c7388Spefo #define PTR_SUB dsub 172f58c7388Spefo #define PTR_SUBU dsubu 173f58c7388Spefo #define PTR_ADDU daddu 174f58c7388Spefo #define LI dli 175f58c7388Spefo #define LA dla 176f58c7388Spefo #define PTR_SLL dsll 177f58c7388Spefo #define PTR_SRL dsrl 178f58c7388Spefo #define PTR_VAL .dword 179195da3bdSmiod #endif 180f58c7388Spefo 18199068adfSmiod #define NOP nop 18299068adfSmiod #define DMFC0 dmfc0 18399068adfSmiod #define DMTC0 dmtc0 18499068adfSmiod #define MFC0 mfc0 18599068adfSmiod #define MTC0 mtc0 18699068adfSmiod #define ERET sync; eret 18799068adfSmiod 188f58c7388Spefo /* 189f58c7388Spefo * Define -pg profile entry code. 190f58c7388Spefo */ 191f58c7388Spefo #if defined(XGPROF) || defined(XPROF) 192f58c7388Spefo #define MCOUNT \ 19350027fe1Smiod PTR_SUBU sp, sp, 64; \ 194f58c7388Spefo SAVE_GP(16); \ 19550027fe1Smiod sd ra, 56(sp); \ 19650027fe1Smiod sd gp, 48(sp); \ 197f58c7388Spefo .set noat; \ 198f58c7388Spefo .set noreorder; \ 199f58c7388Spefo move AT, ra; \ 200f58c7388Spefo jal _mcount; \ 20150027fe1Smiod PTR_SUBU sp, sp, 16; \ 20250027fe1Smiod ld ra, 56(sp); \ 20350027fe1Smiod PTR_ADDU sp, sp, 64; \ 204f58c7388Spefo .set reorder; \ 205f58c7388Spefo .set at; 206f58c7388Spefo #else 207f58c7388Spefo #define MCOUNT 208f58c7388Spefo #endif 209f58c7388Spefo 210f58c7388Spefo /* 2114a63270fSpefo * LEAF(x, fsize) 212f58c7388Spefo * 213f58c7388Spefo * Declare a leaf routine. 214f58c7388Spefo */ 2154a63270fSpefo #define LEAF(x, fsize) \ 216f58c7388Spefo .align 3; \ 217f58c7388Spefo .globl x; \ 218f58c7388Spefo .ent x, 0; \ 219f58c7388Spefo x: ; \ 2204a63270fSpefo .frame sp, fsize, ra; \ 221f58c7388Spefo SETUP_GP \ 222f58c7388Spefo MCOUNT 223f58c7388Spefo 224f58c7388Spefo #define ALEAF(x) \ 225f58c7388Spefo .globl x; \ 226f58c7388Spefo x: 227f58c7388Spefo 228f58c7388Spefo /* 229f58c7388Spefo * NLEAF(x) 230f58c7388Spefo * 231f58c7388Spefo * Declare a non-profiled leaf routine. 232f58c7388Spefo */ 2334a63270fSpefo #define NLEAF(x, fsize) \ 234f58c7388Spefo .align 3; \ 235f58c7388Spefo .globl x; \ 236f58c7388Spefo .ent x, 0; \ 237f58c7388Spefo x: ; \ 2384a63270fSpefo .frame sp, fsize, ra; \ 239f58c7388Spefo SETUP_GP 240f58c7388Spefo 241f58c7388Spefo /* 242f58c7388Spefo * NON_LEAF(x) 243f58c7388Spefo * 244f58c7388Spefo * Declare a non-leaf routine (a routine that makes other C calls). 245f58c7388Spefo */ 246f58c7388Spefo #define NON_LEAF(x, fsize, retpc) \ 247f58c7388Spefo .align 3; \ 248f58c7388Spefo .globl x; \ 249f58c7388Spefo .ent x, 0; \ 250f58c7388Spefo x: ; \ 251f58c7388Spefo .frame sp, fsize, retpc; \ 252f58c7388Spefo SETUP_GP \ 253f58c7388Spefo MCOUNT 254f58c7388Spefo 255f58c7388Spefo /* 256f58c7388Spefo * NNON_LEAF(x) 257f58c7388Spefo * 258f58c7388Spefo * Declare a non-profiled non-leaf routine 259f58c7388Spefo * (a routine that makes other C calls). 260f58c7388Spefo */ 261f58c7388Spefo #define NNON_LEAF(x, fsize, retpc) \ 262f58c7388Spefo .align 3; \ 263f58c7388Spefo .globl x; \ 264f58c7388Spefo .ent x, 0; \ 265f58c7388Spefo x: ; \ 266f58c7388Spefo .frame sp, fsize, retpc \ 267f58c7388Spefo SETUP_GP 268f58c7388Spefo 269f58c7388Spefo /* 270f58c7388Spefo * END(x) 271f58c7388Spefo * 272f58c7388Spefo * Mark end of a procedure. 273f58c7388Spefo */ 274f58c7388Spefo #define END(x) \ 275f58c7388Spefo .end x 276f58c7388Spefo 277f58c7388Spefo /* 2785a25e2caSmartynas * STRONG_ALIAS, WEAK_ALIAS 2795a25e2caSmartynas * Create a strong or weak alias. 280eca0a8dbSguenther */ 2815a25e2caSmartynas #define STRONG_ALIAS(alias,sym) \ 2825a25e2caSmartynas .global alias; alias = sym 283eca0a8dbSguenther #define WEAK_ALIAS(alias,sym) \ 284eca0a8dbSguenther .weak alias; alias = sym 285eca0a8dbSguenther 286eca0a8dbSguenther 287eca0a8dbSguenther /* 288f58c7388Spefo * Macros to panic and printf from assembly language. 289f58c7388Spefo */ 290f58c7388Spefo #define PANIC(msg) \ 2914a63270fSpefo LA a0, 9f; \ 292f58c7388Spefo jal panic; \ 293f58c7388Spefo nop ; \ 294f58c7388Spefo MSG(msg) 295f58c7388Spefo 296f58c7388Spefo #define PRINTF(msg) \ 29750027fe1Smiod LA a0, 9f; \ 298f58c7388Spefo jal printf; \ 299f58c7388Spefo nop ; \ 300f58c7388Spefo MSG(msg) 301f58c7388Spefo 302f58c7388Spefo #define MSG(msg) \ 303f58c7388Spefo .rdata; \ 304f58c7388Spefo 9: .asciiz msg; \ 305f58c7388Spefo .text 306f58c7388Spefo 307c1805af1Smiod #define LOAD_XKPHYS(reg, cca) \ 308c1805af1Smiod li reg, cca | 0x10; \ 309c1805af1Smiod dsll reg, reg, 59 310c1805af1Smiod 3111b9cca20Ssyuu #ifdef MULTIPROCESSOR 3121d6e3571Ssyuu #define GET_CPU_INFO(ci, tmp) HW_GET_CPU_INFO(ci, tmp) 3131b9cca20Ssyuu #else /* MULTIPROCESSOR */ 3141b9cca20Ssyuu #define GET_CPU_INFO(ci, tmp) \ 3151b9cca20Ssyuu LA ci, cpu_info_primary 3161b9cca20Ssyuu #endif /* MULTIPROCESSOR */ 3171b9cca20Ssyuu 3183b05e32eSmiod /* 3193b05e32eSmiod * Hazards 3203b05e32eSmiod */ 3213b05e32eSmiod 322692dc7b2Svisa #ifdef CPU_OCTEON 323692dc7b2Svisa /* 324692dc7b2Svisa * OCTEON clears hazards in hardware. 325692dc7b2Svisa */ 326692dc7b2Svisa #define MFC0_HAZARD /* nothing */ 327692dc7b2Svisa #define MTC0_HAZARD /* nothing */ 328692dc7b2Svisa #define MTC0_SR_IE_HAZARD /* nothing */ 329692dc7b2Svisa #define MTC0_SR_CU_HAZARD /* nothing */ 330692dc7b2Svisa #define TLB_HAZARD /* nothing */ 331692dc7b2Svisa #endif 332692dc7b2Svisa 3333b05e32eSmiod /* Hazard between {d,}mfc0 of COP_0_VADDR */ 3343b05e32eSmiod #ifndef PRE_MFC0_ADDR_HAZARD 3353b05e32eSmiod #define PRE_MFC0_ADDR_HAZARD /* nothing */ 3363b05e32eSmiod #endif 3373b05e32eSmiod 3383b05e32eSmiod /* Hazard after {d,}mfc0 from any register */ 3393b05e32eSmiod #ifndef MFC0_HAZARD 3403b05e32eSmiod #define MFC0_HAZARD /* nothing */ 3413b05e32eSmiod #endif 3423b05e32eSmiod /* Hazard after {d,}mtc0 to any register */ 3433b05e32eSmiod #ifndef MTC0_HAZARD 3443b05e32eSmiod #define MTC0_HAZARD NOP; NOP; NOP; NOP 3453b05e32eSmiod #endif 3463b05e32eSmiod /* Hazard after {d,}mtc0 to COP_0_SR affecting the state of interrupts */ 3473b05e32eSmiod #ifndef MTC0_SR_IE_HAZARD 3483b05e32eSmiod #define MTC0_SR_IE_HAZARD MTC0_HAZARD 3493b05e32eSmiod #endif 3503b05e32eSmiod /* Hazard after {d,}mtc0 to COP_0_SR affecting the state of coprocessors */ 3513b05e32eSmiod #ifndef MTC0_SR_CU_HAZARD 3523b05e32eSmiod #define MTC0_SR_CU_HAZARD NOP; NOP 3533b05e32eSmiod #endif 3543b05e32eSmiod 3553b05e32eSmiod /* Hazard before and after a tlbp, tlbr, tlbwi or tlbwr instruction */ 3563b05e32eSmiod #ifndef TLB_HAZARD 3573b05e32eSmiod #define TLB_HAZARD NOP; NOP 3583b05e32eSmiod #endif 3593b05e32eSmiod 3602fa72412Spirofti #endif /* !_MIPS64_ASM_H_ */ 361