1/* $OpenBSD: asm.h,v 1.27 2021/05/01 16:11:10 visa Exp $ */
2
3/*
4 * Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com)
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 */
28#ifndef _MIPS64_ASM_H_
29#define _MIPS64_ASM_H_
30
31#include <machine/regdef.h>
32
33#define _MIPS_ISA_MIPS1 1 /* R2000/R3000 */
34#define _MIPS_ISA_MIPS2 2 /* R4000/R6000 */
35#define _MIPS_ISA_MIPS3 3 /* R4000 */
36#define _MIPS_ISA_MIPS4 4 /* TFP (R1x000) */
37#define _MIPS_ISA_MIPS32 32 /* MIPS32 */
38#define _MIPS_ISA_MIPS64 64 /* MIPS64 */
39
40#if !defined(ABICALLS) && !defined(_NO_ABICALLS)
41#define ABICALLS .abicalls
42#endif
43
44#if defined(ABICALLS) && !defined(_KERNEL)
45 ABICALLS
46#endif
47
48#define _C_LABEL(x) x /* XXX Obsolete but keep for a while */
49
50#if !defined(__MIPSEL__) && !defined(__MIPSEB__)
51#error "__MIPSEL__ or __MIPSEB__ must be defined"
52#endif
53/*
54 * Define how to access unaligned data word
55 */
56#if defined(__MIPSEL__)
57#define LWLO lwl
58#define LWHI lwr
59#define SWLO swl
60#define SWHI swr
61#define LDLO ldl
62#define LDHI ldr
63#define SDLO sdl
64#define SDHI sdr
65#endif
66#if defined(__MIPSEB__)
67#define LWLO lwr
68#define LWHI lwl
69#define SWLO swr
70#define SWHI swl
71#define LDLO ldr
72#define LDHI ldl
73#define SDLO sdr
74#define SDHI sdl
75#endif
76
77/*
78 * Define programming environment for ABI.
79 */
80#if defined(ABICALLS) && !defined(_KERNEL) && !defined(_STANDALONE)
81
82#ifndef _MIPS_SIM
83#define _MIPS_SIM 1
84#define _ABIO32 1
85#endif
86#ifndef _MIPS_ISA
87#define _MIPS_ISA 2
88#define _MIPS_ISA_MIPS2 2
89#endif
90
91#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
92#define NARGSAVE 4
93
94#define SETUP_GP \
95 .set noreorder; \
96 .cpload t9; \
97 .set reorder;
98
99#define SAVE_GP(x) \
100 .cprestore x
101
102#define SETUP_GP64(gpoff, name)
103#define RESTORE_GP64
104#endif
105
106#if (_MIPS_SIM == _ABI64) || (_MIPS_SIM == _ABIN32)
107#define NARGSAVE 0
108
109#define SETUP_GP
110#define SAVE_GP(x)
111#define SETUP_GP64(gpoff, name) \
112 .cpsetup t9, gpoff, name
113#define RESTORE_GP64 \
114 .cpreturn
115#endif
116
117#define MKFSIZ(narg,locals) (((narg+locals)*REGSZ+31)&(~31))
118
119#else /* defined(ABICALLS) && !defined(_KERNEL) */
120
121#define NARGSAVE 4
122#define SETUP_GP
123#define SAVE_GP(x)
124
125#define ALIGNSZ 16 /* Stack layout alignment */
126#define FRAMESZ(sz) (((sz) + (ALIGNSZ-1)) & ~(ALIGNSZ-1))
127
128#endif
129
130/*
131 * Basic register operations based on selected ISA
132 */
133#if (_MIPS_ISA == _MIPS_ISA_MIPS1 || _MIPS_ISA == _MIPS_ISA_MIPS2 || \
134 _MIPS_ISA == _MIPS_ISA_MIPS32)
135#define REGSZ 4 /* 32 bit mode register size */
136#define LOGREGSZ 2 /* log rsize */
137#define REG_S sw
138#define REG_L lw
139#define CF_SZ 24 /* Call frame size */
140#define CF_ARGSZ 16 /* Call frame arg size */
141#define CF_RA_OFFS 20 /* Call ra save offset */
142#endif
143
144#if (_MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4 || \
145 _MIPS_ISA == _MIPS_ISA_MIPS64)
146#define REGSZ 8 /* 64 bit mode register size */
147#define LOGREGSZ 3 /* log rsize */
148#define REG_S sd
149#define REG_L ld
150#define CF_SZ 48 /* Call frame size (multiple of ALIGNSZ) */
151#define CF_ARGSZ 32 /* Call frame arg size */
152#define CF_RA_OFFS 40 /* Call ra save offset */
153#endif
154
155#ifndef __LP64__
156#define PTR_L lw
157#define PTR_S sw
158#define PTR_SUB sub
159#define PTR_ADD add
160#define PTR_SUBU subu
161#define PTR_ADDU addu
162#define LI li
163#define LA la
164#define PTR_SLL sll
165#define PTR_SRL srl
166#define PTR_VAL .word
167#else
168#define PTR_L ld
169#define PTR_S sd
170#define PTR_ADD dadd
171#define PTR_SUB dsub
172#define PTR_SUBU dsubu
173#define PTR_ADDU daddu
174#define LI dli
175#define LA dla
176#define PTR_SLL dsll
177#define PTR_SRL dsrl
178#define PTR_VAL .dword
179#endif
180
181#define NOP nop
182#define DMFC0 dmfc0
183#define DMTC0 dmtc0
184#define MFC0 mfc0
185#define MTC0 mtc0
186#define ERET sync; eret
187
188/*
189 * Define -pg profile entry code.
190 */
191#if defined(XGPROF) || defined(XPROF)
192#define MCOUNT \
193 PTR_SUBU sp, sp, 64; \
194 SAVE_GP(16); \
195 sd ra, 56(sp); \
196 sd gp, 48(sp); \
197 .set noat; \
198 .set noreorder; \
199 move AT, ra; \
200 jal _mcount; \
201 PTR_SUBU sp, sp, 16; \
202 ld ra, 56(sp); \
203 PTR_ADDU sp, sp, 64; \
204 .set reorder; \
205 .set at;
206#else
207#define MCOUNT
208#endif
209
210/*
211 * LEAF(x, fsize)
212 *
213 * Declare a leaf routine.
214 */
215#define LEAF(x, fsize) \
216 .align 3; \
217 .globl x; \
218 .ent x, 0; \
219x: ; \
220 .frame sp, fsize, ra; \
221 SETUP_GP \
222 MCOUNT
223
224#define ALEAF(x) \
225 .globl x; \
226x:
227
228/*
229 * NLEAF(x)
230 *
231 * Declare a non-profiled leaf routine.
232 */
233#define NLEAF(x, fsize) \
234 .align 3; \
235 .globl x; \
236 .ent x, 0; \
237x: ; \
238 .frame sp, fsize, ra; \
239 SETUP_GP
240
241/*
242 * NON_LEAF(x)
243 *
244 * Declare a non-leaf routine (a routine that makes other C calls).
245 */
246#define NON_LEAF(x, fsize, retpc) \
247 .align 3; \
248 .globl x; \
249 .ent x, 0; \
250x: ; \
251 .frame sp, fsize, retpc; \
252 SETUP_GP \
253 MCOUNT
254
255/*
256 * NNON_LEAF(x)
257 *
258 * Declare a non-profiled non-leaf routine
259 * (a routine that makes other C calls).
260 */
261#define NNON_LEAF(x, fsize, retpc) \
262 .align 3; \
263 .globl x; \
264 .ent x, 0; \
265x: ; \
266 .frame sp, fsize, retpc \
267 SETUP_GP
268
269/*
270 * END(x)
271 *
272 * Mark end of a procedure.
273 */
274#define END(x) \
275 .end x
276
277/*
278 * STRONG_ALIAS, WEAK_ALIAS
279 * Create a strong or weak alias.
280 */
281#define STRONG_ALIAS(alias,sym) \
282 .global alias; alias = sym
283#define WEAK_ALIAS(alias,sym) \
284 .weak alias; alias = sym
285
286
287/*
288 * Macros to panic and printf from assembly language.
289 */
290#define PANIC(msg) \
291 LA a0, 9f; \
292 jal panic; \
293 nop ; \
294 MSG(msg)
295
296#define PRINTF(msg) \
297 LA a0, 9f; \
298 jal printf; \
299 nop ; \
300 MSG(msg)
301
302#define MSG(msg) \
303 .rdata; \
3049: .asciiz msg; \
305 .text
306
307#define LOAD_XKPHYS(reg, cca) \
308 li reg, cca | 0x10; \
309 dsll reg, reg, 59
310
311#ifdef MULTIPROCESSOR
312#define GET_CPU_INFO(ci, tmp) HW_GET_CPU_INFO(ci, tmp)
313#else /* MULTIPROCESSOR */
314#define GET_CPU_INFO(ci, tmp) \
315 LA ci, cpu_info_primary
316#endif /* MULTIPROCESSOR */
317
318/*
319 * Hazards
320 */
321
322#ifdef CPU_OCTEON
323/*
324 * OCTEON clears hazards in hardware.
325 */
326#define MFC0_HAZARD /* nothing */
327#define MTC0_HAZARD /* nothing */
328#define MTC0_SR_IE_HAZARD /* nothing */
329#define MTC0_SR_CU_HAZARD /* nothing */
330#define TLB_HAZARD /* nothing */
331#endif
332
333/* Hazard between {d,}mfc0 of COP_0_VADDR */
334#ifndef PRE_MFC0_ADDR_HAZARD
335#define PRE_MFC0_ADDR_HAZARD /* nothing */
336#endif
337
338/* Hazard after {d,}mfc0 from any register */
339#ifndef MFC0_HAZARD
340#define MFC0_HAZARD /* nothing */
341#endif
342/* Hazard after {d,}mtc0 to any register */
343#ifndef MTC0_HAZARD
344#define MTC0_HAZARD NOP; NOP; NOP; NOP
345#endif
346/* Hazard after {d,}mtc0 to COP_0_SR affecting the state of interrupts */
347#ifndef MTC0_SR_IE_HAZARD
348#define MTC0_SR_IE_HAZARD MTC0_HAZARD
349#endif
350/* Hazard after {d,}mtc0 to COP_0_SR affecting the state of coprocessors */
351#ifndef MTC0_SR_CU_HAZARD
352#define MTC0_SR_CU_HAZARD NOP; NOP
353#endif
354
355/* Hazard before and after a tlbp, tlbr, tlbwi or tlbwr instruction */
356#ifndef TLB_HAZARD
357#define TLB_HAZARD NOP; NOP
358#endif
359
360#endif /* !_MIPS64_ASM_H_ */