VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-3-high-asm.asm@ 102182

Last change on this file since 102182 was 102182, checked in by vboxsync, 17 months ago

ValKit/bs3-cpu-basic-3: Move the 64-bit lea tests to the high DLL where we don't have such tight code size constraints. bugref:10371

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.8 KB
Line 
1; $Id: bs3-cpu-basic-3-high-asm.asm 102182 2023-11-21 09:46:33Z vboxsync $
2;; @file
3; BS3Kit - bs3-cpu-basic-3-high - Assembly code.
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.mac"
42
43
44;*********************************************************************************************************************************
45;* Defined Constants And Macros *
46;*********************************************************************************************************************************
47%define LEA_RAX 01111111111111110h
48%define LEA_RCX 02222222222222202h
49%define LEA_RDX 03333333333333033h
50%define LEA_RBX 04444444444440444h
51%define LEA_RSP 058595a5d51525356h
52%define LEA_RBP 05555555555555551h
53%define LEA_RSI 06666666666666616h
54%define LEA_RDI 07777777777777177h
55%define LEA_R8 08888888888881888h
56%define LEA_R9 09999999999999992h
57%define LEA_R10 0aaaaaaaaaaaaaa2ah
58%define LEA_R11 0bbbbbbbbbbbbb2bbh
59%define LEA_R12 0cccccccccccc2ccch
60%define LEA_R13 0ddddddddddddddd3h
61%define LEA_R14 0eeeeeeeeeeeeee3eh
62%define LEA_R15 0fffffffffffff3ffh
63
64
65;*********************************************************************************************************************************
66;* External Symbols *
67;*********************************************************************************************************************************
68extern _Bs3Text16_StartOfSegment
69
70
71;*********************************************************************************************************************************
72;* Global Variables *
73;*********************************************************************************************************************************
74BS3_BEGIN_DATA64
75
76;; Place to save esp/rsp when doing LEA variations involving esp/rsp.
77BS3_GLOBAL_DATA g_bs3CpuBasic3_lea_rsp, 8
78 dq 0
79
80BS3_GLOBAL_DATA g_bs3CpuBasic3_lea_trace, 4
81 dd 0
82
83;
84; Set up LM64 environment
85;
86%define TMPL_MODE BS3_MODE_LM64
87%include "bs3kit-template-header.mac"
88
89
90;;
91; Tests 64-bit addressing using the LEA instruction.
92;
93TMPL_BEGIN_TEXT
94export BS3_CMN_NM(bs3CpuBasic3_lea_64)
95BS3_PROC_BEGIN_CMN bs3CpuBasic3_lea_64, BS3_PBC_NEAR
96%if 0
97 times 512-0x1a db 1
98%assign x 1
99%rep 167
100%assign x x+1
101 times 512 db x
102%endrep
103%else
104 push rax
105 push rcx
106 push rdx
107 push rbx
108 push rbp
109 push rsi
110 push rdi
111 push r8
112 push r9
113 push r10
114 push r11
115 push r12
116 push r13
117 push r14
118 push r15
119.test_label:
120 mov [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))], rsp
121
122 ;
123 ; Loop thru all the modr/m memory encodings.
124 ;
125 %assign iMod 0
126 %assign iDstReg 0 ; We don't test all destination registers
127 %rep 3
128 %rep 16 ; Destination registers per encoding. Testing all takes too much space.
129 %assign iMemReg 0
130 %rep 16
131 %assign iDstReg_Value %sel(iDstReg+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, LEA_RSP, LEA_RBP, LEA_RSI, LEA_RDI, \
132 LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15)
133
134 %if (iMemReg & 7) == 4
135 ;
136 ; SIB.
137 ;
138 %assign iBase 0
139 %rep 16
140 %if (iBase & 7) == 5 && iMod == 0
141 %assign iBase_Value 0
142 %else
143 %assign iBase_Value %sel(iBase+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, LEA_RSP, LEA_RBP, LEA_RSI, LEA_RDI, \
144 LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15)
145 %endif
146
147 %assign iIndex 0
148 %assign cShift 0 ; we don't have enough room for checking all the shifts.
149 %rep 16
150 %assign iBase_Value %sel(iIndex+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, 0, LEA_RBP, LEA_RSI, LEA_RDI, \
151 LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15)
152
153 ;
154 ; We don't test all shift combinations, there just isn't enough space
155 ; in the image for that.
156 ;
157 %assign cShiftLoops 0 ; Disabled for now
158 %rep cShiftLoops
159%error asdf
160 ;
161 ; LEA+SIB w/ 64-bit operand size and 64-bit address size.
162 ;
163 call .load_regs
164 %if iBase == 4 || iDstReg == 4
165 mov rsp, LEA_RSP
166 %endif
167
168 ; lea
169 %assign iValue iBase_Value + (iIndex_Value << cShift)
170 db X86_OP_REX_W | ((iBase & 8) >> 3) | ((iIndex & 8) >> 2) | ((iDstReg) & 8 >> 1)
171 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7), X86_SIB_MAKE(iBase & 7, iIndex & 7, cShift)
172 %if iMod == X86_MOD_MEM1
173 db -128
174 %assign iValue iValue - 128
175 %elif iMod == X86_MOD_MEM4 || (iMod == 0 && iBase == 5)
176 dd -07fffffffh
177 %assign iValue iValue - 07fffffffh
178 %endif
179
180 ; cmp iDstReg, iValue
181 %if iValue <= 07fffffffh && iValue >= -080000000h
182 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
183 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
184 dd iValue & 0ffffffffh
185 %elif iDstReg != X86_GREG_xAX
186 mov rax, iValue
187 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
188 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
189 %else
190 mov rcx, iValue
191 cmp rax, rcx
192 %endif
193 %if iDstReg == 4
194 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
195 %endif
196 jz $+3
197 int3
198 %assign cShift (cShift + 1) & 3
199
200 %endrep
201 %assign iIndex iIndex + 1
202 %endrep
203 %assign iBase iBase + 1
204 %endrep
205
206 %else ; !SIB
207 ;
208 ; Plain lea reg, [reg] with disp according to iMod,
209 ; or lea reg, [disp32] if iMemReg == 5 && iMod == 0.
210 ;
211 %if (iMemReg & 7) == 5 && iMod == 0
212 %assign iMemReg_Value 0
213 %else
214 %assign iMemReg_Value %sel(iMemReg+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, LEA_RSP, LEA_RBP, LEA_RSI, LEA_RDI, \
215 LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15)
216 %endif
217
218 ;
219 ; 64-bit operand and address size first.
220 ;
221;mov eax, $
222mov dword [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_trace))], $ ;iMod | (iDstReg << 4) | (iMemReg << 8)
223
224 call .load_regs
225 %if iDstReg == 4
226 mov rsp, LEA_RSP
227 %endif
228
229 ; lea
230 %assign iValue iMemReg_Value
231 db X86_OP_REX_W | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
232 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
233 %if iMod == X86_MOD_MEM1
234 db 39
235 %assign iValue iValue + 39
236 %elif iMod == 0 && (iMemReg & 7) == 5
237 dd .load_regs - $ - 4
238 %elif iMod == X86_MOD_MEM4
239 dd 058739af8h
240 %assign iValue iValue + 058739af8h
241 %endif
242
243 ; cmp iDstReg, iValue
244 %if (iValue <= 07fffffffh && iValue >= -080000000h) || (iMod == 0 && (iMemReg & 7) == 5)
245 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
246 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
247 %if iMod == 0 && (iMemReg & 7) == 5
248 dd .load_regs wrt BS3FLAT
249 %else
250 dd iValue & 0ffffffffh
251 %endif
252 %else
253 %if iDstReg != iMemReg && iValue == iMemReg_Value ; This isn't entirely safe, but it saves a bit of space.
254 db X86_OP_REX_W | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
255 db 39h, X86_MODRM_MAKE(X86_MOD_REG, iDstReg & 7, iMemReg & 7)
256 %elif iDstReg != X86_GREG_xAX
257 mov rax, iValue
258 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
259 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
260 %else
261 mov rcx, iValue
262 cmp rax, rcx
263 %endif
264 %endif
265 %if iDstReg == 4
266 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
267 %endif
268 jz $+3
269 int3
270
271 ;
272 ; 64-bit operand and 32-bit address size.
273 ;
274 call .load_regs
275 %if iDstReg == 4
276 mov rsp, LEA_RSP
277 %endif
278
279 ; lea
280 %assign iValue iMemReg_Value
281 db X86_OP_PRF_SIZE_ADDR
282 db X86_OP_REX_W | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
283 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
284 %if iMod == X86_MOD_MEM1
285 db -92
286 %assign iValue iValue - 92
287 %elif iMod == 0 && (iMemReg & 7) == 5
288 dd .test_label - $ - 4
289 %elif iMod == X86_MOD_MEM4
290 dd -038f8acf3h
291 %assign iValue iValue - 038f8acf3h
292 %endif
293 %assign iValue iValue & 0ffffffffh
294
295 ; cmp iDstReg, iValue
296 %if (iValue <= 07fffffffh && iValue >= 0) || (iMod == 0 && (iMemReg & 7) == 5)
297 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
298 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
299 %if iMod == 0 && (iMemReg & 7) == 5
300 dd .test_label wrt BS3FLAT
301 %else
302 dd iValue
303 %endif
304 %else
305 %if iDstReg != X86_GREG_xAX
306 mov eax, iValue
307 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
308 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
309 %else
310 mov ecx, iValue
311 cmp rax, rcx
312 %endif
313 %endif
314 %if iDstReg == 4
315 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
316 %endif
317 jz $+3
318 int3
319
320 ;
321 ; 32-bit operand and 64-bit address size.
322 ;
323 call .load_regs
324 %if iDstReg == 4
325 mov rsp, LEA_RSP
326 %endif
327
328 ; lea
329 %assign iValue iMemReg_Value
330 %if iDstReg >= 8 || iMemReg >= 8
331 db X86_OP_REX | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
332 %endif
333 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
334 %if iMod == X86_MOD_MEM1
335 db 16
336 %assign iValue iValue + 16
337 %elif iMod == 0 && (iMemReg & 7) == 5
338 dd .load_regs - $ - 4
339 %elif iMod == X86_MOD_MEM4
340 dd 0596829deh
341 %assign iValue iValue + 0596829deh
342 %endif
343 %assign iValue iValue & 0ffffffffh
344
345 ; cmp iDstReg, iValue
346 %if (iValue <= 07fffffffh && iValue >= 0) || (iMod == 0 && (iMemReg & 7) == 5)
347 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
348 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
349 %if iMod == 0 && (iMemReg & 7) == 5
350 dd .load_regs wrt BS3FLAT
351 %else
352 dd iValue
353 %endif
354 %else
355 %if iDstReg != X86_GREG_xAX
356 mov eax, iValue
357 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
358 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
359 %else
360 mov ecx, iValue
361 cmp rax, rcx
362 %endif
363 %endif
364 %if iDstReg == 4
365 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
366 %endif
367 jz $+3
368 int3
369
370 ;
371 ; 16-bit operand and 64-bit address size.
372 ;
373 call .load_regs
374 %if iDstReg == 4
375 mov rsp, LEA_RSP
376 %endif
377
378 ; lea
379 %assign iValue iMemReg_Value
380 db X86_OP_PRF_SIZE_OP
381 %if iDstReg >= 8 || iMemReg >= 8
382 db X86_OP_REX | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
383 %endif
384 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
385 %if iMod == X86_MOD_MEM1
386 db -16
387 %assign iValue iValue - 16
388 %elif iMod == 0 && (iMemReg & 7) == 5
389 dd _Bs3Text16_StartOfSegment - $ - 4 + 7 wrt BS3FLAT
390 %assign iValue 7
391 %elif iMod == X86_MOD_MEM4
392 dd 075682332h
393 %assign iValue iValue + 075682332h
394 %endif
395 %assign iValue (iValue & 0ffffh) | (iDstReg_Value & 0ffffffffffff0000h)
396
397 ; cmp iDstReg, iValue
398 %if (iValue <= 07fffffffh && iValue >= -080000000h)
399 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
400 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
401 dd iValue
402 %elif iDstReg != X86_GREG_xAX
403 mov rax, iValue
404 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
405 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
406 %else
407 mov rcx, iValue
408 cmp rax, rcx
409 %endif
410 %if iDstReg == 4
411 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
412 %endif
413 jz $+3
414 int3
415
416 ;
417 ; 16-bit operand and 32-bit address size.
418 ;
419 call .load_regs
420 %if iDstReg == 4
421 mov rsp, LEA_RSP
422 %endif
423
424 ; lea
425 %assign iValue iMemReg_Value
426 db X86_OP_PRF_SIZE_OP
427 db X86_OP_PRF_SIZE_ADDR
428 %if iDstReg >= 8 || iMemReg >= 8
429 db X86_OP_REX | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
430 %endif
431 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
432 %if iMod == X86_MOD_MEM1
433 db 99
434 %assign iValue iValue + 99
435 %elif iMod == 0 && (iMemReg & 7) == 5
436 dd _Bs3Text16_StartOfSegment - $ - 4 + 3347 wrt BS3FLAT
437 %assign iValue 3347
438 %elif iMod == X86_MOD_MEM4
439 dd -075623432h
440 %assign iValue iValue - 075623432h
441 %endif
442 %assign iValue (iValue & 0ffffh) | (iDstReg_Value & 0ffffffffffff0000h)
443
444 ; cmp iDstReg, iValue
445 %if (iValue <= 07fffffffh && iValue >= -080000000h)
446 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
447 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
448 dd iValue
449 %elif iDstReg != X86_GREG_xAX
450 mov rax, iValue
451 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
452 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
453 %else
454 mov rcx, iValue
455 cmp rax, rcx
456 %endif
457 %if iDstReg == 4
458 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
459 %endif
460 jz $+3
461 int3
462
463 %endif ; !SIB
464 %assign iMemReg iMemReg + 1
465 %endrep
466 %assign iDstReg (iDstReg + 1) & 15
467 %endrep
468 %assign iMod iMod + 1
469 %endrep
470
471 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
472 pop r15
473 pop r14
474 pop r13
475 pop r12
476 pop r11
477 pop r10
478 pop r9
479 pop r8
480 pop rdi
481 pop rsi
482 pop rbp
483 pop rbx
484 pop rdx
485 pop rcx
486 pop rax
487 ret
488
489.load_regs:
490 mov rax, LEA_RAX
491 mov rcx, LEA_RCX
492 mov rdx, LEA_RDX
493 mov rbx, LEA_RBX
494 mov rbp, LEA_RBP
495 mov rsi, LEA_RSI
496 mov rdi, LEA_RDI
497 mov r8, LEA_R8
498 mov r9, LEA_R9
499 mov r10, LEA_R10
500 mov r11, LEA_R11
501 mov r12, LEA_R12
502 mov r13, LEA_R13
503 mov r14, LEA_R14
504 mov r15, LEA_R15
505 ret
506%endif
507BS3_PROC_END_CMN bs3CpuBasic3_lea_64
508
509
510align 512
511%assign x 1
512%rep 16
513%assign x x+1
514 times 512 db x
515%endrep
516
Note: See TracBrowser for help on using the repository browser.

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