VirtualBox

source: vbox/trunk/include/iprt/asm-amd64-x86-watcom-16.h@ 69016

Last change on this file since 69016 was 68606, checked in by vboxsync, 7 years ago

iprt/asm*: Made the code safe to use with 16-bit code models employing near data pointers (i.e. adding RT_FAR to all pointers).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.9 KB
Line 
1/** @file
2 * IPRT - AMD64 and x86 Specific Assembly Functions, 16-bit Watcom C pragma aux.
3 */
4
5/*
6 * Copyright (C) 2006-2016 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___iprt_asm_amd64_x86_h
27# error "Don't include this header directly."
28#endif
29#ifndef ___iprt_asm_amd64_x86_watcom_16_h
30#define ___iprt_asm_amd64_x86_watcom_16_h
31
32/*
33 * Turns out we cannot use 'ds' for segment stuff here because the compiler
34 * seems to insists on loading the DGROUP segment into 'ds' before calling
35 * stuff when using -ecc. Using 'es' instead as this seems to work fine.
36 *
37 * Note! The #undef that preceds the #pragma aux statements is for undoing
38 * the mangling, because the symbol in #pragma aux [symbol] statements
39 * doesn't get subjected to preprocessing. This is also why we include
40 * the watcom header at the top rather than at the bottom of the
41 * asm-amd64-x86.h file.
42 */
43
44#undef ASMGetIDTR
45#pragma aux ASMGetIDTR = \
46 ".286p" \
47 "sidt fword ptr es:[bx]" \
48 parm [es bx] \
49 modify exact [];
50
51#undef ASMGetIdtrLimit
52#pragma aux ASMGetIdtrLimit = \
53 ".286p" \
54 "sub sp, 8" \
55 "mov bx, sp" \
56 "sidt fword ptr ss:[bx]" \
57 "mov bx, ss:[bx]" \
58 "add sp, 8" \
59 parm [] \
60 value [bx] \
61 modify exact [bx];
62
63#undef ASMSetIDTR
64#pragma aux ASMSetIDTR = \
65 ".286p" \
66 "lidt fword ptr es:[bx]" \
67 parm [es bx] nomemory \
68 modify nomemory;
69
70#undef ASMGetGDTR
71#pragma aux ASMGetGDTR = \
72 ".286p" \
73 "sgdt fword ptr es:[bx]" \
74 parm [es bx] \
75 modify exact [];
76
77#undef ASMSetGDTR
78#pragma aux ASMSetGDTR = \
79 ".286p" \
80 "lgdt fword ptr es:[bx]" \
81 parm [es bx] nomemory \
82 modify exact [] nomemory;
83
84#undef ASMGetCS
85#pragma aux ASMGetCS = \
86 "mov ax, cs" \
87 parm [] nomemory \
88 value [ax] \
89 modify exact [ax] nomemory;
90
91#undef ASMGetDS
92#pragma aux ASMGetDS = \
93 "mov ax, ds" \
94 parm [] nomemory \
95 value [ax] \
96 modify exact [ax] nomemory;
97
98#undef ASMGetES
99#pragma aux ASMGetES = \
100 "mov ax, es" \
101 parm [] nomemory \
102 value [ax] \
103 modify exact [ax] nomemory;
104
105#undef ASMGetFS
106#pragma aux ASMGetFS = \
107 ".386" \
108 "mov ax, fs" \
109 parm [] nomemory \
110 value [ax] \
111 modify exact [ax] nomemory;
112
113#undef ASMGetGS
114#pragma aux ASMGetGS = \
115 ".386" \
116 "mov ax, gs" \
117 parm [] nomemory \
118 value [ax] \
119 modify exact [ax] nomemory;
120
121#undef ASMGetSS
122#pragma aux ASMGetSS = \
123 "mov ax, ss" \
124 parm [] nomemory \
125 value [ax] \
126 modify exact [ax] nomemory;
127
128#undef ASMGetTR
129#pragma aux ASMGetTR = \
130 ".286" \
131 "str ax" \
132 parm [] nomemory \
133 value [ax] \
134 modify exact [ax] nomemory;
135
136#undef ASMGetLDTR
137#pragma aux ASMGetLDTR = \
138 ".286" \
139 "sldt ax" \
140 parm [] nomemory \
141 value [ax] \
142 modify exact [ax] nomemory;
143
144/** @todo ASMGetSegAttr */
145
146#undef ASMGetFlags
147#pragma aux ASMGetFlags = \
148 "pushf" \
149 "pop ax" \
150 parm [] nomemory \
151 value [ax] \
152 modify exact [ax] nomemory;
153
154#undef ASMSetFlags
155#pragma aux ASMSetFlags = \
156 "push ax" \
157 "popf" \
158 parm [ax] nomemory \
159 modify exact [] nomemory;
160
161#undef ASMChangeFlags
162#pragma aux ASMChangeFlags = \
163 "pushf" \
164 "pop ax" \
165 "and dx, ax" \
166 "or dx, cx" \
167 "push dx" \
168 "popf" \
169 parm [dx] [cx] nomemory \
170 value [ax] \
171 modify exact [dx] nomemory;
172
173#undef ASMAddFlags
174#pragma aux ASMAddFlags = \
175 "pushf" \
176 "pop ax" \
177 "or dx, ax" \
178 "push dx" \
179 "popf" \
180 parm [dx] nomemory \
181 value [ax] \
182 modify exact [dx] nomemory;
183
184#undef ASMClearFlags
185#pragma aux ASMClearFlags = \
186 "pushf" \
187 "pop ax" \
188 "and dx, ax" \
189 "push dx" \
190 "popf" \
191 parm [dx] nomemory \
192 value [ax] \
193 modify exact [dx] nomemory;
194
195/* Note! Must use the 64-bit integer return value convension.
196 The order of registers in the value [set] does not seem to mean anything. */
197#undef ASMReadTSC
198#pragma aux ASMReadTSC = \
199 ".586" \
200 "rdtsc" \
201 "mov ebx, edx" \
202 "mov ecx, eax" \
203 "shr ecx, 16" \
204 "xchg eax, edx" \
205 "shr eax, 16" \
206 parm [] nomemory \
207 value [dx cx bx ax] \
208 modify exact [ax bx cx dx] nomemory;
209
210/** @todo ASMReadTscWithAux if needed (rdtscp not recognized by compiler) */
211
212
213/* ASMCpuId: Implemented externally, too many parameters. */
214/* ASMCpuId_Idx_ECX: Implemented externally, too many parameters. */
215/* ASMCpuIdExSlow: Always implemented externally. */
216/* ASMCpuId_ECX_EDX: Implemented externally, too many parameters. */
217
218#undef ASMCpuId_EAX
219#pragma aux ASMCpuId_EAX = \
220 ".586" \
221 "xchg ax, dx" \
222 "shl eax, 16" \
223 "mov ax, dx" \
224 "cpuid" \
225 "mov edx, eax" \
226 "shr edx, 16" \
227 parm [ax dx] \
228 value [ax dx] \
229 modify exact [ax bx cx dx];
230
231#undef ASMCpuId_EBX
232#pragma aux ASMCpuId_EBX = \
233 ".586" \
234 "xchg ax, dx" \
235 "shl eax, 16" \
236 "mov ax, dx" \
237 "cpuid" \
238 "mov ax, bx" \
239 "shr ebx, 16" \
240 parm [ax dx] \
241 value [ax bx] \
242 modify exact [ax bx cx dx];
243
244#undef ASMCpuId_ECX
245#pragma aux ASMCpuId_ECX = \
246 ".586" \
247 "xchg ax, dx" \
248 "shl eax, 16" \
249 "mov ax, dx" \
250 "cpuid" \
251 "mov ax, cx" \
252 "shr ecx, 16" \
253 parm [ax dx] \
254 value [ax cx] \
255 modify exact [ax bx cx dx];
256
257#undef ASMCpuId_EDX
258#pragma aux ASMCpuId_EDX = \
259 ".586" \
260 "xchg ax, dx" \
261 "shl eax, 16" \
262 "mov ax, dx" \
263 "cpuid" \
264 "mov ax, dx" \
265 "shr edx, 16" \
266 parm [ax dx] \
267 value [ax dx] \
268 modify exact [ax bx cx dx];
269
270/* ASMHasCpuId: MSC inline in main source file. */
271/* ASMGetApicId: Implemented externally, lazy bird. */
272
273/* Note! Again, when returning two registers, watcom have certain fixed ordering rules (low:high):
274 ax:bx, ax:cx, ax:dx, ax:si, ax:di
275 bx:cx, bx:dx, bx:si, bx:di
276 dx:cx, si:cx, di:cx
277 si:dx, di:dx
278 si:di
279 This ordering seems to apply to parameter values too. */
280#undef ASMGetCR0
281#pragma aux ASMGetCR0 = \
282 ".386" \
283 "mov eax, cr0" \
284 "mov edx, eax" \
285 "shr edx, 16" \
286 parm [] nomemory \
287 value [ax dx] \
288 modify exact [ax dx] nomemory;
289
290#undef ASMSetCR0
291#pragma aux ASMSetCR0 = \
292 ".386" \
293 "shl edx, 16" \
294 "mov dx, ax" \
295 "mov cr0, edx" \
296 parm [ax dx] nomemory \
297 modify exact [dx] nomemory;
298
299#undef ASMGetCR2
300#pragma aux ASMGetCR2 = \
301 ".386" \
302 "mov eax, cr2" \
303 "mov edx, eax" \
304 "shr edx, 16" \
305 parm [] nomemory \
306 value [ax dx] \
307 modify exact [ax dx] nomemory;
308
309#undef ASMSetCR2
310#pragma aux ASMSetCR2 = \
311 ".386" \
312 "shl edx, 16" \
313 "mov dx, ax" \
314 "mov cr2, edx" \
315 parm [ax dx] nomemory \
316 modify exact [dx] nomemory;
317
318#undef ASMGetCR3
319#pragma aux ASMGetCR3 = \
320 ".386" \
321 "mov eax, cr3" \
322 "mov edx, eax" \
323 "shr edx, 16" \
324 parm [] nomemory \
325 value [ax dx] \
326 modify exact [ax dx] nomemory;
327
328#undef ASMSetCR3
329#pragma aux ASMSetCR3 = \
330 ".386" \
331 "shl edx, 16" \
332 "mov dx, ax" \
333 "mov cr3, edx" \
334 parm [ax dx] nomemory \
335 modify exact [dx] nomemory;
336
337#undef ASMReloadCR3
338#pragma aux ASMReloadCR3 = \
339 ".386" \
340 "mov eax, cr3" \
341 "mov cr3, eax" \
342 parm [] nomemory \
343 modify exact [ax] nomemory;
344
345#undef ASMGetCR4
346#pragma aux ASMGetCR4 = \
347 ".386" \
348 "mov eax, cr4" \
349 "mov edx, eax" \
350 "shr edx, 16" \
351 parm [] nomemory \
352 value [ax dx] \
353 modify exact [ax dx] nomemory;
354
355#undef ASMSetCR4
356#pragma aux ASMSetCR4 = \
357 ".386" \
358 "shl edx, 16" \
359 "mov dx, ax" \
360 "mov cr4, edx" \
361 parm [ax dx] nomemory \
362 modify exact [dx] nomemory;
363
364/* ASMGetCR8: Don't bother for 16-bit. */
365/* ASMSetCR8: Don't bother for 16-bit. */
366
367#undef ASMIntEnable
368#pragma aux ASMIntEnable = \
369 "sti" \
370 parm [] nomemory \
371 modify exact [] nomemory;
372
373#undef ASMIntDisable
374#pragma aux ASMIntDisable = \
375 "cli" \
376 parm [] nomemory \
377 modify exact [] nomemory;
378
379#undef ASMIntDisableFlags
380#pragma aux ASMIntDisableFlags = \
381 "pushf" \
382 "cli" \
383 "pop ax" \
384 parm [] nomemory \
385 value [ax] \
386 modify exact [] nomemory;
387
388#undef ASMHalt
389#pragma aux ASMHalt = \
390 "hlt" \
391 parm [] nomemory \
392 modify exact [] nomemory;
393
394#undef ASMRdMsr
395#pragma aux ASMRdMsr = \
396 ".586" \
397 "shl ecx, 16" \
398 "mov cx, ax" \
399 "rdmsr" \
400 "mov ebx, edx" \
401 "mov ecx, eax" \
402 "shr ecx, 16" \
403 "xchg eax, edx" \
404 "shr eax, 16" \
405 parm [ax cx] nomemory \
406 value [dx cx bx ax] \
407 modify exact [ax bx cx dx] nomemory;
408
409/* ASMWrMsr: Implemented externally, lazy bird. */
410/* ASMRdMsrEx: Implemented externally, lazy bird. */
411/* ASMWrMsrEx: Implemented externally, lazy bird. */
412
413#undef ASMRdMsr_Low
414#pragma aux ASMRdMsr_Low = \
415 ".586" \
416 "shl ecx, 16" \
417 "mov cx, ax" \
418 "rdmsr" \
419 "mov edx, eax" \
420 "shr edx, 16" \
421 parm [ax cx] nomemory \
422 value [ax dx] \
423 modify exact [ax bx cx dx] nomemory;
424
425#undef ASMRdMsr_High
426#pragma aux ASMRdMsr_High = \
427 ".586" \
428 "shl ecx, 16" \
429 "mov cx, ax" \
430 "rdmsr" \
431 "mov eax, edx" \
432 "shr edx, 16" \
433 parm [ax cx] nomemory \
434 value [ax dx] \
435 modify exact [ax bx cx dx] nomemory;
436
437
438#undef ASMGetDR0
439#pragma aux ASMGetDR0 = \
440 ".386" \
441 "mov eax, dr0" \
442 "mov edx, eax" \
443 "shr edx, 16" \
444 parm [] nomemory \
445 value [ax dx] \
446 modify exact [ax dx] nomemory;
447
448#undef ASMGetDR1
449#pragma aux ASMGetDR1 = \
450 ".386" \
451 "mov eax, dr1" \
452 "mov edx, eax" \
453 "shr edx, 16" \
454 parm [] nomemory \
455 value [ax dx] \
456 modify exact [ax dx] nomemory;
457
458#undef ASMGetDR2
459#pragma aux ASMGetDR2 = \
460 ".386" \
461 "mov eax, dr2" \
462 "mov edx, eax" \
463 "shr edx, 16" \
464 parm [] nomemory \
465 value [ax dx] \
466 modify exact [ax dx] nomemory;
467
468#undef ASMGetDR3
469#pragma aux ASMGetDR3 = \
470 ".386" \
471 "mov eax, dr3" \
472 "mov edx, eax" \
473 "shr edx, 16" \
474 parm [] nomemory \
475 value [ax dx] \
476 modify exact [ax dx] nomemory;
477
478#undef ASMGetDR6
479#pragma aux ASMGetDR6 = \
480 ".386" \
481 "mov eax, dr6" \
482 "mov edx, eax" \
483 "shr edx, 16" \
484 parm [] nomemory \
485 value [ax dx] \
486 modify exact [ax dx] nomemory;
487
488#undef ASMGetAndClearDR6
489#pragma aux ASMGetAndClearDR6 = \
490 ".386" \
491 "mov edx, 0ffff0ff0h" \
492 "mov eax, dr6" \
493 "mov dr6, edx" \
494 "mov edx, eax" \
495 "shr edx, 16" \
496 parm [] nomemory \
497 value [ax dx] \
498 modify exact [ax dx] nomemory;
499
500#undef ASMGetDR7
501#pragma aux ASMGetDR7 = \
502 ".386" \
503 "mov eax, dr7" \
504 "mov edx, eax" \
505 "shr edx, 16" \
506 parm [] nomemory \
507 value [ax dx] \
508 modify exact [ax dx] nomemory;
509
510#undef ASMSetDR0
511#pragma aux ASMSetDR0 = \
512 ".386" \
513 "shl edx, 16" \
514 "mov dx, ax" \
515 "mov dr0, edx" \
516 parm [ax dx] nomemory \
517 modify exact [dx] nomemory;
518
519#undef ASMSetDR1
520#pragma aux ASMSetDR1 = \
521 ".386" \
522 "shl edx, 16" \
523 "mov dx, ax" \
524 "mov dr1, edx" \
525 parm [ax dx] nomemory \
526 modify exact [dx] nomemory;
527
528#undef ASMSetDR2
529#pragma aux ASMSetDR2 = \
530 ".386" \
531 "shl edx, 16" \
532 "mov dx, ax" \
533 "mov dr2, edx" \
534 parm [ax dx] nomemory \
535 modify exact [dx] nomemory;
536
537#undef ASMSetDR3
538#pragma aux ASMSetDR3 = \
539 ".386" \
540 "shl edx, 16" \
541 "mov dx, ax" \
542 "mov dr3, edx" \
543 parm [ax dx] nomemory \
544 modify exact [dx] nomemory;
545
546#undef ASMSetDR6
547#pragma aux ASMSetDR6 = \
548 ".386" \
549 "shl edx, 16" \
550 "mov dx, ax" \
551 "mov dr6, edx" \
552 parm [ax dx] nomemory \
553 modify exact [dx] nomemory;
554
555#undef ASMSetDR7
556#pragma aux ASMSetDR7 = \
557 ".386" \
558 "shl edx, 16" \
559 "mov dx, ax" \
560 "mov dr7, edx" \
561 parm [ax dx] nomemory \
562 modify exact [dx] nomemory;
563
564/* Yeah, could've used outp here, but this keeps the main file simpler. */
565#undef ASMOutU8
566#pragma aux ASMOutU8 = \
567 "out dx, al" \
568 parm [dx] [al] nomemory \
569 modify exact [] nomemory;
570
571#undef ASMInU8
572#pragma aux ASMInU8 = \
573 "in al, dx" \
574 parm [dx] nomemory \
575 value [al] \
576 modify exact [] nomemory;
577
578#undef ASMOutU16
579#undef ASMOutU16
580#pragma aux ASMOutU16 = \
581 "out dx, ax" \
582 parm [dx] [ax] nomemory \
583 modify exact [] nomemory;
584
585#undef ASMInU16
586#pragma aux ASMInU16 = \
587 "in ax, dx" \
588 parm [dx] nomemory \
589 value [ax] \
590 modify exact [] nomemory;
591
592#undef ASMOutU32
593#pragma aux ASMOutU32 = \
594 ".386" \
595 "shl ecx, 16" \
596 "mov cx, ax" \
597 "mov eax, ecx" \
598 "out dx, eax" \
599 parm [dx] [ax cx] nomemory \
600 modify exact [] nomemory;
601
602#undef ASMInU32
603#pragma aux ASMInU32 = \
604 ".386" \
605 "in eax, dx" \
606 "mov ecx, eax" \
607 "shr ecx, 16" \
608 parm [dx] nomemory \
609 value [ax cx] \
610 modify exact [] nomemory;
611
612#undef ASMOutStrU8
613#pragma aux ASMOutStrU8 = \
614 ".186" \
615 "mov ds, bx" \
616 "rep outsb" \
617 parm [dx] [bx si] [cx] nomemory \
618 modify exact [si cx ds] nomemory;
619
620#undef ASMInStrU8
621#pragma aux ASMInStrU8 = \
622 ".186" \
623 "rep insb" \
624 parm [dx] [es di] [cx] \
625 modify exact [di cx];
626
627#undef ASMOutStrU16
628#pragma aux ASMOutStrU16 = \
629 ".186" \
630 "mov ds, bx" \
631 "rep outsw" \
632 parm [dx] [bx si] [cx] nomemory \
633 modify exact [si cx ds] nomemory;
634
635#undef ASMInStrU16
636#pragma aux ASMInStrU16 = \
637 ".186" \
638 "rep insw" \
639 parm [dx] [es di] [cx] \
640 modify exact [di cx];
641
642#undef ASMOutStrU32
643#pragma aux ASMOutStrU32 = \
644 ".386" \
645 "mov ds, bx" \
646 "rep outsd" \
647 parm [dx] [bx si] [cx] nomemory \
648 modify exact [si cx ds] nomemory;
649
650#undef ASMInStrU32
651#pragma aux ASMInStrU32 = \
652 ".386" \
653 "rep insd" \
654 parm [dx] [es di] [cx] \
655 modify exact [di cx];
656
657#undef ASMInvalidatePage
658#pragma aux ASMInvalidatePage = \
659 ".486" \
660 "shl edx, 16" \
661 "mov dx, ax" \
662 "invlpg [edx]" \
663 parm [ax dx] \
664 modify exact [dx];
665
666#undef ASMWriteBackAndInvalidateCaches
667#pragma aux ASMWriteBackAndInvalidateCaches = \
668 ".486" \
669 "wbinvd" \
670 parm [] nomemory \
671 modify exact [] nomemory;
672
673#undef ASMInvalidateInternalCaches
674#pragma aux ASMInvalidateInternalCaches = \
675 ".486" \
676 "invd" \
677 parm [] \
678 modify exact [];
679
680#endif
681
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette