VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-3-cmn-template.mac@ 102157

Last change on this file since 102157 was 102157, checked in by vboxsync, 10 months ago

ValKit/bs3kit,bs3-cpu-basic-3: Experimental support for loading a 2nd test image above 1MB (at 8MB by default). This should allow for larger testcases, esp. for 32-bit and 64-bit code. bugref:10371

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 26.1 KB
Line 
1; $Id: bs3-cpu-basic-3-cmn-template.mac 102157 2023-11-20 16:16:55Z vboxsync $
2;; @file
3; BS3Kit - bs3-cpu-basic-3 assembly template, common code (CMN).
4;
5
6;
7; Copyright (C) 2007-2023 Oracle and/or its affiliates.
8;
9; This file is part of VirtualBox base platform packages, as
10; available from https://www.virtualbox.org.
11;
12; This program is free software; you can redistribute it and/or
13; modify it under the terms of the GNU General Public License
14; as published by the Free Software Foundation, in version 3 of the
15; License.
16;
17; This program is distributed in the hope that it will be useful, but
18; WITHOUT ANY WARRANTY; without even the implied warranty of
19; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20; General Public License for more details.
21;
22; You should have received a copy of the GNU General Public License
23; along with this program; if not, see <https://www.gnu.org/licenses>.
24;
25; The contents of this file may alternatively be used under the terms
26; of the Common Development and Distribution License Version 1.0
27; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28; in the VirtualBox distribution, in which case the provisions of the
29; CDDL are applicable instead of those of the GPL.
30;
31; You may elect to license modified versions of this file under the
32; terms and conditions of either the GPL or the CDDL or both.
33;
34; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35;
36
37
38;*********************************************************************************************************************************
39;* Header Files *
40;*********************************************************************************************************************************
41%include "bs3kit-template-header.mac" ; setup environment
42
43
44TMPL_BEGIN_TEXT
45
46
47;*********************************************************************************************************************************
48;* External Symbols *
49;*********************************************************************************************************************************
50extern _Bs3Text16_StartOfSegment
51
52
53;*********************************************************************************************************************************
54;* LEA - in BS3X1TEXT16 *
55;*********************************************************************************************************************************
56
57%define LEA_EAX 011111110h
58%define LEA_ECX 022222202h
59%define LEA_EDX 033333033h
60%define LEA_EBX 044440444h
61%define LEA_ESP 051525356h
62%define LEA_EBP 055555551h
63%define LEA_ESI 066666616h
64%define LEA_EDI 077777177h
65
66%define LEA_RAX 01111111111111110h
67%define LEA_RCX 02222222222222202h
68%define LEA_RDX 03333333333333033h
69%define LEA_RBX 04444444444440444h
70%define LEA_RSP 058595a5d51525356h
71%define LEA_RBP 05555555555555551h
72%define LEA_RSI 06666666666666616h
73%define LEA_RDI 07777777777777177h
74%define LEA_R8 08888888888881888h
75%define LEA_R9 09999999999999992h
76%define LEA_R10 0aaaaaaaaaaaaaa2ah
77%define LEA_R11 0bbbbbbbbbbbbb2bbh
78%define LEA_R12 0cccccccccccc2ccch
79%define LEA_R13 0ddddddddddddddd3h
80%define LEA_R14 0eeeeeeeeeeeeee3eh
81%define LEA_R15 0fffffffffffff3ffh
82
83
84
85;
86; Switching segment for the 16-bit stuff, this may need some space.
87;
88%if TMPL_BITS == 16
89BS3_BEGIN_X0TEXT16
90%else
91TMPL_BEGIN_TEXT
92%endif
93
94
95%if TMPL_BITS != 64
96 ;
97 ; Macros for 16-bit lea tests.
98 ;
99 %ifndef BS3CPUBASIC3_LEA_16_MACROS
100 %define BS3CPUBASIC3_LEA_16_MACROS
101 %macro test_lea_16_one 3
102 call .load_regs
103 lea strict %1, strict %2
104 cmp %1, %3 & 0ffffh
105 jz %%okay
106 int3
107 %%okay:
108 %endm
109 %macro test_lea_16_inner 2
110 test_lea_16_one ax, %1, %2
111 test_lea_16_one cx, %1, %2
112 test_lea_16_one dx, %1, %2
113 test_lea_16_one bx, %1, %2
114 test_lea_16_one bp, %1, %2
115 test_lea_16_one si, %1, %2
116 test_lea_16_one di, %1, %2
117
118 test_lea_16_one eax, %1, %2
119 test_lea_16_one ecx, %1, %2
120 test_lea_16_one edx, %1, %2
121 test_lea_16_one ebx, %1, %2
122 test_lea_16_one ebp, %1, %2
123 test_lea_16_one esi, %1, %2
124 test_lea_16_one edi, %1, %2
125 %endm
126 %macro test_lea_16_outer 3
127 %if %1 == 0
128 test_lea_16_inner [%2], %3
129 %else
130 test_lea_16_inner [word %3], %3 ; mod0/6 = disp16
131 %endif
132 test_lea_16_inner [%2 + 07fh], %3 + 7fh
133 test_lea_16_inner [%2 - 19], %3 - 19
134 test_lea_16_inner [%2 + 5708h], %3 + 5708h
135 test_lea_16_inner [%2 - 7293h], %3 - 7293h
136 %endm
137 %endif
138
139;;
140; Tests 16-bit addressing using the LEA instruction.
141;
142BS3_PROC_BEGIN_CMN bs3CpuBasic3_lea_16, BS3_PBC_FAR
143 pushad
144
145 test_lea_16_outer 0, bx + si, 00444h+06616h
146 test_lea_16_outer 0, bx + di, 00444h+07177h
147 test_lea_16_outer 0, bp + si, 05551h+06616h
148 test_lea_16_outer 0, bp + di, 05551h+07177h
149 test_lea_16_outer 0, si, 06616h
150 test_lea_16_outer 0, di, 07177h
151 test_lea_16_outer 1, bp, 05551h
152 test_lea_16_outer 0, bx, 00444h
153
154 popad
155 BS3_HYBRID_RET
156
157.load_regs:
158 mov eax, LEA_EAX
159 mov ecx, LEA_ECX
160 mov edx, LEA_EDX
161 mov ebx, LEA_EBX
162 mov ebp, LEA_EBP
163 mov esi, LEA_ESI
164 mov edi, LEA_EDI
165 ret
166BS3_PROC_END_CMN bs3CpuBasic3_lea_16
167
168
169;
170; Switching segment for the 16-bit stuff, SIB needs too much space.
171;
172 %if TMPL_BITS == 16
173BS3_BEGIN_X1TEXT16
174 %endif
175
176;
177; Macros for 32-bit lea tests.
178;
179 %if TMPL_BITS == 16
180 %define MY_O16 67h,
181 %define MY_O32 67h, 66h,
182 %define MY_CMP_O32 66h,
183 %else
184 %define MY_O16 66h,
185 %define MY_O32
186 %define MY_CMP_O32
187 %endif
188
189;;
190; Tests 32-bit addressing using the LEA instruction.
191;
192BS3_PROC_BEGIN_CMN bs3CpuBasic3_lea_32, BS3_PBC_FAR
193 pushad
194 mov [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))], esp
195
196 ;
197 ; Loop thru all the modr/m memory encodings.
198 ;
199 %assign iMod 0
200 %rep 3
201 %assign iDstReg 0
202 %rep 8
203 %assign iMemReg 0
204 %rep 8
205 %if iDstReg == 0
206 %assign iDstReg_Value LEA_EAX
207 %elif iDstReg == 1
208 %assign iDstReg_Value LEA_ECX
209 %elif iDstReg == 2
210 %assign iDstReg_Value LEA_EDX
211 %elif iDstReg == 3
212 %assign iDstReg_Value LEA_EBX
213 %elif iDstReg == 4
214 %assign iDstReg_Value LEA_ESP
215 %elif iDstReg == 5
216 %assign iDstReg_Value LEA_EBP
217 %elif iDstReg == 6
218 %assign iDstReg_Value LEA_ESI
219 %elif iDstReg == 7
220 %assign iDstReg_Value LEA_EDI
221 %else
222 %error iDstReg
223 %endif
224
225 %if iMemReg == 4
226 ;
227 ; SIB.
228 ;
229 %assign iBase 0
230 %rep 8
231 %if iBase == 0
232 %assign iBase_Value LEA_EAX
233 %elif iBase == 1
234 %assign iBase_Value LEA_ECX
235 %elif iBase == 2
236 %assign iBase_Value LEA_EDX
237 %elif iBase == 3
238 %assign iBase_Value LEA_EBX
239 %elif iBase == 4
240 %assign iBase_Value LEA_ESP
241 %elif iBase == 5 && iMod == 0
242 %assign iBase_Value 0
243 %elif iBase == 5
244 %assign iBase_Value LEA_EBP
245 %elif iBase == 6
246 %assign iBase_Value LEA_ESI
247 %elif iBase == 7
248 %assign iBase_Value LEA_EDI
249 %else
250 %error iBase
251 %endif
252
253 %assign iIndex 0
254 %assign cShift 0 ; we don't have enough room for checking all the shifts in the 16-bit segment or the total image.
255 %rep 8
256 %if iIndex == 0
257 %assign iIndex_Value LEA_EAX
258 %elif iIndex == 1
259 %assign iIndex_Value LEA_ECX
260 %elif iIndex == 2
261 %assign iIndex_Value LEA_EDX
262 %elif iIndex == 3
263 %assign iIndex_Value LEA_EBX
264 %elif iIndex == 4
265 %assign iIndex_Value 0
266 %elif iIndex == 5
267 %assign iIndex_Value LEA_EBP
268 %elif iIndex == 6
269 %assign iIndex_Value LEA_ESI
270 %elif iIndex == 7
271 %assign iIndex_Value LEA_EDI
272 %else
273 %error iIndex
274 %endif
275
276 ;
277 ; We don't test all shift combinations, there just isn't enough space
278 ; in the image (32-bit case) or the segment (16-bit case) unfortunately.
279 ;
280 %if TMPL_BITS == 32
281 %assign cShiftLoops 2
282 %else
283 %assign cShiftLoops 1
284 %endif
285 %rep cShiftLoops
286
287 ;
288 ; LEA+SIB w/ 32-bit operand size.
289 ;
290 call .load_regs
291 %if iBase == 4 || iDstReg == 4
292 mov esp, LEA_ESP
293 %endif
294
295 ; lea
296 %assign iValue iBase_Value + (iIndex_Value << cShift)
297 db MY_O32 8dh, X86_MODRM_MAKE(iMod, iDstReg, iMemReg), X86_SIB_MAKE(iBase, iIndex, cShift)
298 %if iMod == X86_MOD_MEM1
299 db -119
300 %assign iValue iValue - 119
301 %elif iMod == X86_MOD_MEM4 || (iMod == 0 && iBase == 5)
302 dd -04353f1ech
303 %assign iValue iValue - 04353f1ech
304 %endif
305
306 ; cmp iDstReg, iValue
307 db MY_CMP_O32 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg)
308 dd iValue & 0ffffffffh
309 %if iBase == 4 || iDstReg == 4
310 mov esp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
311 %endif
312 jz $+3
313 int3
314 %assign cShift (cShift + 1) & 3
315
316 ;
317 ; LEA+SIB w/ 16-bit operand size.
318 ;
319 %if TMPL_BITS == 32 ; No room in the 16-bit segment for all of this.
320 call .load_regs
321 %if iBase == 4 || iDstReg == 4
322 mov esp, LEA_ESP
323 %endif
324
325 ; lea
326 %assign iValue iBase_Value + (iIndex_Value << cShift)
327 db MY_O16 8dh, X86_MODRM_MAKE(iMod, iDstReg, iMemReg), X86_SIB_MAKE(iBase, iIndex, cShift)
328 %if iMod == X86_MOD_MEM1
329 db -7
330 %assign iValue iValue - 7
331 %elif iMod == X86_MOD_MEM4 || (iMod == 0 && iBase == 5)
332 dd -073d676e4h
333 %assign iValue iValue - 073d676e4h
334 %endif
335
336 ; cmp iDstReg, iValue
337 db MY_CMP_O32 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg)
338 dd (iValue & 00000ffffh) | (iDstReg_Value & 0ffff0000h)
339 %if 1 || iBase == 4 || iDstReg == 4
340 mov esp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
341 %endif
342 jz $+3
343 int3
344 %assign cShift (cShift + 2) & 3
345 %endif ; TMPL_BITS == 32
346 %endrep
347 %assign iIndex iIndex + 1
348 %endrep
349 %assign iBase iBase + 1
350 %endrep
351
352 %else ; !SIB
353 ;
354 ; Plain lea reg, [reg] with disp according to iMod,
355 ; or lea reg, [disp32] if iMemReg == 5 && iMod == 0.
356 ;
357 %if iMemReg == 0
358 %assign iMemReg_Value LEA_EAX
359 %elif iMemReg == 1
360 %assign iMemReg_Value LEA_ECX
361 %elif iMemReg == 2
362 %assign iMemReg_Value LEA_EDX
363 %elif iMemReg == 3
364 %assign iMemReg_Value LEA_EBX
365 %elif iMemReg == 5 && iMod == 0
366 %assign iMemReg_Value 0
367 %elif iMemReg == 5
368 %assign iMemReg_Value LEA_EBP
369 %elif iMemReg == 6
370 %assign iMemReg_Value LEA_ESI
371 %elif iMemReg == 7
372 %assign iMemReg_Value LEA_EDI
373 %else
374 %error iMemReg
375 %endif
376
377 ;
378 ; 32-bit operand size first.
379 ;
380 call .load_regs
381 %if iDstReg == 4
382 mov esp, LEA_ESP
383 %endif
384
385 ; lea
386 %assign iValue iMemReg_Value
387 db MY_O32 8dh, X86_MODRM_MAKE(iMod, iDstReg, iMemReg)
388 %if iMod == X86_MOD_MEM1
389 db 89
390 %assign iValue iValue + 89
391 %elif iMod == X86_MOD_MEM4 || (iMod == 0 && iMemReg == 5)
392 dd 058739af8h
393 %assign iValue iValue + 058739af8h
394 %endif
395
396 ; cmp iDstReg, iValue
397 db MY_CMP_O32 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg)
398 dd iValue & 0ffffffffh
399 %if iDstReg == 4
400 mov esp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
401 %endif
402 jz $+3
403 int3
404
405 ;
406 ; 16-bit operand size next.
407 ;
408 call .load_regs
409 %if iDstReg == 4
410 mov esp, LEA_ESP
411 %endif
412
413 ; lea
414 %assign iValue iMemReg_Value
415 db MY_O16 8dh, X86_MODRM_MAKE(iMod, iDstReg, iMemReg)
416 %if iMod == X86_MOD_MEM1
417 db -98
418 %assign iValue iValue - 98
419 %elif iMod == X86_MOD_MEM4 || (iMod == 0 && iMemReg == 5)
420 dd 0f3694352h
421 %assign iValue iValue + 0f3694352h
422 %endif
423
424 ; cmp iDstReg, iValue
425 db MY_CMP_O32 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg)
426 dd (iValue & 00000ffffh) | (iDstReg_Value & 0ffff0000h)
427 %if iDstReg == 4
428 mov esp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
429 %endif
430 jz $+3
431 int3
432
433 %endif ; !SIB
434 %assign iMemReg iMemReg + 1
435 %endrep
436 %assign iDstReg iDstReg + 1
437 %endrep
438 %assign iMod iMod + 1
439 %endrep
440
441 mov esp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
442 popad
443 BS3_HYBRID_RET
444
445.load_regs:
446 mov eax, LEA_EAX
447 mov ecx, LEA_ECX
448 mov edx, LEA_EDX
449 mov ebx, LEA_EBX
450 mov ebp, LEA_EBP
451 mov esi, LEA_ESI
452 mov edi, LEA_EDI
453 ret
454BS3_PROC_END_CMN bs3CpuBasic3_lea_32
455
456
457%else ; TMPL_BITS == 64
458
459
460;;
461; Tests 64-bit addressing using the LEA instruction.
462;
463BS3_PROC_BEGIN_CMN bs3CpuBasic3_lea_64, BS3_PBC_FAR
464 push rax
465 push rcx
466 push rdx
467 push rbx
468 push rbp
469 push rsi
470 push rdi
471 push r8
472 push r9
473 push r10
474 push r11
475 push r12
476 push r13
477 push r14
478 push r15
479.test_label:
480 mov [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))], rsp
481
482 ;
483 ; Loop thru all the modr/m memory encodings.
484 ;
485 %assign iMod 0
486 %assign iDstReg 0 ; We don't test all destination registers
487 %rep 3
488 %rep 16 ; Destination registers per encoding. Testing all takes too much space.
489 %assign iMemReg 0
490 %rep 16
491 %assign iDstReg_Value %sel(iDstReg+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, LEA_RSP, LEA_RBP, LEA_RSI, LEA_RDI, \
492 LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15)
493
494 %if (iMemReg & 7) == 4
495 ;
496 ; SIB.
497 ;
498 %assign iBase 0
499 %rep 16
500 %if (iBase & 7) == 5 && iMod == 0
501 %assign iBase_Value 0
502 %else
503 %assign iBase_Value %sel(iBase+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, LEA_RSP, LEA_RBP, LEA_RSI, LEA_RDI, \
504 LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15)
505 %endif
506
507 %assign iIndex 0
508 %assign cShift 0 ; we don't have enough room for checking all the shifts.
509 %rep 16
510 %assign iBase_Value %sel(iIndex+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, 0, LEA_RBP, LEA_RSI, LEA_RDI, \
511 LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15)
512
513 ;
514 ; We don't test all shift combinations, there just isn't enough space
515 ; in the image for that.
516 ;
517 %assign cShiftLoops 0 ; Disabled for now
518 %rep cShiftLoops
519%error asdf
520 ;
521 ; LEA+SIB w/ 64-bit operand size and 64-bit address size.
522 ;
523 call .load_regs
524 %if iBase == 4 || iDstReg == 4
525 mov rsp, LEA_RSP
526 %endif
527
528 ; lea
529 %assign iValue iBase_Value + (iIndex_Value << cShift)
530 db X86_OP_REX_W | ((iBase & 8) >> 3) | ((iIndex & 8) >> 2) | ((iDstReg) & 8 >> 1)
531 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7), X86_SIB_MAKE(iBase & 7, iIndex & 7, cShift)
532 %if iMod == X86_MOD_MEM1
533 db -128
534 %assign iValue iValue - 128
535 %elif iMod == X86_MOD_MEM4 || (iMod == 0 && iBase == 5)
536 dd -07fffffffh
537 %assign iValue iValue - 07fffffffh
538 %endif
539
540 ; cmp iDstReg, iValue
541 %if iValue <= 07fffffffh && iValue >= -080000000h
542 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
543 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
544 dd iValue & 0ffffffffh
545 %elif iDstReg != X86_GREG_xAX
546 mov rax, iValue
547 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
548 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
549 %else
550 mov rcx, iValue
551 cmp rax, rcx
552 %endif
553 %if iDstReg == 4
554 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
555 %endif
556 jz $+3
557 int3
558 %assign cShift (cShift + 1) & 3
559
560 %endrep
561 %assign iIndex iIndex + 1
562 %endrep
563 %assign iBase iBase + 1
564 %endrep
565
566 %else ; !SIB
567 ;
568 ; Plain lea reg, [reg] with disp according to iMod,
569 ; or lea reg, [disp32] if iMemReg == 5 && iMod == 0.
570 ;
571 %if (iMemReg & 7) == 5 && iMod == 0
572 %assign iMemReg_Value 0
573 %else
574 %assign iMemReg_Value %sel(iMemReg+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, LEA_RSP, LEA_RBP, LEA_RSI, LEA_RDI, \
575 LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15)
576 %endif
577
578 ;
579 ; 64-bit operand and address size first.
580 ;
581 call .load_regs
582 %if iDstReg == 4
583 mov rsp, LEA_RSP
584 %endif
585
586 ; lea
587 %assign iValue iMemReg_Value
588 db X86_OP_REX_W | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
589 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
590 %if iMod == X86_MOD_MEM1
591 db 39
592 %assign iValue iValue + 39
593 %elif iMod == 0 && (iMemReg & 7) == 5
594 dd .load_regs - $ - 4
595 %elif iMod == X86_MOD_MEM4
596 dd 058739af8h
597 %assign iValue iValue + 058739af8h
598 %endif
599
600 ; cmp iDstReg, iValue
601 %if (iValue <= 07fffffffh && iValue >= -080000000h) || (iMod == 0 && (iMemReg & 7) == 5)
602 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
603 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
604 %if iMod == 0 && (iMemReg & 7) == 5
605 dd .load_regs wrt BS3FLAT
606 %else
607 dd iValue & 0ffffffffh
608 %endif
609 %else
610 %if iDstReg != iMemReg && iValue == iMemReg_Value ; This isn't entirely safe, but it saves a bit of space.
611 db X86_OP_REX_W | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
612 db 39h, X86_MODRM_MAKE(X86_MOD_REG, iDstReg & 7, iMemReg & 7)
613 %elif iDstReg != X86_GREG_xAX
614 mov rax, iValue
615 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
616 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
617 %else
618 mov rcx, iValue
619 cmp rax, rcx
620 %endif
621 %endif
622 %if iDstReg == 4
623 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
624 %endif
625 jz $+3
626 int3
627
628 ;
629 ; 64-bit operand and 32-bit address size.
630 ;
631 call .load_regs
632 %if iDstReg == 4
633 mov rsp, LEA_RSP
634 %endif
635
636 ; lea
637 %assign iValue iMemReg_Value
638 db X86_OP_PRF_SIZE_ADDR
639 db X86_OP_REX_W | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
640 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
641 %if iMod == X86_MOD_MEM1
642 db -92
643 %assign iValue iValue - 92
644 %elif iMod == 0 && (iMemReg & 7) == 5
645 dd .test_label - $ - 4
646 %elif iMod == X86_MOD_MEM4
647 dd -038f8acf3h
648 %assign iValue iValue - 038f8acf3h
649 %endif
650 %assign iValue iValue & 0ffffffffh
651
652 ; cmp iDstReg, iValue
653 %if (iValue <= 07fffffffh && iValue >= 0) || (iMod == 0 && (iMemReg & 7) == 5)
654 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
655 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
656 %if iMod == 0 && (iMemReg & 7) == 5
657 dd .test_label wrt BS3FLAT
658 %else
659 dd iValue
660 %endif
661 %else
662 %if iDstReg != X86_GREG_xAX
663 mov eax, iValue
664 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
665 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
666 %else
667 mov ecx, iValue
668 cmp rax, rcx
669 %endif
670 %endif
671 %if iDstReg == 4
672 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
673 %endif
674 jz $+3
675 int3
676
677 ;
678 ; 32-bit operand and 64-bit address size.
679 ;
680 call .load_regs
681 %if iDstReg == 4
682 mov rsp, LEA_RSP
683 %endif
684
685 ; lea
686 %assign iValue iMemReg_Value
687 %if iDstReg >= 8 || iMemReg >= 8
688 db X86_OP_REX | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
689 %endif
690 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
691 %if iMod == X86_MOD_MEM1
692 db 16
693 %assign iValue iValue + 16
694 %elif iMod == 0 && (iMemReg & 7) == 5
695 dd .load_regs - $ - 4
696 %elif iMod == X86_MOD_MEM4
697 dd 0596829deh
698 %assign iValue iValue + 0596829deh
699 %endif
700 %assign iValue iValue & 0ffffffffh
701
702 ; cmp iDstReg, iValue
703 %if (iValue <= 07fffffffh && iValue >= 0) || (iMod == 0 && (iMemReg & 7) == 5)
704 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
705 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
706 %if iMod == 0 && (iMemReg & 7) == 5
707 dd .load_regs wrt BS3FLAT
708 %else
709 dd iValue
710 %endif
711 %else
712 %if iDstReg != X86_GREG_xAX
713 mov eax, iValue
714 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
715 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
716 %else
717 mov ecx, iValue
718 cmp rax, rcx
719 %endif
720 %endif
721 %if iDstReg == 4
722 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
723 %endif
724 jz $+3
725 int3
726
727 ;
728 ; 16-bit operand and 64-bit address size.
729 ;
730 call .load_regs
731 %if iDstReg == 4
732 mov rsp, LEA_RSP
733 %endif
734
735 ; lea
736 %assign iValue iMemReg_Value
737 db X86_OP_PRF_SIZE_OP
738 %if iDstReg >= 8 || iMemReg >= 8
739 db X86_OP_REX | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
740 %endif
741 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
742 %if iMod == X86_MOD_MEM1
743 db -16
744 %assign iValue iValue - 16
745 %elif iMod == 0 && (iMemReg & 7) == 5
746 dd _Bs3Text16_StartOfSegment - $ - 4 + 7 wrt BS3FLAT
747 %assign iValue 7
748 %elif iMod == X86_MOD_MEM4
749 dd 075682332h
750 %assign iValue iValue + 075682332h
751 %endif
752 %assign iValue (iValue & 0ffffh) | (iDstReg_Value & 0ffffffffffff0000h)
753
754 ; cmp iDstReg, iValue
755 %if (iValue <= 07fffffffh && iValue >= -080000000h)
756 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
757 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
758 dd iValue
759 %elif iDstReg != X86_GREG_xAX
760 mov rax, iValue
761 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
762 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
763 %else
764 mov rcx, iValue
765 cmp rax, rcx
766 %endif
767 %if iDstReg == 4
768 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
769 %endif
770 jz $+3
771 int3
772
773 ;
774 ; 16-bit operand and 32-bit address size.
775 ;
776 call .load_regs
777 %if iDstReg == 4
778 mov rsp, LEA_RSP
779 %endif
780
781 ; lea
782 %assign iValue iMemReg_Value
783 db X86_OP_PRF_SIZE_OP
784 db X86_OP_PRF_SIZE_ADDR
785 %if iDstReg >= 8 || iMemReg >= 8
786 db X86_OP_REX | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
787 %endif
788 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
789 %if iMod == X86_MOD_MEM1
790 db 99
791 %assign iValue iValue + 99
792 %elif iMod == 0 && (iMemReg & 7) == 5
793 dd _Bs3Text16_StartOfSegment - $ - 4 + 3347 wrt BS3FLAT
794 %assign iValue 3347
795 %elif iMod == X86_MOD_MEM4
796 dd -075623432h
797 %assign iValue iValue - 075623432h
798 %endif
799 %assign iValue (iValue & 0ffffh) | (iDstReg_Value & 0ffffffffffff0000h)
800
801 ; cmp iDstReg, iValue
802 %if (iValue <= 07fffffffh && iValue >= -080000000h)
803 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
804 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
805 dd iValue
806 %elif iDstReg != X86_GREG_xAX
807 mov rax, iValue
808 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
809 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
810 %else
811 mov rcx, iValue
812 cmp rax, rcx
813 %endif
814 %if iDstReg == 4
815 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
816 %endif
817 jz $+3
818 int3
819
820 %endif ; !SIB
821 %assign iMemReg iMemReg + 1
822 %endrep
823 %assign iDstReg (iDstReg + 1) & 15
824 %endrep
825 %assign iMod iMod + 1
826 %endrep
827
828 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
829 pop r15
830 pop r14
831 pop r13
832 pop r12
833 pop r11
834 pop r10
835 pop r9
836 pop r8
837 pop rdi
838 pop rsi
839 pop rbp
840 pop rbx
841 pop rdx
842 pop rcx
843 pop rax
844 ret
845
846.load_regs:
847 mov rax, LEA_RAX
848 mov rcx, LEA_RCX
849 mov rdx, LEA_RDX
850 mov rbx, LEA_RBX
851 mov rbp, LEA_RBP
852 mov rsi, LEA_RSI
853 mov rdi, LEA_RDI
854 mov r8, LEA_R8
855 mov r9, LEA_R9
856 mov r10, LEA_R10
857 mov r11, LEA_R11
858 mov r12, LEA_R12
859 mov r13, LEA_R13
860 mov r14, LEA_R14
861 mov r15, LEA_R15
862 ret
863BS3_PROC_END_CMN bs3CpuBasic3_lea_64
864
865%endif ; TMPL_BITS == 64
866
867
868%include "bs3kit-template-footer.mac" ; reset environment
869
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