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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _IA32_SYS_ASM_LINKAGE_H 28 #define _IA32_SYS_ASM_LINKAGE_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #include <sys/stack.h> 33 #include <sys/trap.h> 34 35 #ifdef __cplusplus 36 extern "C" { 37 #endif 38 39 #ifdef _ASM /* The remainder of this file is only for assembly files */ 40 41 /* 42 * make annoying differences in assembler syntax go away 43 */ 44 45 /* 46 * D16 and A16 are used to insert instructions prefixes; the 47 * macros help the assembler code be slightly more portable. 48 */ 49 #if !defined(__GNUC_AS__) 50 /* 51 * /usr/ccs/bin/as prefixes are parsed as separate instructions 52 */ 53 #define D16 data16; 54 #define A16 addr16; 55 56 /* 57 * (There are some weird constructs in constant expressions) 58 */ 59 #define _CONST(const) [const] 60 #define _BITNOT(const) -1!_CONST(const) 61 #define _MUL(a, b) _CONST(a \* b) 62 63 #else 64 /* 65 * Why not use the 'data16' and 'addr16' prefixes .. well, the 66 * assembler doesn't quite believe in real mode, and thus argues with 67 * us about what we're trying to do. 68 */ 69 #define D16 .byte 0x66; 70 #define A16 .byte 0x67; 71 72 #define _CONST(const) (const) 73 #define _BITNOT(const) ~_CONST(const) 74 #define _MUL(a, b) _CONST(a * b) 75 76 #endif 77 78 /* 79 * C pointers are different sizes between i386 and amd64. 80 * These constants can be used to compute offsets into pointer arrays. 81 */ 82 #if defined(__amd64) 83 #define CLONGSHIFT 3 84 #define CLONGSIZE 8 85 #define CLONGMASK 7 86 #elif defined(__i386) 87 #define CLONGSHIFT 2 88 #define CLONGSIZE 4 89 #define CLONGMASK 3 90 #endif 91 92 /* 93 * Since we know we're either ILP32 or LP64 .. 94 */ 95 #define CPTRSHIFT CLONGSHIFT 96 #define CPTRSIZE CLONGSIZE 97 #define CPTRMASK CLONGMASK 98 99 #if CPTRSIZE != (1 << CPTRSHIFT) || CLONGSIZE != (1 << CLONGSHIFT) 100 #error "inconsistent shift constants" 101 #endif 102 103 #if CPTRMASK != (CPTRSIZE - 1) || CLONGMASK != (CLONGSIZE - 1) 104 #error "inconsistent mask constants" 105 #endif 106 107 #define ASM_ENTRY_ALIGN 16 108 109 /* 110 * SSE register alignment and save areas 111 */ 112 113 #define XMM_SIZE 16 114 #define XMM_ALIGN 16 115 116 #if defined(__amd64) 117 118 #define SAVE_XMM_PROLOG(sreg, nreg) \ 119 subq $_CONST(_MUL(XMM_SIZE, nreg)), %rsp; \ 120 movq %rsp, sreg 121 122 #define RSTOR_XMM_EPILOG(sreg, nreg) \ 123 addq $_CONST(_MUL(XMM_SIZE, nreg)), %rsp 124 125 #elif defined(__i386) 126 127 #define SAVE_XMM_PROLOG(sreg, nreg) \ 128 subl $_CONST(_MUL(XMM_SIZE, nreg) + XMM_ALIGN), %esp; \ 129 movl %esp, sreg; \ 130 addl $XMM_ALIGN, sreg; \ 131 andl $_BITNOT(XMM_ALIGN-1), sreg 132 133 #define RSTOR_XMM_EPILOG(sreg, nreg) \ 134 addl $_CONST(_MUL(XMM_SIZE, nreg) + XMM_ALIGN), %esp; 135 136 #endif /* __i386 */ 137 138 /* 139 * profiling causes definitions of the MCOUNT and RTMCOUNT 140 * particular to the type 141 */ 142 #ifdef GPROF 143 144 #define MCOUNT(x) \ 145 pushl %ebp; \ 146 movl %esp, %ebp; \ 147 call _mcount; \ 148 popl %ebp 149 150 #endif /* GPROF */ 151 152 #ifdef PROF 153 154 #define MCOUNT(x) \ 155 /* CSTYLED */ \ 156 .lcomm .L_/**/x/**/1, 4, 4; \ 157 pushl %ebp; \ 158 movl %esp, %ebp; \ 159 /* CSTYLED */ \ 160 movl $.L_/**/x/**/1, %edx; \ 161 call _mcount; \ 162 popl %ebp 163 164 #endif /* PROF */ 165 166 /* 167 * if we are not profiling, MCOUNT should be defined to nothing 168 */ 169 #if !defined(PROF) && !defined(GPROF) 170 #define MCOUNT(x) 171 #endif /* !defined(PROF) && !defined(GPROF) */ 172 173 #define RTMCOUNT(x) MCOUNT(x) 174 175 /* 176 * Macro to define weak symbol aliases. These are similar to the ANSI-C 177 * #pragma weak _name = name 178 * except a compiler can determine type. The assembler must be told. Hence, 179 * the second parameter must be the type of the symbol (i.e.: function,...) 180 */ 181 #define ANSI_PRAGMA_WEAK(sym, stype) \ 182 /* CSTYLED */ \ 183 .weak _/**/sym; \ 184 /* CSTYLED */ \ 185 .type _/**/sym, @stype; \ 186 /* CSTYLED */ \ 187 _/**/sym = sym 188 189 /* 190 * Like ANSI_PRAGMA_WEAK(), but for unrelated names, as in: 191 * #pragma weak sym1 = sym2 192 */ 193 #define ANSI_PRAGMA_WEAK2(sym1, sym2, stype) \ 194 .weak sym1; \ 195 .type sym1, @stype; \ 196 sym1 = sym2 197 198 /* 199 * ENTRY provides the standard procedure entry code and an easy way to 200 * insert the calls to mcount for profiling. ENTRY_NP is identical, but 201 * never calls mcount. 202 */ 203 #define ENTRY(x) \ 204 .text; \ 205 .align ASM_ENTRY_ALIGN; \ 206 .globl x; \ 207 .type x, @function; \ 208 x: MCOUNT(x) 209 210 #define ENTRY_NP(x) \ 211 .text; \ 212 .align ASM_ENTRY_ALIGN; \ 213 .globl x; \ 214 .type x, @function; \ 215 x: 216 217 #define RTENTRY(x) \ 218 .text; \ 219 .align ASM_ENTRY_ALIGN; \ 220 .globl x; \ 221 .type x, @function; \ 222 x: RTMCOUNT(x) 223 224 /* 225 * ENTRY2 is identical to ENTRY but provides two labels for the entry point. 226 */ 227 #define ENTRY2(x, y) \ 228 .text; \ 229 .align ASM_ENTRY_ALIGN; \ 230 .globl x, y; \ 231 .type x, @function; \ 232 .type y, @function; \ 233 /* CSTYLED */ \ 234 x: ; \ 235 y: MCOUNT(x) 236 237 #define ENTRY_NP2(x, y) \ 238 .text; \ 239 .align ASM_ENTRY_ALIGN; \ 240 .globl x, y; \ 241 .type x, @function; \ 242 .type y, @function; \ 243 /* CSTYLED */ \ 244 x: ; \ 245 y: 246 247 248 /* 249 * ALTENTRY provides for additional entry points. 250 */ 251 #define ALTENTRY(x) \ 252 .globl x; \ 253 .type x, @function; \ 254 x: 255 256 /* 257 * DGDEF and DGDEF2 provide global data declarations. 258 * 259 * DGDEF provides a word aligned word of storage. 260 * 261 * DGDEF2 allocates "sz" bytes of storage with **NO** alignment. This 262 * implies this macro is best used for byte arrays. 263 * 264 * DGDEF3 allocates "sz" bytes of storage with "algn" alignment. 265 */ 266 #define DGDEF2(name, sz) \ 267 .data; \ 268 .globl name; \ 269 .type name, @object; \ 270 .size name, sz; \ 271 name: 272 273 #define DGDEF3(name, sz, algn) \ 274 .data; \ 275 .align algn; \ 276 .globl name; \ 277 .type name, @object; \ 278 .size name, sz; \ 279 name: 280 281 #define DGDEF(name) DGDEF3(name, 4, 4) 282 283 /* 284 * SET_SIZE trails a function and set the size for the ELF symbol table. 285 */ 286 #define SET_SIZE(x) \ 287 .size x, [.-x] 288 289 /* 290 * NWORD provides native word value. 291 */ 292 #if defined(__amd64) 293 294 /*CSTYLED*/ 295 #define NWORD quad 296 297 #elif defined(__i386) 298 299 #define NWORD long 300 301 #endif /* __i386 */ 302 303 #endif /* _ASM */ 304 305 #ifdef __cplusplus 306 } 307 #endif 308 309 #endif /* _IA32_SYS_ASM_LINKAGE_H */ 310