1/* $NetBSD: asm.h,v 1.11.2.1 2026/04/02 15:59:59 martin Exp $ */
2
3/*-
4 * Copyright (c) 2014 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas of 3am Software Foundry.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#ifndef _RISCV_ASM_H
33#define _RISCV_ASM_H
34
35#define _C_LABEL(x) x
36
37#define __CONCAT(x,y) x ## y
38#define __STRING(x) #x
39
40#define ___CONCAT(x,y) __CONCAT(x,y)
41
42/*
43 * Define -pg profile entry code.
44 */
45#define _KERN_MCOUNT \
46 addi sp, sp, -CALLFRAME_SIZ; \
47 REG_S ra, CALLFRAME_RA(sp); \
48 REG_S a0, CALLFRAME_S1(sp); \
49 mv a0, ra; \
50 call PLT(_mcount); \
51 REG_L ra, CALLFRAME_RA(sp); \
52 REG_L a0, CALLFRAME_S1(sp); \
53 addi sp, sp, CALLFRAME_SIZ
54
55#ifdef GPROF
56#define _PROF_PROLOGUE _KERN_MCOUNT
57#else
58#define _PROF_PROLOGUE
59#endif
60
61#ifdef __PIC__
62#define PLT(x) x##@plt
63#else
64#define PLT(x) x
65#endif
66
67/*
68 * WEAK_ALIAS: create a weak alias.
69 */
70#define WEAK_ALIAS(alias,sym) \
71 .weak alias; \
72 alias = sym
73/*
74 * STRONG_ALIAS: create a strong alias.
75 */
76#define STRONG_ALIAS(alias,sym) \
77 .globl alias; \
78 alias = sym
79
80/*
81 * WARN_REFERENCES: create a warning if the specified symbol is referenced.
82 */
83#define WARN_REFERENCES(sym,msg) \
84 .pushsection __CONCAT(.gnu.warning.,sym); \
85 .ascii msg; \
86 .popsection
87
88#define _ENTRY(x) \
89 .globl _C_LABEL(x); \
90 .type _C_LABEL(x), @function; \
91 _C_LABEL(x):
92
93#define ENTRY_NP(x) .text; .align 2; _ENTRY(x)
94#define ENTRY(x) ENTRY_NP(x); _PROF_PROLOGUE
95#define ALTENTRY(x) _ENTRY(x)
96#define END(x) .size _C_LABEL(x), . - _C_LABEL(x)
97
98/*
99 * Macros to panic and printf from assembly language.
100 */
101#define PANIC(msg) \
102 la a0, 9f; \
103 call _C_LABEL(panic); \
104 MSG(msg)
105
106#define PRINTF(msg) \
107 la a0, 9f; \
108 call _C_LABEL(printf); \
109 MSG(msg)
110
111#define MSG(msg) \
112 .pushsection .rodata.str1.8,"aMS",@progbits,1; \
1139: .asciiz msg; \
114 .popsection
115
116#define ASMSTR(str) \
117 .asciiz str; \
118 .align 3
119
120#ifdef _NETBSD_REVISIONID
121#define __RCSID(x) .pushsection ".ident","MS",@progbits,1; \
122 .asciz x; \
123 .ascii "$"; .ascii "NetBSD: "; .ascii __FILE__; \
124 .ascii " "; .ascii _NETBSD_REVISIONID; \
125 .asciz " $"; \
126 .popsection
127#else
128#define __RCSID(x) .pushsection ".ident","MS",@progbits,1; \
129 .asciz x; \
130 .popsection
131#endif
132#define RCSID(name) __RCSID(name)
133
134#if defined(_LP64)
135#define SZREG 8
136#else
137#define SZREG 4
138#endif
139
140#define ALSK 15 /* stack alignment */
141#define ALMASK -15 /* stack alignment */
142#define SZFPREG 8
143#define FP_L fld
144#define FP_S fsd
145
146/*
147 * standard callframe {
148 * register_t cf_sp; frame pointer
149 * register_t cf_ra; return address
150 * };
151 */
152#define CALLFRAME_SIZ (SZREG * 4)
153#define CALLFRAME_S1 (CALLFRAME_SIZ - 4 * SZREG)
154#define CALLFRAME_S0 (CALLFRAME_SIZ - 3 * SZREG)
155#define CALLFRAME_SP (CALLFRAME_SIZ - 2 * SZREG)
156#define CALLFRAME_RA (CALLFRAME_SIZ - 1 * SZREG)
157
158/*
159 * These macros hide the use of rv32 and rv64 instructions from the
160 * assembler to prevent the assembler from generating 64-bit style
161 * ABI calls.
162 */
163#define PTR_ADD add
164#define PTR_ADDI addi
165#define PTR_SUB sub
166#define PTR_SUBI subi
167#define PTR_LA la
168#define PTR_SLLI slli
169#define PTR_SLL sll
170#define PTR_SRLI srli
171#define PTR_SRL srl
172#define PTR_SRAI srai
173#define PTR_SRA sra
174#if _LP64
175#define PTR_L ld
176#define PTR_S sd
177#define PTR_LR lr.d
178#define PTR_SC sc.d
179#define PTR_WORD .dword
180#define PTR_SCALESHIFT 3
181#else
182#define PTR_L lw
183#define PTR_S sw
184#define PTR_LR lr.w
185#define PTR_SC sc.w
186#define PTR_WORD .word
187#define PTR_SCALESHIFT 2
188#endif
189
190#define INT_L lw
191#define INT_LA la
192#define INT_S sw
193#define INT_LR lr.w
194#define INT_SC sc.w
195#define INT_WORD .word
196#define INT_SCALESHIFT 2
197#ifdef _LP64
198#define INT_ADD addw
199#define INT_ADDI addwi
200#define INT_SUB subw
201#define INT_SUBI subwi
202#define INT_SLL sllwi
203#define INT_SLLV sllw
204#define INT_SRL srlwi
205#define INT_SRLV srlw
206#define INT_SRA srawi
207#define INT_SRAV sraw
208#else
209#define INT_ADD add
210#define INT_ADDI addi
211#define INT_SUB sub
212#define INT_SUBI subi
213#define INT_SLLI slli
214#define INT_SLL sll
215#define INT_SRLI srli
216#define INT_SRL srl
217#define INT_SRAI srai
218#define INT_SRA sra
219#endif
220
221#define LONG_LA la
222#define LONG_ADD add
223#define LONG_ADDI addi
224#define LONG_SUB sub
225#define LONG_SUBI subi
226#define LONG_SLLI slli
227#define LONG_SLL sll
228#define LONG_SRLI srli
229#define LONG_SRL srl
230#define LONG_SRAI srai
231#define LONG_SRA sra
232#ifdef _LP64
233#define LONG_L ld
234#define LONG_S sd
235#define LONG_LR lr.d
236#define LONG_SC sc.d
237#define LONG_WORD .quad
238#define LONG_SCALESHIFT 3
239#else
240#define LONG_L lw
241#define LONG_S sw
242#define LONG_LR lr.w
243#define LONG_SC sc.w
244#define LONG_WORD .word
245#define LONG_SCALESHIFT 2
246#endif
247
248#define REG_LI li
249#define REG_ADD add
250#define REG_SLLI slli
251#define REG_SLL sll
252#define REG_SRLI srli
253#define REG_SRL srl
254#define REG_SRAI srai
255#define REG_SRA sra
256#if _LP64
257#define REG_L ld
258#define REG_S sd
259#define REG_LR lr.d
260#define REG_SC sc.d
261#define REG_SCALESHIFT 3
262#else
263#define REG_L lw
264#define REG_S sw
265#define REG_LR lr.w
266#define REG_SC sc.w
267#define REG_SCALESHIFT 2
268#endif
269
270#define CPUVAR(off) _C_LABEL(cpu_info_store)+__CONCAT(CPU_INFO_,off)
271
272#endif /* _RISCV_ASM_H */