1/*	$NetBSD: asm.h,v 1.2 2015/03/27 06:57:21 matt 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/*
38 * Define -pg profile entry code.
39 * Must always be noreorder, must never use a macro instruction
40 * Final addiu to t9 must always equal the size of this _KERN_MCOUNT
41 */
42#define	_KERN_MCOUNT						\
43	.set	push;						\
44	subi	sp, sp, CALLFRAME_SIZE;				\
45	REG_S	a0, CALLFRAME_S0(sp);				\
46	REG_S	ra, CALLFRAME_RA(sp);				\
47	move	a0, ra;						\
48	call	_mcount 					\
49	REG_L	ra, CALLFRAME_RA(sp);				\
50	REG_L	a0, CALLFRAME_S0(sp);				\
51	addi	sp, sp, CALLFRAME_SIZ;				\
52	.set	pop;
53
54#ifdef GPROF
55#define	_PROF_PROLOGUE _KERN_MCOUNT
56#else
57#define	_PROF_PROLOGUE
58#endif
59
60#ifdef __PIC__
61#define	PLT(x)	x##@
62#else
63#define PLT(x)	x
64#endif
65
66/*
67 * WEAK_ALIAS: create a weak alias.
68 */
69#define	WEAK_ALIAS(alias,sym)						\
70	.weak alias;							\
71	alias = sym
72/*
73 * STRONG_ALIAS: create a strong alias.
74 */
75#define	STRONG_ALIAS(alias,sym)						\
76	.globl alias;							\
77	alias = sym
78
79/*
80 * WARN_REFERENCES: create a warning if the specified symbol is referenced.
81 */
82#define	WARN_REFERENCES(sym,msg)					\
83	.pushsection __CONCAT(.gnu.warning.,sym);			\
84	.ascii msg;							\
85	.popsection
86
87#define	_ENTRY(x)			\
88	.globl	_C_LABEL(x);		\
89	.type	_C_LABEL(x), @function;	\
90	_C_LABEL(x):
91
92#define	ENTRY_NP(x)	.text; .align 2; _ENTRY(x)
93#define	ENTRY(x)	ENTRY_NP(x); _PROF_PROLOGUE
94#define	END(x)		.size _C_LABEL(x), . - _C_LABEL(x)
95
96/*
97 * Macros to panic and printf from assembly language.
98 */
99#define	PANIC(msg)			\
100	la	a0, 9f;			\
101	call	_C_LABEL(panic);	\
102	MSG(msg)
103
104#define	PRINTF(msg)			\
105	la	a0, 9f;			\
106	call	_C_LABEL(printf);	\
107	MSG(msg)
108
109#define	MSG(msg)			\
110        .pushsection .rodata.str1.8,"aMS",@progbits,1; \
1119:	.asciiz	msg;			\
112	.popsection
113
114#define	ASMSTR(str)			\
115	.asciiz str;			\
116	.align	3
117
118#define	__RCSID(name)	.pushsection ".ident"; .asciz name; .popsection
119#define RCSID(name)	__RCSID(name)
120
121#if defined(_LP64)
122#define	SZREG	8
123#else
124#define	SZREG	4
125#endif
126
127#define	ALSK	15		/* stack alignment */
128#define	ALMASK	-15		/* stack alignment */
129#define	SZFPREG	8
130#define	FP_L	fld
131#define	FP_S	fsd
132
133/*
134 *  standard callframe {
135 *  	register_t cf_sp;		frame pointer
136 *  	register_t cf_ra;		return address
137 *  };
138 */
139#define	CALLFRAME_SIZ	(SZREG * 4)
140#define	CALLFRAME_S1	(CALLFRAME_SIZ - 4 * SZREG)
141#define	CALLFRAME_S0	(CALLFRAME_SIZ - 3 * SZREG)
142#define	CALLFRAME_SP	(CALLFRAME_SIZ - 2 * SZREG)
143#define	CALLFRAME_RA	(CALLFRAME_SIZ - 1 * SZREG)
144
145/*
146 * These macros hide the use of rv32 and rv64 instructions from the
147 * assembler to prevent the assembler from generating 64-bit style
148 * ABI calls.
149 */
150#define	PTR_ADD		add
151#define	PTR_ADDI	addi
152#define	PTR_SUB		sub
153#define	PTR_SUBI	subi
154#define	PTR_LA		la
155#define	PTR_SLLI	slli
156#define	PTR_SLL		sll
157#define	PTR_SRLI	srli
158#define	PTR_SRL		srl
159#define	PTR_SRAI	srai
160#define	PTR_SRA		sra
161#if _LP64
162#define	PTR_L		ld
163#define	PTR_S		sd
164#define	PTR_LR		lr.d
165#define	PTR_SC		sc.d
166#define	PTR_WORD	.dword
167#define	PTR_SCALESHIFT	3
168#else
169#define	PTR_L		lw
170#define	PTR_S		sw
171#define	PTR_LR		lr.w
172#define	PTR_SC		sc.w
173#define	PTR_WORD	.word
174#define	PTR_SCALESHIFT	2
175#endif
176
177#define	INT_L		lw
178#define	INT_LA		la
179#define	INT_S		sw
180#define	INT_LR		lr.w
181#define	INT_SC		sc.w
182#define	INT_WORD	.word
183#define	INT_SCALESHIFT	2
184#ifdef _LP64
185#define	INT_ADD		addw
186#define	INT_ADDI	addwi
187#define	INT_SUB		subw
188#define	INT_SUBI	subwi
189#define	INT_SLL		sllwi
190#define	INT_SLLV	sllw
191#define	INT_SRL		srlwi
192#define	INT_SRLV	srlw
193#define	INT_SRA		srawi
194#define	INT_SRAV	sraw
195#else
196#define	INT_ADD		add
197#define	INT_ADDI	addi
198#define	INT_SUB		sub
199#define	INT_SUBI	subi
200#define	INT_SLLI	slli
201#define	INT_SLL		sll
202#define	INT_SRLI	srli
203#define	INT_SRL		srl
204#define	INT_SRAI	srai
205#define	INT_SRA		sra
206#endif
207
208#define	LONG_LA		la
209#define	LONG_ADD	add
210#define	LONG_ADDI	addi
211#define	LONG_SUB	sub
212#define	LONG_SUBI	subi
213#define	LONG_SLLI	slli
214#define	LONG_SLL	sll
215#define	LONG_SRLI	srli
216#define	LONG_SRL	srl
217#define	LONG_SRAI	srai
218#define	LONG_SRA	sra
219#ifdef _LP64
220#define	LONG_L		ld
221#define	LONG_S		sd
222#define	LONG_LR		lr.d
223#define	LONG_SC		sc.d
224#define	LONG_WORD	.quad
225#define	LONG_SCALESHIFT	3
226#else
227#define	LONG_L		lw
228#define	LONG_S		sw
229#define	LONG_LR		lr.w
230#define	LONG_SC		sc.w
231#define	LONG_WORD	.word
232#define	LONG_SCALESHIFT	2
233#endif
234
235#define	REG_LI		li
236#define	REG_ADD		add
237#define	REG_SLLI	slli
238#define	REG_SLL		sll
239#define	REG_SRLI	srli
240#define	REG_SRL		srl
241#define	REG_SRAI	srai
242#define	REG_SRA		sra
243#if _LP64
244#define	REG_L		ld
245#define	REG_S		sd
246#define	REG_LR		lr.d
247#define	REG_SC		sc.d
248#define	REG_SCALESHIFT	3
249#else
250#define	REG_L		lw
251#define	REG_S		sw
252#define	REG_LR		lr.w
253#define	REG_SC		sc.w
254#define	REG_SCALESHIFT	2
255#endif
256
257#define	CPUVAR(off) _C_LABEL(cpu_info_store)+__CONCAT(CPU_INFO_,off)
258
259#endif /* _RISCV_ASM_H */
260