1 /*        $NetBSD: asm.h,v 1.31 2025/01/06 10:46:44 martin Exp $      */
2 
3 /*-
4  * Copyright (c) 1990 The Regents of the University of California.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * William Jolitz.
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  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *        @(#)asm.h 5.5 (Berkeley) 5/7/91
35  */
36 
37 #ifndef _SH3_ASM_H_
38 #define   _SH3_ASM_H_
39 
40 /*
41  * The old NetBSD/sh3 ELF toolchain used underscores.  The new
42  * NetBSD/sh3 ELF toolchain does not.  The C pre-processor
43  * defines __NO_LEADING_UNDERSCORES__ for the new ELF toolchain.
44  */
45 
46 #if defined(__ELF__) && defined(__NO_LEADING_UNDERSCORES__)
47 # define _C_LABEL(x)          x
48 #else
49 #ifdef __STDC__
50 # define _C_LABEL(x)          _ ## x
51 #else
52 # define _C_LABEL(x)          _/**/x
53 #endif
54 #endif
55 #define   _ASM_LABEL(x)       x
56 
57 /* let kernels and others override entrypoint alignment */
58 #ifndef _ALIGN_TEXT
59 # define _ALIGN_TEXT .align 2
60 #endif
61 
62 #ifdef __ELF__
63 #define   _ENTRY(x)                                                             \
64           .text                                                                           ;\
65           _ALIGN_TEXT                                                                     ;\
66           .globl x                                                              ;\
67           .type x,@function                                                     ;\
68           x:
69 #else /* !__ELF__ */
70 #define   _ENTRY(x)                                                             \
71           .text                                                                           ;\
72           _ALIGN_TEXT                                                                     ;\
73           .globl x                                                              ;\
74           x:
75 #endif /* !__ELF__ */
76 
77 #ifdef GPROF
78 #define   _PROF_PROLOGUE                                      \
79           mov.l     1f,r1                                   ; \
80           mova      2f,r0                                   ; \
81           jmp       @r1                                     ; \
82            nop                                              ; \
83           .align    2                                       ; \
84 1:        .long     __mcount                      ; \
85 2:
86 #else  /* !GPROF */
87 #define   _PROF_PROLOGUE
88 #endif /* !GPROF */
89 
90 #define   ENTRY(y)  _ENTRY(_C_LABEL(y)) _PROF_PROLOGUE
91 #define   NENTRY(y) _ENTRY(_C_LABEL(y))
92 #define   ASENTRY(y)          _ENTRY(_ASM_LABEL(y)) _PROF_PROLOGUE
93 
94 #define SET_ENTRY_SIZE(y) \
95           .size     _C_LABEL(y), . - _C_LABEL(y)
96 
97 #define SET_ASENTRY_SIZE(y) \
98           .size     _ASM_LABEL(y), . - _ASM_LABEL(y)
99 
100 #ifdef __ELF__
101 #define   ALTENTRY(name)                                     \
102           .globl _C_LABEL(name)                             ;\
103           .type _C_LABEL(name),@function                    ;\
104           _C_LABEL(name):
105 #else
106 #define   ALTENTRY(name)                                     \
107           .globl _C_LABEL(name)                             ;\
108           _C_LABEL(name):
109 #endif
110 
111 
112 /*
113  * Hide the gory details of PIC calls vs. normal calls.  Use as in the
114  * following example:
115  *
116  *        sts.l     pr, @-sp
117  *        PIC_PROLOGUE(.L_got, r0)      ! saves old r12 on stack
118  *        ...
119  *        mov.l     .L_function_1, r0
120  * 1:     CALL      r0                            ! each call site needs a label
121  *         nop
122  *      ...
123  *        mov.l     .L_function_2, r0
124  * 2:     CALL      r0
125  *         nop
126  *        ...
127  *        PIC_EPILOGUE                            ! restores r12 from stack
128  *        lds.l     @sp+, pr            !  so call in right order
129  *        rts
130  *         nop
131  *
132  *        .align 2
133  * .L_got:
134  *        PIC_GOT_DATUM
135  * .L_function_1:                       ! if you call the same function twice
136  *        CALL_DATUM(function, 1b)      !  provide call datum for each call
137  * .L_function_2:
138  *        CALL_DATUM(function, 2b)
139  */
140 
141 #ifdef __PIC__
142 
143 #define   PIC_PLT(x)          x@PLT
144 #define   PIC_GOT(x)          x@GOT
145 #define   PIC_GOTOFF(x)       x@GOTOFF
146 
147 #define   PIC_PROLOGUE(got)                       \
148           mov.l     r12, @-sp;                    \
149                     PIC_PROLOGUE_NOSAVE(got)
150 
151 /*
152  * Functions that do non local jumps don't need to preserve r12,
153  * so we can shave off two instructions to save/restore it.
154  */
155 #define   PIC_PROLOGUE_NOSAVE(got)                \
156           mov.l     got, r12;           \
157           mova      got, r0;            \
158           add       r0, r12
159 
160 #define   PIC_EPILOGUE                                      \
161                     mov.l     @sp+, r12
162 
163 #define PIC_EPILOGUE_SLOT                         \
164                     PIC_EPILOGUE
165 
166 #define PIC_GOT_DATUM \
167                     .long     _GLOBAL_OFFSET_TABLE_
168 
169 #define CALL        bsrf
170 #define JUMP        braf
171 
172 #define CALL_DATUM(function, lpcs) \
173                     .long     PIC_PLT(function) - ((lpcs) + 4 - (.))
174 
175 /*
176  * This will result in text relocations in the shared library,
177  * unless the function is local or has hidden or protected visibility.
178  * Does not require PIC prologue.
179  */
180 #define CALL_DATUM_LOCAL(function, lpcs) \
181                     .long     function - ((lpcs) + 4)
182 
183 #else  /* !__PIC__ */
184 
185 #define   PIC_PROLOGUE(label)
186 #define   PIC_PROLOGUE_NOSAVE(label)
187 #define   PIC_EPILOGUE
188 #define   PIC_EPILOGUE_SLOT   nop
189 #define PIC_GOT_DATUM
190 
191 #define CALL        jsr @
192 #define JUMP        jmp @
193 
194 #define CALL_DATUM(function, lpcs) \
195                     .long     function
196 
197 #define CALL_DATUM_LOCAL(function, lpcs) \
198                     .long     function
199 
200 #endif /* !__PIC__ */
201 
202 
203 #define   ASMSTR              .asciz
204 
205 #ifdef __ELF__
206 #ifdef _NETBSD_REVISIONID
207 #define RCSID(x)    .pushsection ".ident","MS",@progbits,1;           \
208                               .asciz x;                                         \
209                               .ascii "$"; .ascii "NetBSD: "; .ascii __FILE__;   \
210                               .ascii " "; .ascii _NETBSD_REVISIONID;            \
211                               .asciz " $";                                                \
212                               .popsection
213 #else
214 #define RCSID(x)    .pushsection ".ident","MS",@progbits,1;           \
215                               .asciz x;                                         \
216                               .popsection
217 #endif
218 #else
219 #define   RCSID(x)  .text; .asciz x
220 #endif
221 
222 #ifdef NO_KERNEL_RCSIDS
223 #define   __KERNEL_RCSID(_n, _s)        /* nothing */
224 #else
225 #define   __KERNEL_RCSID(_n, _s)        RCSID(_s)
226 #endif
227 
228 #ifdef __ELF__
229 #define   WEAK_ALIAS(alias,sym)                                                           \
230           .weak _C_LABEL(alias);                                                          \
231           _C_LABEL(alias) = _C_LABEL(sym)
232 #endif
233 
234 /*
235  * STRONG_ALIAS: create a strong alias.
236  */
237 #define STRONG_ALIAS(alias,sym)                                                           \
238           .globl _C_LABEL(alias);                                                         \
239           _C_LABEL(alias) = _C_LABEL(sym)
240 
241 #ifdef __STDC__
242 #define   WARN_REFERENCES(sym,msg)                                              \
243           .pushsection .gnu.warning. ## sym;                                    \
244           .ascii msg;                                                                     \
245           .popsection
246 #else
247 #define   WARN_REFERENCES(sym,msg)                                              \
248           .pushsection .gnu.warning./**/sym;                                    \
249           .ascii msg;                                                                     \
250           .popsection
251 #endif /* __STDC__ */
252 
253 #endif /* !_SH3_ASM_H_ */
254