VirtualBox

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

Last change on this file since 103068 was 102272, checked in by vboxsync, 13 months ago

ValKit/bs3-cpu-basic-3: Full 64-bit lea testcase. Use python (3+) to generate the bulk of it, as the nasm preprocessor is too slow and uses too much memory (19+ GiBs). bugref:10371

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.0 KB
Line 
1; $Id: bs3-cpu-basic-3-high-asm.asm 102272 2023-11-23 00:43:20Z 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
80%ifdef WITH_TRACING
81BS3_GLOBAL_DATA g_bs3CpuBasic3_lea_trace, 4
82 dd 0
83%endif
84
85;
86; Set up LM64 environment
87;
88%define TMPL_MODE BS3_MODE_LM64
89%include "bs3kit-template-header.mac"
90
91
92;;
93; Tests 64-bit addressing using the LEA instruction.
94;
95TMPL_BEGIN_TEXT
96export BS3_CMN_NM(bs3CpuBasic3_lea_64)
97BS3_PROC_BEGIN_CMN bs3CpuBasic3_lea_64, BS3_PBC_NEAR
98 push rax
99 push rcx
100 push rdx
101 push rbx
102 push rbp
103 push rsi
104 push rdi
105 push r8
106 push r9
107 push r10
108 push r11
109 push r12
110 push r13
111 push r14
112 push r15
113.test_label:
114 mov [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))], rsp
115
116 ;
117 ; We generate all the permutations using a python script, as nasm ends
118 ; up consuming >19 GiB of memory running the preprocessor code below.
119 ; It also took forever (3+ min).
120 ;
121%if 1
122 %include "bs3-cpu-basic-3-high-lea64.inc"
123%else
124 ;
125 ; Loop thru all the modr/m memory encodings.
126 ;
127%assign iMod 0
128%rep 3
129 %assign iDstReg 0
130 %rep 16
131 %assign iMemReg 0
132 %rep 16
133 %assign iDstReg_Value %sel(iDstReg+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, LEA_RSP, LEA_RBP, LEA_RSI, LEA_RDI, \
134 LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15)
135
136 %if (iMemReg & 7) == 4
137 ;
138 ; SIB.
139 ;
140 %assign iBase 0
141 %rep 16
142 %if (iBase & 7) == 5 && iMod == 0
143 %assign iBase_Value 0
144 %else
145 %assign iBase_Value %sel(iBase+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, LEA_RSP, LEA_RBP, LEA_RSI, LEA_RDI, \
146 LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15)
147 %endif
148
149 %assign iIndex 0
150 %assign cShift 0 ; we don't have enough room for checking all the shifts.
151 %rep 16
152 %assign iIndex_Value %sel(iIndex+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, 0, LEA_RBP, LEA_RSI, LEA_RDI, \
153 LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15)
154
155 ;
156 ; We don't test all shift combinations, there just isn't enough space
157 ; in the image for that.
158 ;
159 %assign cShiftLoops 4
160 %rep cShiftLoops
161
162 ;
163 ; LEA+SIB w/ 64-bit operand size and 64-bit address size.
164 ;
165 %ifdef WITH_TRACING
166 mov dword [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_trace))], $
167 %endif
168 call .load_regs
169 %if iBase == 4 || iDstReg == 4
170 mov rsp, LEA_RSP
171 %endif
172
173 ; lea
174 %assign iValue iBase_Value + (iIndex_Value << cShift)
175 db X86_OP_REX_W | ((iBase & 8) >> 3) | ((iIndex & 8) >> 2) | ((iDstReg & 8) >> 1)
176 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7), X86_SIB_MAKE(iBase & 7, iIndex & 7, cShift)
177 %if iMod == X86_MOD_MEM1
178 db -128
179 %assign iValue iValue - 128
180 %elif iMod == X86_MOD_MEM4 || (iMod == 0 && (iBase & 7) == 5)
181 dd -07ffef3ffh
182 %assign iValue iValue - 07ffef3ffh
183 %endif
184
185 ; cmp iDstReg, iValue
186 %if iValue <= 07fffffffh && iValue >= -080000000h
187 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
188 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
189 dd iValue & 0ffffffffh
190 %elif iDstReg != X86_GREG_xAX
191 mov rax, iValue
192 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
193 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
194 %else
195 mov rcx, iValue
196 cmp rax, rcx
197 %endif
198 %if iBase == 4 || iDstReg == 4
199 mov rdx, rsp
200 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
201 %endif
202 jz $+3
203 int3
204
205 ;
206 ; LEA+SIB w/ 64-bit operand size and 32-bit address size.
207 ;
208 %ifdef WITH_TRACING
209 mov dword [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_trace))], $
210 %endif
211 call .load_regs
212 %if iBase == 4 || iDstReg == 4
213 mov rsp, LEA_RSP
214 %endif
215
216 ; lea
217 %assign iValue iBase_Value + (iIndex_Value << cShift)
218 db X86_OP_PRF_SIZE_ADDR
219 db X86_OP_REX_W | ((iBase & 8) >> 3) | ((iIndex & 8) >> 2) | ((iDstReg & 8) >> 1)
220 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7), X86_SIB_MAKE(iBase & 7, iIndex & 7, cShift)
221 %if iMod == X86_MOD_MEM1
222 db +127
223 %assign iValue iValue + 127
224 %elif iMod == X86_MOD_MEM4 || (iMod == 0 && (iBase & 7) == 5)
225 dd +0356786aeh
226 %assign iValue iValue + 0356786aeh
227 %endif
228 %assign iValue (iValue & 0ffffffffh)
229
230 ; cmp iDstReg, iValue
231 %if iValue <= 07fffffffh && iValue >= -080000000h
232 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
233 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
234 dd iValue & 0ffffffffh
235 %elif iDstReg != X86_GREG_xAX
236 mov rax, iValue
237 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
238 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
239 %else
240 mov rcx, iValue
241 cmp rax, rcx
242 %endif
243 %if iBase == 4 || iDstReg == 4
244 mov rdx, rsp
245 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
246 %endif
247 jz $+3
248 int3
249
250 ;
251 ; LEA+SIB w/ 32-bit operand size and 64-bit address size.
252 ;
253 %ifdef WITH_TRACING
254 mov dword [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_trace))], $
255 %endif
256 call .load_regs
257 %if iBase == 4 || iDstReg == 4
258 mov rsp, LEA_RSP
259 %endif
260
261 ; lea
262 %assign iValue iBase_Value + (iIndex_Value << cShift)
263 %if (iBase | iIndex | iDstReg) & 8
264 db X86_OP_REX | ((iBase & 8) >> 3) | ((iIndex & 8) >> 2) | ((iDstReg & 8) >> 1)
265 %endif
266 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7), X86_SIB_MAKE(iBase & 7, iIndex & 7, cShift)
267 %if iMod == X86_MOD_MEM1
268 db -18
269 %assign iValue iValue - 18
270 %elif iMod == X86_MOD_MEM4 || (iMod == 0 && (iBase & 7) == 5)
271 dd -07fef3ffh
272 %assign iValue iValue - 07fef3ffh
273 %endif
274 %assign iValue (iValue & 0ffffffffh)
275
276 ; cmp iDstReg, iValue
277 %if iValue <= 07fffffffh && iValue >= -080000000h
278 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
279 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
280 dd iValue & 0ffffffffh
281 %elif iDstReg != X86_GREG_xAX
282 mov rax, iValue
283 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
284 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
285 %else
286 mov rcx, iValue
287 cmp rax, rcx
288 %endif
289 %if iBase == 4 || iDstReg == 4
290 mov rdx, rsp
291 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
292 %endif
293 jz $+3
294 int3
295
296 ;
297 ; LEA+SIB w/ 32-bit operand size and 32-bit address size.
298 ;
299 %ifdef WITH_TRACING
300 mov dword [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_trace))], $
301 %endif
302 call .load_regs
303 %if iBase == 4 || iDstReg == 4
304 mov rsp, LEA_RSP
305 %endif
306
307 ; lea
308 %assign iValue iBase_Value + (iIndex_Value << cShift)
309 db X86_OP_PRF_SIZE_ADDR
310 %if (iBase | iIndex | iDstReg) & 8
311 db X86_OP_REX | ((iBase & 8) >> 3) | ((iIndex & 8) >> 2) | ((iDstReg & 8) >> 1)
312 %endif
313 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7), X86_SIB_MAKE(iBase & 7, iIndex & 7, cShift)
314 %if iMod == X86_MOD_MEM1
315 db +17
316 %assign iValue iValue + 17
317 %elif iMod == X86_MOD_MEM4 || (iMod == 0 && (iBase & 7) == 5)
318 dd +0356786h
319 %assign iValue iValue + 0356786h
320 %endif
321 %assign iValue (iValue & 0ffffffffh)
322
323 ; cmp iDstReg, iValue
324 %if iValue <= 07fffffffh && iValue >= -080000000h
325 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
326 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
327 dd iValue & 0ffffffffh
328 %elif iDstReg != X86_GREG_xAX
329 mov rax, iValue
330 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
331 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
332 %else
333 mov rcx, iValue
334 cmp rax, rcx
335 %endif
336 %if iBase == 4 || iDstReg == 4
337 mov rdx, rsp
338 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
339 %endif
340 jz $+3
341 int3
342
343 ;
344 ; LEA+SIB w/ 16-bit operand size and 64-bit address size.
345 ;
346 %ifdef WITH_TRACING
347 mov dword [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_trace))], $
348 %endif
349 call .load_regs
350 %if iBase == 4 || iDstReg == 4
351 mov rsp, LEA_RSP
352 %endif
353
354 ; lea
355 %assign iValue iBase_Value + (iIndex_Value << cShift)
356 db X86_OP_PRF_SIZE_OP
357 %if (iBase | iIndex | iDstReg) & 8
358 db X86_OP_REX | ((iBase & 8) >> 3) | ((iIndex & 8) >> 2) | ((iDstReg & 8) >> 1)
359 %endif
360 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7), X86_SIB_MAKE(iBase & 7, iIndex & 7, cShift)
361 %if iMod == X86_MOD_MEM1
362 db -18
363 %assign iValue iValue - 18
364 %elif iMod == X86_MOD_MEM4 || (iMod == 0 && (iBase & 7) == 5)
365 dd -07fef3ffh
366 %assign iValue iValue - 07fef3ffh
367 %endif
368 %assign iValue (iValue & 0ffffh) | (iDstReg_Value & 0ffffffffffff0000h)
369
370 ; cmp iDstReg, iValue
371 %if iValue <= 07fffffffh && iValue >= -080000000h
372 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
373 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
374 dd iValue & 0ffffffffh
375 %elif iDstReg != X86_GREG_xAX
376 mov rax, iValue
377 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
378 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
379 %else
380 mov rcx, iValue
381 cmp rax, rcx
382 %endif
383 %if iBase == 4 || iDstReg == 4
384 mov rdx, rsp
385 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
386 %endif
387 jz $+3
388 int3
389
390 ;
391 ; LEA+SIB w/ 16-bit operand size and 32-bit address size.
392 ;
393 %ifdef WITH_TRACING
394 mov dword [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_trace))], $
395 %endif
396 call .load_regs
397 %if iBase == 4 || iDstReg == 4
398 mov rsp, LEA_RSP
399 %endif
400
401 ; lea
402 %assign iValue iBase_Value + (iIndex_Value << cShift)
403 %if cShift & 2
404 db X86_OP_PRF_SIZE_OP, X86_OP_PRF_SIZE_ADDR
405 %else
406 db X86_OP_PRF_SIZE_ADDR, X86_OP_PRF_SIZE_OP
407 %endif
408 %if (iBase | iIndex | iDstReg) & 8
409 db X86_OP_REX | ((iBase & 8) >> 3) | ((iIndex & 8) >> 2) | ((iDstReg & 8) >> 1)
410 %endif
411 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7), X86_SIB_MAKE(iBase & 7, iIndex & 7, cShift)
412 %if iMod == X86_MOD_MEM1
413 db +17
414 %assign iValue iValue + 17
415 %elif iMod == X86_MOD_MEM4 || (iMod == 0 && (iBase & 7) == 5)
416 dd +0356786h
417 %assign iValue iValue + 0356786h
418 %endif
419 %assign iValue (iValue & 0ffffh) | (iDstReg_Value & 0ffffffffffff0000h)
420
421 ; cmp iDstReg, iValue
422 %if iValue <= 07fffffffh && iValue >= -080000000h
423 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
424 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
425 dd iValue & 0ffffffffh
426 %elif iDstReg != X86_GREG_xAX
427 mov rax, iValue
428 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
429 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
430 %else
431 mov rcx, iValue
432 cmp rax, rcx
433 %endif
434 %if iBase == 4 || iDstReg == 4
435 mov rdx, rsp
436 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
437 %endif
438 jz $+3
439 int3
440
441 %assign cShift (cShift + 1) & 3
442 %endrep
443 %assign iIndex iIndex + 1
444 %endrep
445 %assign iBase iBase + 1
446 %endrep
447
448 %else ; !SIB
449 ;
450 ; Plain lea reg, [reg] with disp according to iMod,
451 ; or lea reg, [disp32] if iMemReg == 5 && iMod == 0.
452 ;
453 %if (iMemReg & 7) == 5 && iMod == 0
454 %assign iMemReg_Value 0
455 %else
456 %assign iMemReg_Value %sel(iMemReg+1, LEA_RAX, LEA_RCX, LEA_RDX, LEA_RBX, LEA_RSP, LEA_RBP, LEA_RSI, LEA_RDI, \
457 LEA_R8, LEA_R9, LEA_R10, LEA_R11, LEA_R12, LEA_R13, LEA_R14, LEA_R15)
458 %endif
459
460 ;
461 ; 64-bit operand and address size first.
462 ;
463 %ifdef WITH_TRACING
464 mov dword [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_trace))], $
465 %endif
466 call .load_regs
467 %if iDstReg == 4
468 mov rsp, LEA_RSP
469 %endif
470
471 ; lea
472 %assign iValue iMemReg_Value
473 db X86_OP_REX_W | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
474 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
475 %if iMod == X86_MOD_MEM1
476 db 39
477 %assign iValue iValue + 39
478 %elif iMod == 0 && (iMemReg & 7) == 5
479 dd .load_regs - $ - 4
480 %elif iMod == X86_MOD_MEM4
481 dd 058739af8h
482 %assign iValue iValue + 058739af8h
483 %endif
484
485 ; cmp iDstReg, iValue
486 %if (iValue <= 07fffffffh && iValue >= -080000000h) || (iMod == 0 && (iMemReg & 7) == 5)
487 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
488 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
489 %if iMod == 0 && (iMemReg & 7) == 5
490 dd .load_regs wrt BS3FLAT
491 %else
492 dd iValue & 0ffffffffh
493 %endif
494 %else
495 %if iDstReg != iMemReg && iValue == iMemReg_Value ; This isn't entirely safe, but it saves a bit of space.
496 db X86_OP_REX_W | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
497 db 39h, X86_MODRM_MAKE(X86_MOD_REG, iDstReg & 7, iMemReg & 7)
498 %elif iDstReg != X86_GREG_xAX
499 mov rax, iValue
500 db (X86_OP_REX_W | ((iDstReg & 8) >> 3))
501 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
502 %else
503 mov rcx, iValue
504 cmp rax, rcx
505 %endif
506 %endif
507 %if iDstReg == 4
508 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
509 %endif
510 jz $+3
511 int3
512
513 ;
514 ; 64-bit operand and 32-bit address size.
515 ;
516 call .load_regs
517 %if iDstReg == 4
518 mov rsp, LEA_RSP
519 %endif
520
521 ; lea
522 %assign iValue iMemReg_Value
523 db X86_OP_PRF_SIZE_ADDR
524 db X86_OP_REX_W | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
525 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
526 %if iMod == X86_MOD_MEM1
527 db -92
528 %assign iValue iValue - 92
529 %elif iMod == 0 && (iMemReg & 7) == 5
530 dd .test_label - $ - 4
531 %elif iMod == X86_MOD_MEM4
532 dd -038f8acf3h
533 %assign iValue iValue - 038f8acf3h
534 %endif
535 %assign iValue iValue & 0ffffffffh
536
537 ; cmp iDstReg, iValue
538 %if (iValue <= 07fffffffh && iValue >= 0) || (iMod == 0 && (iMemReg & 7) == 5)
539 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
540 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
541 %if iMod == 0 && (iMemReg & 7) == 5
542 dd .test_label wrt BS3FLAT
543 %else
544 dd iValue
545 %endif
546 %else
547 %if iDstReg != X86_GREG_xAX
548 mov eax, iValue
549 ;cmp eax, %sel(iDstReg+1, rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15)
550 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
551 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
552 %else
553 mov ecx, iValue
554 cmp rax, rcx
555 %endif
556 %endif
557 %if iDstReg == 4
558 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
559 %endif
560 jz $+3
561 int3
562
563 ;
564 ; 32-bit operand and 64-bit address size.
565 ;
566 call .load_regs
567 %if iDstReg == 4
568 mov rsp, LEA_RSP
569 %endif
570
571 ; lea
572 %assign iValue iMemReg_Value
573 %if iDstReg >= 8 || iMemReg >= 8
574 db X86_OP_REX | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
575 %endif
576 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
577 %if iMod == X86_MOD_MEM1
578 db 16
579 %assign iValue iValue + 16
580 %elif iMod == 0 && (iMemReg & 7) == 5
581 dd .load_regs - $ - 4
582 %elif iMod == X86_MOD_MEM4
583 dd 0596829deh
584 %assign iValue iValue + 0596829deh
585 %endif
586 %assign iValue iValue & 0ffffffffh
587
588 ; cmp iDstReg, iValue
589 %if (iValue <= 07fffffffh && iValue >= 0) || (iMod == 0 && (iMemReg & 7) == 5)
590 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
591 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
592 %if iMod == 0 && (iMemReg & 7) == 5
593 dd .load_regs wrt BS3FLAT
594 %else
595 dd iValue
596 %endif
597 %else
598 %if iDstReg != X86_GREG_xAX
599 mov eax, iValue
600 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
601 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
602 %else
603 mov ecx, iValue
604 cmp rax, rcx
605 %endif
606 %endif
607 %if iDstReg == 4
608 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
609 %endif
610 jz $+3
611 int3
612
613 ;
614 ; 16-bit operand and 64-bit address size.
615 ;
616 call .load_regs
617 %if iDstReg == 4
618 mov rsp, LEA_RSP
619 %endif
620
621 ; lea
622 %assign iValue iMemReg_Value
623 db X86_OP_PRF_SIZE_OP
624 %if iDstReg >= 8 || iMemReg >= 8
625 db X86_OP_REX | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
626 %endif
627 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
628 %if iMod == X86_MOD_MEM1
629 db -16
630 %assign iValue iValue - 16
631 %elif iMod == 0 && (iMemReg & 7) == 5
632 dd _Bs3Text16_StartOfSegment - $ - 4 + 7 wrt BS3FLAT
633 %assign iValue 7
634 %elif iMod == X86_MOD_MEM4
635 dd 075682332h
636 %assign iValue iValue + 075682332h
637 %endif
638 %assign iValue (iValue & 0ffffh) | (iDstReg_Value & 0ffffffffffff0000h)
639
640 ; cmp iDstReg, iValue
641 %if (iValue <= 07fffffffh && iValue >= -080000000h)
642 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
643 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
644 dd iValue
645 %elif iDstReg != X86_GREG_xAX
646 mov rax, iValue
647 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
648 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
649 %else
650 mov rcx, iValue
651 cmp rax, rcx
652 %endif
653 %if iDstReg == 4
654 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
655 %endif
656 jz $+3
657 int3
658
659 ;
660 ; 16-bit operand and 32-bit address size.
661 ;
662 call .load_regs
663 %if iDstReg == 4
664 mov rsp, LEA_RSP
665 %endif
666
667 ; lea
668 %assign iValue iMemReg_Value
669 db X86_OP_PRF_SIZE_OP
670 db X86_OP_PRF_SIZE_ADDR
671 %if iDstReg >= 8 || iMemReg >= 8
672 db X86_OP_REX | ((iDstReg & 8) >> 1) | ((iMemReg & 8) >> 3)
673 %endif
674 db 8dh, X86_MODRM_MAKE(iMod, iDstReg & 7, iMemReg & 7)
675 %if iMod == X86_MOD_MEM1
676 db 99
677 %assign iValue iValue + 99
678 %elif iMod == 0 && (iMemReg & 7) == 5
679 dd _Bs3Text16_StartOfSegment - $ - 4 + 3347 wrt BS3FLAT
680 %assign iValue 3347
681 %elif iMod == X86_MOD_MEM4
682 dd -075623432h
683 %assign iValue iValue - 075623432h
684 %endif
685 %assign iValue (iValue & 0ffffh) | (iDstReg_Value & 0ffffffffffff0000h)
686
687 ; cmp iDstReg, iValue
688 %if (iValue <= 07fffffffh && iValue >= -080000000h)
689 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
690 db 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg & 7)
691 dd iValue
692 %elif iDstReg != X86_GREG_xAX
693 mov rax, iValue
694 db X86_OP_REX_W | ((iDstReg & 8) >> 3)
695 db 39h, X86_MODRM_MAKE(X86_MOD_REG, X86_GREG_xAX, iDstReg & 7)
696 %else
697 mov rcx, iValue
698 cmp rax, rcx
699 %endif
700 %if iDstReg == 4
701 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
702 %endif
703 jz $+3
704 int3
705
706 %endif ; !SIB
707 %assign iMemReg iMemReg + 1
708 %endrep
709 %assign iDstReg iDstReg + 1
710 %endrep
711 %assign iMod iMod + 1
712%endrep
713%endif ; !python
714
715 mov rsp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
716 pop r15
717 pop r14
718 pop r13
719 pop r12
720 pop r11
721 pop r10
722 pop r9
723 pop r8
724 pop rdi
725 pop rsi
726 pop rbp
727 pop rbx
728 pop rdx
729 pop rcx
730 pop rax
731 ret
732
733.load_regs:
734 mov rax, LEA_RAX
735 mov rcx, LEA_RCX
736 mov rdx, LEA_RDX
737 mov rbx, LEA_RBX
738 mov rbp, LEA_RBP
739 mov rsi, LEA_RSI
740 mov rdi, LEA_RDI
741 mov r8, LEA_R8
742 mov r9, LEA_R9
743 mov r10, LEA_R10
744 mov r11, LEA_R11
745 mov r12, LEA_R12
746 mov r13, LEA_R13
747 mov r14, LEA_R14
748 mov r15, LEA_R15
749 ret
750BS3_PROC_END_CMN bs3CpuBasic3_lea_64
751
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