5291 x86 {high,low}bit rely on undefined behavior
[illumos-gate.git] / usr / src / uts / intel / ia32 / ml / ia32.il
blob8ced7d69a66c2c0a118adf71d5e83c996e8a30d9
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  */
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
28 / Inline functions for i386 kernels.
29 /       Shared between all x86 platform variants.
33 / return current thread pointer
35 / NOTE: the "0x10" should be replaced by the computed value of the
36 /       offset of "cpu_thread" from the beginning of the struct cpu.
37 /       Including "assym.h" does not work, however, since that stuff
38 /       is PSM-specific and is only visible to the 'unix' build anyway.
39 /       Same with current cpu pointer, where "0xc" should be replaced
40 /       by the computed value of the offset of "cpu_self".
41 /       Ugh -- what a disaster.
43         .inline threadp,0
44         movl    %gs:0x10, %eax
45         .end
48 / return current cpu pointer
50         .inline curcpup,0
51         movl    %gs:0xc, %eax
52         .end
55 / return caller
57         .inline caller,0
58         movl    4(%ebp), %eax
59         .end
62 / convert ipl to spl.  This is the identity function for i86
64         .inline ipltospl,0
65         movl    (%esp), %eax
66         .end
69 / Networking byte order functions (too bad, Intel has the wrong byte order)
71         .inline htonll,4
72         movl    (%esp), %edx
73         movl    4(%esp), %eax
74         bswap   %edx
75         bswap   %eax
76         .end
78         .inline ntohll,4
79         movl    (%esp), %edx
80         movl    4(%esp), %eax
81         bswap   %edx
82         bswap   %eax
83         .end
85         .inline htonl,4
86         movl    (%esp), %eax
87         bswap   %eax
88         .end
90         .inline ntohl,4
91         movl    (%esp), %eax
92         bswap   %eax
93         .end
95         .inline htons,4
96         movl    (%esp), %eax
97         bswap   %eax
98         shrl    $16, %eax
99         .end
101         .inline ntohs,4
102         movl    (%esp), %eax
103         bswap   %eax
104         shrl    $16, %eax
105         .end
108  * multiply two long numbers and yield a u_longlong_t result
109  * Provided to manipulate hrtime_t values.
110  */
111         .inline mul32, 8
112         movl    4(%esp), %eax
113         movl    (%esp), %ecx
114         mull    %ecx
115         .end
118  * Unlock hres_lock and increment the count value. (See clock.h)
119  */
120         .inline unlock_hres_lock, 0
121         lock
122         incl    hres_lock
123         .end
125         .inline atomic_orb,8
126         movl    (%esp), %eax
127         movl    4(%esp), %edx
128         lock
129         orb     %dl,(%eax)
130         .end
132         .inline atomic_andb,8
133         movl    (%esp), %eax
134         movl    4(%esp), %edx
135         lock
136         andb    %dl,(%eax)
137         .end
140  * atomic inc/dec operations.
141  *      void atomic_inc16(uint16_t *addr) { ++*addr; }
142  *      void atomic_dec16(uint16_t *addr) { --*addr; }
143  */
144         .inline atomic_inc16,4
145         movl    (%esp), %eax
146         lock
147         incw    (%eax)
148         .end
150         .inline atomic_dec16,4
151         movl    (%esp), %eax
152         lock
153         decw    (%eax)
154         .end
157  * Call the pause instruction.  To the Pentium 4 Xeon processor, it acts as
158  * a hint that the code sequence is a busy spin-wait loop.  Without a pause
159  * instruction in these loops, the P4 Xeon processor may suffer a severe
160  * penalty when exiting the loop because the processor detects a possible
161  * memory violation.  Inserting the pause instruction significantly reduces
162  * the likelihood of a memory order violation, improving performance.
163  * The pause instruction is a NOP on all other IA-32 processors.
164  */
165         .inline ht_pause, 0
166         rep                     / our compiler doesn't support "pause" yet,
167         nop                     / so we're using "F3 90" opcode directly
168         .end
171  * prefetch 64 bytes
173  * prefetch is an SSE extension which is not supported on older 32-bit processors
174  * so define this as a no-op for now
175  */
177         .inline prefetch_read_many,4
178 /       movl            (%esp), %eax
179 /       prefetcht0      (%eax)
180 /       prefetcht0      32(%eax)
181         .end
183         .inline prefetch_read_once,4
184 /       movl            (%esp), %eax
185 /       prefetchnta     (%eax)
186 /       prefetchnta     32(%eax)
187         .end
189         .inline prefetch_write_many,4
190 /       movl            (%esp), %eax
191 /       prefetcht0      (%eax)
192 /       prefetcht0      32(%eax)
193         .end
195         .inline prefetch_write_once,4
196 /       movl            (%esp), %eax
197 /       prefetcht0      (%eax)
198 /       prefetcht0      32(%eax)
199         .end