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 |
|
---|
44 | TMPL_BEGIN_TEXT
|
---|
45 |
|
---|
46 |
|
---|
47 | ;*********************************************************************************************************************************
|
---|
48 | ;* External Symbols *
|
---|
49 | ;*********************************************************************************************************************************
|
---|
50 | extern _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
|
---|
89 | BS3_BEGIN_X0TEXT16
|
---|
90 | %else
|
---|
91 | TMPL_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 | ;
|
---|
142 | BS3_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
|
---|
166 | BS3_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
|
---|
173 | BS3_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 | ;
|
---|
192 | BS3_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
|
---|
454 | BS3_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 | ;
|
---|
463 | BS3_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
|
---|
863 | BS3_PROC_END_CMN bs3CpuBasic3_lea_64
|
---|
864 |
|
---|
865 | %endif ; TMPL_BITS == 64
|
---|
866 |
|
---|
867 |
|
---|
868 | %include "bs3kit-template-footer.mac" ; reset environment
|
---|
869 |
|
---|