1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1987 by Sun Microsystems, Inc. 24 */ 25 26 #ifndef _SYS_ASM_LINKAGE_H 27 #define _SYS_ASM_LINKAGE_H 28 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 /* from SunOS 4.0 1.4 */ 31 32 /* allow word aligned user stacks */ 33 #define PARTIAL_ALIGN 34 35 /* 36 * A stack frame looks like: 37 * 38 * %fp->| | 39 * |-------------------------------| 40 * | Locals, temps, saved floats | 41 * |-------------------------------| 42 * | outgoing parameters past 6 | 43 * |-------------------------------|-\ 44 * | 6 words for callee to dump | | 45 * | register arguments | | 46 * |-------------------------------| > minimum stack frame 47 * | One word struct-ret address | | 48 * |-------------------------------| | 49 * | 16 words to save IN and | | 50 * %sp->| LOCAL register on overflow | | 51 * |-------------------------------|-/ 52 */ 53 54 /* 55 * Constants defining a stack frame. 56 */ 57 #define WINDOWSIZE (16*4) /* size of window save area */ 58 #define ARGPUSHSIZE (6*4) /* size of arg dump area */ 59 #define ARGPUSH (WINDOWSIZE+4) /* arg dump area offset */ 60 #define MINFRAME (WINDOWSIZE+ARGPUSHSIZE+4) /* min frame */ 61 62 /* 63 * Stack alignment macros. 64 */ 65 #define STACK_ALIGN 8 66 #define SA(X) (((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1)) 67 68 #ifdef _ASM /* The remainder of this file is only for assembly files */ 69 70 /* 71 * Symbolic section definitions. 72 */ 73 #define RODATA ".rodata" 74 75 /* 76 * profiling causes defintions of the MCOUNT and RTMCOUNT 77 * particular to the type 78 */ 79 #ifdef GPROF 80 81 #define MCOUNT(x) \ 82 save %sp, -SA(MINFRAME), %sp; \ 83 call mcount; \ 84 nop ; \ 85 restore ; 86 87 #endif /* GPROF */ 88 89 #ifdef PROF 90 91 #define MCOUNT(x) \ 92 save %sp, -SA(MINFRAME), %sp; \ 93 sethi %hi(.L_/**/x/**/1), %o0; \ 94 call mcount; \ 95 or %o0, %lo(.L_/**/x/**/1), %o0; \ 96 restore; \ 97 .common .L_/**/x/**/1, 4, ".bss"; 98 99 #endif /* PROF */ 100 101 /* 102 * if we are not profiling, MCOUNT should be defined to nothing 103 */ 104 #if !defined(PROF) && !defined(GPROF) 105 #define MCOUNT(x) 106 #endif /* !defined(PROF) && !defined(GPROF) */ 107 108 #define RTMCOUNT(x) MCOUNT(x) 109 110 /* 111 * Pre-ansi compiler versions prepended an underscore to function names. 112 * This macro provides this function. 113 */ 114 #ifndef __STDC__ 115 #define NAME(x) _/**/x 116 #endif /* __STDC__ */ 117 118 /* 119 * Macro to define weak symbol aliases. These are similar to the ANSI-C 120 * #pragma weak name = _name 121 * except a compiler can determine type. The assembler must be told. Hence, 122 * the second parameter must be the type of the symbol (i.e.: function,...) 123 */ 124 #ifdef __STDC__ 125 #define ANSI_PRAGMA_WEAK(sym,stype) \ 126 .weak sym; \ 127 .type sym,#stype; \ 128 sym = _/**/sym 129 #endif /* __STDC__ */ 130 131 /* 132 * ENTRY provides a way to insert the calls to mcount for profiling. 133 */ 134 #ifdef __STDC__ 135 136 #define ENTRY(x) \ 137 .section ".text"; \ 138 .align 4; \ 139 .global x; \ 140 .type x,#function; \ 141 x: MCOUNT(x) 142 143 #define RTENTRY(x) \ 144 .global x; x: RTMCOUNT(x) 145 146 #else /* __STDC__ */ 147 148 #define ENTRY(x) \ 149 .global NAME(x); \ 150 NAME(x): MCOUNT(x) 151 152 #define RTENTRY(x) \ 153 .global x; x: RTMCOUNT(x) 154 155 #endif /* __STDC__ */ 156 157 /* 158 * ENTRY2 is identical to ENTRY but provides two labels for the entry point. 159 */ 160 #ifdef __STDC__ 161 162 #define ENTRY2(x,y) \ 163 .section ".text"; \ 164 .align 4; \ 165 .global x, y; \ 166 .type x,#function; \ 167 .type y,#function; \ 168 x: ; \ 169 y: MCOUNT(x) 170 171 #else /* __STDC__ */ 172 173 #define ENTRY2(x,y) \ 174 .global NAME(x), NAME(y); \ 175 NAME(x): ; \ 176 NAME(y): MCOUNT(x) 177 178 #endif /* __STDC__ */ 179 180 /* 181 * ALTENTRY provides for additional entry points. 182 */ 183 #ifdef __STDC__ 184 185 #define ALTENTRY(x) \ 186 .global x; \ 187 .type x,#function; \ 188 x: 189 190 #else /* __STDC__ */ 191 192 #define ALTENTRY(x) \ 193 .global NAME(x); \ 194 NAME(x): 195 196 #endif /* __STDC__ */ 197 198 /* 199 * DGDEF and DGDEF2 provide global data declarations. 200 */ 201 #ifdef __STDC__ 202 203 #define DGDEF2(name,sz) \ 204 .section ".data"; \ 205 .global name; \ 206 .type name,#object; \ 207 .size name,sz; \ 208 name: 209 210 #else /* __STDC__ */ 211 212 #define DGDEF2(name,sz) \ 213 .section ".data"; \ 214 .global name; \ 215 name: 216 217 #endif /* __STDC__ */ 218 219 #define DGDEF(name) DGDEF2(name,4) 220 221 /* 222 * SET_SIZE trails a function and set the size for the ELF symbol table. 223 */ 224 #ifdef __STDC__ 225 226 #define SET_SIZE(x) \ 227 .size x,(.-x) 228 229 #else /* __STDC__ */ 230 231 #define SET_SIZE(x) 232 233 #endif /* __STDC__ */ 234 235 #ifdef _KERNEL 236 /* 237 * Macros for saving/restoring registers. 238 */ 239 240 #define SAVE_GLOBALS(RP) \ 241 st %g1, [RP + G1*4]; \ 242 std %g2, [RP + G2*4]; \ 243 std %g4, [RP + G4*4]; \ 244 std %g6, [RP + G6*4]; \ 245 mov %y, %g1; \ 246 st %g1, [RP + Y*4] 247 248 #define RESTORE_GLOBALS(RP) \ 249 ld [RP + Y*4], %g1; \ 250 mov %g1, %y; \ 251 ld [RP + G1*4], %g1; \ 252 ldd [RP + G2*4], %g2; \ 253 ldd [RP + G4*4], %g4; \ 254 ldd [RP + G6*4], %g6; 255 256 #define SAVE_OUTS(RP) \ 257 std %i0, [RP + O0*4]; \ 258 std %i2, [RP + O2*4]; \ 259 std %i4, [RP + O4*4]; \ 260 std %i6, [RP + O6*4]; 261 262 #define RESTORE_OUTS(RP) \ 263 ldd [RP + O0*4], %i0; \ 264 ldd [RP + O2*4], %i2; \ 265 ldd [RP + O4*4], %i4; \ 266 ldd [RP + O6*4], %i6; 267 268 #define SAVE_WINDOW(SBP) \ 269 std %l0, [SBP + (0*4)]; \ 270 std %l2, [SBP + (2*4)]; \ 271 std %l4, [SBP + (4*4)]; \ 272 std %l6, [SBP + (6*4)]; \ 273 std %i0, [SBP + (8*4)]; \ 274 std %i2, [SBP + (10*4)]; \ 275 std %i4, [SBP + (12*4)]; \ 276 std %i6, [SBP + (14*4)]; 277 278 #define RESTORE_WINDOW(SBP) \ 279 ldd [SBP + (0*4)], %l0; \ 280 ldd [SBP + (2*4)], %l2; \ 281 ldd [SBP + (4*4)], %l4; \ 282 ldd [SBP + (6*4)], %l6; \ 283 ldd [SBP + (8*4)], %i0; \ 284 ldd [SBP + (10*4)], %i2; \ 285 ldd [SBP + (12*4)], %i4; \ 286 ldd [SBP + (14*4)], %i6; 287 288 #ifdef PARTIAL_ALIGN 289 290 #define SAVE_WINDOW_S(SBP) \ 291 st %l0, [SBP + (0*4)]; \ 292 st %l1, [SBP + (1*4)]; \ 293 st %l2, [SBP + (2*4)]; \ 294 st %l3, [SBP + (3*4)]; \ 295 st %l4, [SBP + (4*4)]; \ 296 st %l5, [SBP + (5*4)]; \ 297 st %l6, [SBP + (6*4)]; \ 298 st %l7, [SBP + (7*4)]; \ 299 st %i0, [SBP + (8*4)]; \ 300 st %i1, [SBP + (9*4)]; \ 301 st %i2, [SBP + (10*4)]; \ 302 st %i3, [SBP + (11*4)]; \ 303 st %i4, [SBP + (12*4)]; \ 304 st %i5, [SBP + (13*4)]; \ 305 st %i6, [SBP + (14*4)]; \ 306 st %i7, [SBP + (15*4)] 307 308 #define RESTORE_WINDOW_S(SBP) \ 309 ld [SBP + (0*4)], %l0; \ 310 ld [SBP + (1*4)], %l1; \ 311 ld [SBP + (2*4)], %l2; \ 312 ld [SBP + (3*4)], %l3; \ 313 ld [SBP + (4*4)], %l4; \ 314 ld [SBP + (5*4)], %l5; \ 315 ld [SBP + (6*4)], %l6; \ 316 ld [SBP + (7*4)], %l7; \ 317 ld [SBP + (8*4)], %i0; \ 318 ld [SBP + (9*4)], %i1; \ 319 ld [SBP + (10*4)], %i2; \ 320 ld [SBP + (11*4)], %i3; \ 321 ld [SBP + (12*4)], %i4; \ 322 ld [SBP + (13*4)], %i5; \ 323 ld [SBP + (14*4)], %i6; \ 324 ld [SBP + (15*4)], %i7 325 326 #endif /* PARTIAL_ALIGN */ 327 328 #endif /* _KERNEL */ 329 330 #endif /* _ASM */ 331 332 #endif /* _SYS_ASM_LINKAGE_H */ 333