10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*6812Sraf * Common Development and Distribution License (the "License"). 6*6812Sraf * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 21*6812Sraf 220Sstevel@tonic-gate /* 23*6812Sraf * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate #ifndef _IA32_SYS_ASM_LINKAGE_H 280Sstevel@tonic-gate #define _IA32_SYS_ASM_LINKAGE_H 290Sstevel@tonic-gate 300Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 310Sstevel@tonic-gate 320Sstevel@tonic-gate #include <sys/stack.h> 330Sstevel@tonic-gate #include <sys/trap.h> 340Sstevel@tonic-gate 350Sstevel@tonic-gate #ifdef __cplusplus 360Sstevel@tonic-gate extern "C" { 370Sstevel@tonic-gate #endif 380Sstevel@tonic-gate 390Sstevel@tonic-gate #ifdef _ASM /* The remainder of this file is only for assembly files */ 400Sstevel@tonic-gate 410Sstevel@tonic-gate /* 420Sstevel@tonic-gate * make annoying differences in assembler syntax go away 430Sstevel@tonic-gate */ 440Sstevel@tonic-gate 450Sstevel@tonic-gate /* 460Sstevel@tonic-gate * D16 and A16 are used to insert instructions prefixes; the 470Sstevel@tonic-gate * macros help the assembler code be slightly more portable. 480Sstevel@tonic-gate */ 490Sstevel@tonic-gate #if !defined(__GNUC_AS__) 500Sstevel@tonic-gate /* 510Sstevel@tonic-gate * /usr/ccs/bin/as prefixes are parsed as separate instructions 520Sstevel@tonic-gate */ 530Sstevel@tonic-gate #define D16 data16; 540Sstevel@tonic-gate #define A16 addr16; 550Sstevel@tonic-gate 560Sstevel@tonic-gate /* 570Sstevel@tonic-gate * (There are some weird constructs in constant expressions) 580Sstevel@tonic-gate */ 590Sstevel@tonic-gate #define _CONST(const) [const] 600Sstevel@tonic-gate #define _BITNOT(const) -1!_CONST(const) 610Sstevel@tonic-gate #define _MUL(a, b) _CONST(a \* b) 620Sstevel@tonic-gate 630Sstevel@tonic-gate #else 640Sstevel@tonic-gate /* 650Sstevel@tonic-gate * Why not use the 'data16' and 'addr16' prefixes .. well, the 660Sstevel@tonic-gate * assembler doesn't quite believe in real mode, and thus argues with 670Sstevel@tonic-gate * us about what we're trying to do. 680Sstevel@tonic-gate */ 690Sstevel@tonic-gate #define D16 .byte 0x66; 700Sstevel@tonic-gate #define A16 .byte 0x67; 710Sstevel@tonic-gate 720Sstevel@tonic-gate #define _CONST(const) (const) 730Sstevel@tonic-gate #define _BITNOT(const) ~_CONST(const) 740Sstevel@tonic-gate #define _MUL(a, b) _CONST(a * b) 750Sstevel@tonic-gate 760Sstevel@tonic-gate #endif 770Sstevel@tonic-gate 780Sstevel@tonic-gate /* 790Sstevel@tonic-gate * C pointers are different sizes between i386 and amd64. 800Sstevel@tonic-gate * These constants can be used to compute offsets into pointer arrays. 810Sstevel@tonic-gate */ 820Sstevel@tonic-gate #if defined(__amd64) 830Sstevel@tonic-gate #define CLONGSHIFT 3 840Sstevel@tonic-gate #define CLONGSIZE 8 850Sstevel@tonic-gate #define CLONGMASK 7 860Sstevel@tonic-gate #elif defined(__i386) 870Sstevel@tonic-gate #define CLONGSHIFT 2 880Sstevel@tonic-gate #define CLONGSIZE 4 890Sstevel@tonic-gate #define CLONGMASK 3 900Sstevel@tonic-gate #endif 910Sstevel@tonic-gate 920Sstevel@tonic-gate /* 930Sstevel@tonic-gate * Since we know we're either ILP32 or LP64 .. 940Sstevel@tonic-gate */ 950Sstevel@tonic-gate #define CPTRSHIFT CLONGSHIFT 960Sstevel@tonic-gate #define CPTRSIZE CLONGSIZE 970Sstevel@tonic-gate #define CPTRMASK CLONGMASK 980Sstevel@tonic-gate 990Sstevel@tonic-gate #if CPTRSIZE != (1 << CPTRSHIFT) || CLONGSIZE != (1 << CLONGSHIFT) 1000Sstevel@tonic-gate #error "inconsistent shift constants" 1010Sstevel@tonic-gate #endif 1020Sstevel@tonic-gate 1030Sstevel@tonic-gate #if CPTRMASK != (CPTRSIZE - 1) || CLONGMASK != (CLONGSIZE - 1) 1040Sstevel@tonic-gate #error "inconsistent mask constants" 1050Sstevel@tonic-gate #endif 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate #define ASM_ENTRY_ALIGN 16 1080Sstevel@tonic-gate 1090Sstevel@tonic-gate /* 1100Sstevel@tonic-gate * SSE register alignment and save areas 1110Sstevel@tonic-gate */ 1120Sstevel@tonic-gate 1130Sstevel@tonic-gate #define XMM_SIZE 16 1140Sstevel@tonic-gate #define XMM_ALIGN 16 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate #if defined(__amd64) 1170Sstevel@tonic-gate 1180Sstevel@tonic-gate #define SAVE_XMM_PROLOG(sreg, nreg) \ 1190Sstevel@tonic-gate subq $_CONST(_MUL(XMM_SIZE, nreg)), %rsp; \ 1200Sstevel@tonic-gate movq %rsp, sreg 1210Sstevel@tonic-gate 1220Sstevel@tonic-gate #define RSTOR_XMM_EPILOG(sreg, nreg) \ 1230Sstevel@tonic-gate addq $_CONST(_MUL(XMM_SIZE, nreg)), %rsp 1240Sstevel@tonic-gate 1250Sstevel@tonic-gate #elif defined(__i386) 1260Sstevel@tonic-gate 1270Sstevel@tonic-gate #define SAVE_XMM_PROLOG(sreg, nreg) \ 1280Sstevel@tonic-gate subl $_CONST(_MUL(XMM_SIZE, nreg) + XMM_ALIGN), %esp; \ 1290Sstevel@tonic-gate movl %esp, sreg; \ 1300Sstevel@tonic-gate addl $XMM_ALIGN, sreg; \ 1310Sstevel@tonic-gate andl $_BITNOT(XMM_ALIGN-1), sreg 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate #define RSTOR_XMM_EPILOG(sreg, nreg) \ 1340Sstevel@tonic-gate addl $_CONST(_MUL(XMM_SIZE, nreg) + XMM_ALIGN), %esp; 1350Sstevel@tonic-gate 1360Sstevel@tonic-gate #endif /* __i386 */ 1370Sstevel@tonic-gate 1380Sstevel@tonic-gate /* 1390Sstevel@tonic-gate * profiling causes definitions of the MCOUNT and RTMCOUNT 1400Sstevel@tonic-gate * particular to the type 1410Sstevel@tonic-gate */ 1420Sstevel@tonic-gate #ifdef GPROF 1430Sstevel@tonic-gate 1440Sstevel@tonic-gate #define MCOUNT(x) \ 1450Sstevel@tonic-gate pushl %ebp; \ 1460Sstevel@tonic-gate movl %esp, %ebp; \ 1470Sstevel@tonic-gate call _mcount; \ 1480Sstevel@tonic-gate popl %ebp 1490Sstevel@tonic-gate 1500Sstevel@tonic-gate #endif /* GPROF */ 1510Sstevel@tonic-gate 1520Sstevel@tonic-gate #ifdef PROF 1530Sstevel@tonic-gate 1540Sstevel@tonic-gate #define MCOUNT(x) \ 1550Sstevel@tonic-gate /* CSTYLED */ \ 1560Sstevel@tonic-gate .lcomm .L_/**/x/**/1, 4, 4; \ 1570Sstevel@tonic-gate pushl %ebp; \ 1580Sstevel@tonic-gate movl %esp, %ebp; \ 1590Sstevel@tonic-gate /* CSTYLED */ \ 1600Sstevel@tonic-gate movl $.L_/**/x/**/1, %edx; \ 1610Sstevel@tonic-gate call _mcount; \ 1620Sstevel@tonic-gate popl %ebp 1630Sstevel@tonic-gate 1640Sstevel@tonic-gate #endif /* PROF */ 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate /* 1670Sstevel@tonic-gate * if we are not profiling, MCOUNT should be defined to nothing 1680Sstevel@tonic-gate */ 1690Sstevel@tonic-gate #if !defined(PROF) && !defined(GPROF) 1700Sstevel@tonic-gate #define MCOUNT(x) 1710Sstevel@tonic-gate #endif /* !defined(PROF) && !defined(GPROF) */ 1720Sstevel@tonic-gate 1730Sstevel@tonic-gate #define RTMCOUNT(x) MCOUNT(x) 1740Sstevel@tonic-gate 1750Sstevel@tonic-gate /* 1760Sstevel@tonic-gate * Macro to define weak symbol aliases. These are similar to the ANSI-C 177*6812Sraf * #pragma weak _name = name 1780Sstevel@tonic-gate * except a compiler can determine type. The assembler must be told. Hence, 1790Sstevel@tonic-gate * the second parameter must be the type of the symbol (i.e.: function,...) 1800Sstevel@tonic-gate */ 1810Sstevel@tonic-gate #define ANSI_PRAGMA_WEAK(sym, stype) \ 182*6812Sraf /* CSTYLED */ \ 183*6812Sraf .weak _/**/sym; \ 1840Sstevel@tonic-gate /* CSTYLED */ \ 185*6812Sraf .type _/**/sym, @stype; \ 186*6812Sraf /* CSTYLED */ \ 187*6812Sraf _/**/sym = sym 1880Sstevel@tonic-gate 1890Sstevel@tonic-gate /* 1900Sstevel@tonic-gate * Like ANSI_PRAGMA_WEAK(), but for unrelated names, as in: 1910Sstevel@tonic-gate * #pragma weak sym1 = sym2 1920Sstevel@tonic-gate */ 1930Sstevel@tonic-gate #define ANSI_PRAGMA_WEAK2(sym1, sym2, stype) \ 1940Sstevel@tonic-gate .weak sym1; \ 1950Sstevel@tonic-gate .type sym1, @stype; \ 1960Sstevel@tonic-gate sym1 = sym2 1970Sstevel@tonic-gate 1980Sstevel@tonic-gate /* 1990Sstevel@tonic-gate * ENTRY provides the standard procedure entry code and an easy way to 2000Sstevel@tonic-gate * insert the calls to mcount for profiling. ENTRY_NP is identical, but 2010Sstevel@tonic-gate * never calls mcount. 2020Sstevel@tonic-gate */ 2030Sstevel@tonic-gate #define ENTRY(x) \ 2040Sstevel@tonic-gate .text; \ 2050Sstevel@tonic-gate .align ASM_ENTRY_ALIGN; \ 2060Sstevel@tonic-gate .globl x; \ 2070Sstevel@tonic-gate .type x, @function; \ 2080Sstevel@tonic-gate x: MCOUNT(x) 2090Sstevel@tonic-gate 2100Sstevel@tonic-gate #define ENTRY_NP(x) \ 2110Sstevel@tonic-gate .text; \ 2120Sstevel@tonic-gate .align ASM_ENTRY_ALIGN; \ 2130Sstevel@tonic-gate .globl x; \ 2140Sstevel@tonic-gate .type x, @function; \ 2150Sstevel@tonic-gate x: 2160Sstevel@tonic-gate 2170Sstevel@tonic-gate #define RTENTRY(x) \ 2180Sstevel@tonic-gate .text; \ 2190Sstevel@tonic-gate .align ASM_ENTRY_ALIGN; \ 2200Sstevel@tonic-gate .globl x; \ 2210Sstevel@tonic-gate .type x, @function; \ 2220Sstevel@tonic-gate x: RTMCOUNT(x) 2230Sstevel@tonic-gate 2240Sstevel@tonic-gate /* 2250Sstevel@tonic-gate * ENTRY2 is identical to ENTRY but provides two labels for the entry point. 2260Sstevel@tonic-gate */ 2270Sstevel@tonic-gate #define ENTRY2(x, y) \ 2280Sstevel@tonic-gate .text; \ 2290Sstevel@tonic-gate .align ASM_ENTRY_ALIGN; \ 2300Sstevel@tonic-gate .globl x, y; \ 2310Sstevel@tonic-gate .type x, @function; \ 2320Sstevel@tonic-gate .type y, @function; \ 2330Sstevel@tonic-gate /* CSTYLED */ \ 2340Sstevel@tonic-gate x: ; \ 2350Sstevel@tonic-gate y: MCOUNT(x) 2360Sstevel@tonic-gate 2370Sstevel@tonic-gate #define ENTRY_NP2(x, y) \ 2380Sstevel@tonic-gate .text; \ 2390Sstevel@tonic-gate .align ASM_ENTRY_ALIGN; \ 2400Sstevel@tonic-gate .globl x, y; \ 2410Sstevel@tonic-gate .type x, @function; \ 2420Sstevel@tonic-gate .type y, @function; \ 2430Sstevel@tonic-gate /* CSTYLED */ \ 2440Sstevel@tonic-gate x: ; \ 2450Sstevel@tonic-gate y: 2460Sstevel@tonic-gate 2470Sstevel@tonic-gate 2480Sstevel@tonic-gate /* 2490Sstevel@tonic-gate * ALTENTRY provides for additional entry points. 2500Sstevel@tonic-gate */ 2510Sstevel@tonic-gate #define ALTENTRY(x) \ 2520Sstevel@tonic-gate .globl x; \ 2530Sstevel@tonic-gate .type x, @function; \ 2540Sstevel@tonic-gate x: 2550Sstevel@tonic-gate 2560Sstevel@tonic-gate /* 2570Sstevel@tonic-gate * DGDEF and DGDEF2 provide global data declarations. 2580Sstevel@tonic-gate * 2590Sstevel@tonic-gate * DGDEF provides a word aligned word of storage. 2600Sstevel@tonic-gate * 2610Sstevel@tonic-gate * DGDEF2 allocates "sz" bytes of storage with **NO** alignment. This 2620Sstevel@tonic-gate * implies this macro is best used for byte arrays. 2630Sstevel@tonic-gate * 2640Sstevel@tonic-gate * DGDEF3 allocates "sz" bytes of storage with "algn" alignment. 2650Sstevel@tonic-gate */ 2660Sstevel@tonic-gate #define DGDEF2(name, sz) \ 2670Sstevel@tonic-gate .data; \ 2680Sstevel@tonic-gate .globl name; \ 2690Sstevel@tonic-gate .type name, @object; \ 2700Sstevel@tonic-gate .size name, sz; \ 2710Sstevel@tonic-gate name: 2720Sstevel@tonic-gate 2730Sstevel@tonic-gate #define DGDEF3(name, sz, algn) \ 2740Sstevel@tonic-gate .data; \ 2750Sstevel@tonic-gate .align algn; \ 2760Sstevel@tonic-gate .globl name; \ 2770Sstevel@tonic-gate .type name, @object; \ 2780Sstevel@tonic-gate .size name, sz; \ 2790Sstevel@tonic-gate name: 2800Sstevel@tonic-gate 2810Sstevel@tonic-gate #define DGDEF(name) DGDEF3(name, 4, 4) 2820Sstevel@tonic-gate 2830Sstevel@tonic-gate /* 2840Sstevel@tonic-gate * SET_SIZE trails a function and set the size for the ELF symbol table. 2850Sstevel@tonic-gate */ 2860Sstevel@tonic-gate #define SET_SIZE(x) \ 2870Sstevel@tonic-gate .size x, [.-x] 2880Sstevel@tonic-gate 2890Sstevel@tonic-gate /* 2900Sstevel@tonic-gate * NWORD provides native word value. 2910Sstevel@tonic-gate */ 2920Sstevel@tonic-gate #if defined(__amd64) 2930Sstevel@tonic-gate 2940Sstevel@tonic-gate /*CSTYLED*/ 2950Sstevel@tonic-gate #define NWORD quad 2960Sstevel@tonic-gate 2970Sstevel@tonic-gate #elif defined(__i386) 2980Sstevel@tonic-gate 2990Sstevel@tonic-gate #define NWORD long 3000Sstevel@tonic-gate 3010Sstevel@tonic-gate #endif /* __i386 */ 3020Sstevel@tonic-gate 3030Sstevel@tonic-gate #endif /* _ASM */ 3040Sstevel@tonic-gate 3050Sstevel@tonic-gate #ifdef __cplusplus 3060Sstevel@tonic-gate } 3070Sstevel@tonic-gate #endif 3080Sstevel@tonic-gate 3090Sstevel@tonic-gate #endif /* _IA32_SYS_ASM_LINKAGE_H */ 310