1 | ; $Id: bs3-cpu-basic-3-cmn-template.mac 106061 2024-09-16 14:03:52Z vboxsync $
|
---|
2 | ;; @file
|
---|
3 | ; BS3Kit - bs3-cpu-basic-3 assembly template, common code (CMN).
|
---|
4 | ;
|
---|
5 |
|
---|
6 | ;
|
---|
7 | ; Copyright (C) 2007-2024 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 |
|
---|
67 |
|
---|
68 | ;
|
---|
69 | ; Switching segment for the 16-bit stuff, this may need some space.
|
---|
70 | ;
|
---|
71 | %if TMPL_BITS == 16
|
---|
72 | BS3_BEGIN_X0TEXT16
|
---|
73 | %else
|
---|
74 | TMPL_BEGIN_TEXT
|
---|
75 | %endif
|
---|
76 |
|
---|
77 |
|
---|
78 | %if TMPL_BITS != 64
|
---|
79 | ;
|
---|
80 | ; Macros for 16-bit lea tests.
|
---|
81 | ;
|
---|
82 | %ifndef BS3CPUBASIC3_LEA_16_MACROS
|
---|
83 | %define BS3CPUBASIC3_LEA_16_MACROS
|
---|
84 | %macro test_lea_16_one 3
|
---|
85 | call .load_regs
|
---|
86 | lea strict %1, strict %2
|
---|
87 | cmp %1, %3 & 0ffffh
|
---|
88 | jz %%okay
|
---|
89 | int3
|
---|
90 | %%okay:
|
---|
91 | %endm
|
---|
92 | %macro test_lea_16_inner 2
|
---|
93 | test_lea_16_one ax, %1, %2
|
---|
94 | test_lea_16_one cx, %1, %2
|
---|
95 | test_lea_16_one dx, %1, %2
|
---|
96 | test_lea_16_one bx, %1, %2
|
---|
97 | test_lea_16_one bp, %1, %2
|
---|
98 | test_lea_16_one si, %1, %2
|
---|
99 | test_lea_16_one di, %1, %2
|
---|
100 |
|
---|
101 | test_lea_16_one eax, %1, %2
|
---|
102 | test_lea_16_one ecx, %1, %2
|
---|
103 | test_lea_16_one edx, %1, %2
|
---|
104 | test_lea_16_one ebx, %1, %2
|
---|
105 | test_lea_16_one ebp, %1, %2
|
---|
106 | test_lea_16_one esi, %1, %2
|
---|
107 | test_lea_16_one edi, %1, %2
|
---|
108 | %endm
|
---|
109 | %macro test_lea_16_outer 3
|
---|
110 | %if %1 == 0
|
---|
111 | test_lea_16_inner [%2], %3
|
---|
112 | %else
|
---|
113 | test_lea_16_inner [word %3], %3 ; mod0/6 = disp16
|
---|
114 | %endif
|
---|
115 | test_lea_16_inner [%2 + 07fh], %3 + 7fh
|
---|
116 | test_lea_16_inner [%2 - 19], %3 - 19
|
---|
117 | test_lea_16_inner [%2 + 5708h], %3 + 5708h
|
---|
118 | test_lea_16_inner [%2 - 7293h], %3 - 7293h
|
---|
119 | %endm
|
---|
120 | %endif
|
---|
121 |
|
---|
122 | ;;
|
---|
123 | ; Tests 16-bit addressing using the LEA instruction.
|
---|
124 | ;
|
---|
125 | BS3_PROC_BEGIN_CMN bs3CpuBasic3_lea_16, BS3_PBC_FAR
|
---|
126 | pushad
|
---|
127 |
|
---|
128 | test_lea_16_outer 0, bx + si, 00444h+06616h
|
---|
129 | test_lea_16_outer 0, bx + di, 00444h+07177h
|
---|
130 | test_lea_16_outer 0, bp + si, 05551h+06616h
|
---|
131 | test_lea_16_outer 0, bp + di, 05551h+07177h
|
---|
132 | test_lea_16_outer 0, si, 06616h
|
---|
133 | test_lea_16_outer 0, di, 07177h
|
---|
134 | test_lea_16_outer 1, bp, 05551h
|
---|
135 | test_lea_16_outer 0, bx, 00444h
|
---|
136 |
|
---|
137 | popad
|
---|
138 | BS3_HYBRID_RET
|
---|
139 |
|
---|
140 | .load_regs:
|
---|
141 | mov eax, LEA_EAX
|
---|
142 | mov ecx, LEA_ECX
|
---|
143 | mov edx, LEA_EDX
|
---|
144 | mov ebx, LEA_EBX
|
---|
145 | mov ebp, LEA_EBP
|
---|
146 | mov esi, LEA_ESI
|
---|
147 | mov edi, LEA_EDI
|
---|
148 | ret
|
---|
149 | BS3_PROC_END_CMN bs3CpuBasic3_lea_16
|
---|
150 |
|
---|
151 |
|
---|
152 | ;
|
---|
153 | ; Switching segment for the 16-bit stuff, SIB needs too much space.
|
---|
154 | ;
|
---|
155 | %if TMPL_BITS == 16
|
---|
156 | BS3_BEGIN_X1TEXT16
|
---|
157 | %endif
|
---|
158 |
|
---|
159 | ;
|
---|
160 | ; Macros for 32-bit lea tests.
|
---|
161 | ;
|
---|
162 | %if TMPL_BITS == 16
|
---|
163 | %define MY_O16 67h,
|
---|
164 | %define MY_O32 67h, 66h,
|
---|
165 | %define MY_CMP_O32 66h,
|
---|
166 | %else
|
---|
167 | %define MY_O16 66h,
|
---|
168 | %define MY_O32
|
---|
169 | %define MY_CMP_O32
|
---|
170 | %endif
|
---|
171 |
|
---|
172 | ;;
|
---|
173 | ; Tests 32-bit addressing using the LEA instruction.
|
---|
174 | ;
|
---|
175 | BS3_PROC_BEGIN_CMN bs3CpuBasic3_lea_32, BS3_PBC_FAR
|
---|
176 | pushad
|
---|
177 | mov [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))], esp
|
---|
178 |
|
---|
179 | ;
|
---|
180 | ; Loop thru all the modr/m memory encodings.
|
---|
181 | ;
|
---|
182 | %assign iMod 0
|
---|
183 | %rep 3
|
---|
184 | %assign iDstReg 0
|
---|
185 | %rep 8
|
---|
186 | %assign iMemReg 0
|
---|
187 | %rep 8
|
---|
188 | %if iDstReg == 0
|
---|
189 | %assign iDstReg_Value LEA_EAX
|
---|
190 | %elif iDstReg == 1
|
---|
191 | %assign iDstReg_Value LEA_ECX
|
---|
192 | %elif iDstReg == 2
|
---|
193 | %assign iDstReg_Value LEA_EDX
|
---|
194 | %elif iDstReg == 3
|
---|
195 | %assign iDstReg_Value LEA_EBX
|
---|
196 | %elif iDstReg == 4
|
---|
197 | %assign iDstReg_Value LEA_ESP
|
---|
198 | %elif iDstReg == 5
|
---|
199 | %assign iDstReg_Value LEA_EBP
|
---|
200 | %elif iDstReg == 6
|
---|
201 | %assign iDstReg_Value LEA_ESI
|
---|
202 | %elif iDstReg == 7
|
---|
203 | %assign iDstReg_Value LEA_EDI
|
---|
204 | %else
|
---|
205 | %error iDstReg
|
---|
206 | %endif
|
---|
207 |
|
---|
208 | %if iMemReg == 4
|
---|
209 | ;
|
---|
210 | ; SIB.
|
---|
211 | ;
|
---|
212 | %assign iBase 0
|
---|
213 | %rep 8
|
---|
214 | %if iBase == 0
|
---|
215 | %assign iBase_Value LEA_EAX
|
---|
216 | %elif iBase == 1
|
---|
217 | %assign iBase_Value LEA_ECX
|
---|
218 | %elif iBase == 2
|
---|
219 | %assign iBase_Value LEA_EDX
|
---|
220 | %elif iBase == 3
|
---|
221 | %assign iBase_Value LEA_EBX
|
---|
222 | %elif iBase == 4
|
---|
223 | %assign iBase_Value LEA_ESP
|
---|
224 | %elif iBase == 5 && iMod == 0
|
---|
225 | %assign iBase_Value 0
|
---|
226 | %elif iBase == 5
|
---|
227 | %assign iBase_Value LEA_EBP
|
---|
228 | %elif iBase == 6
|
---|
229 | %assign iBase_Value LEA_ESI
|
---|
230 | %elif iBase == 7
|
---|
231 | %assign iBase_Value LEA_EDI
|
---|
232 | %else
|
---|
233 | %error iBase
|
---|
234 | %endif
|
---|
235 |
|
---|
236 | %assign iIndex 0
|
---|
237 | %assign cShift 0 ; we don't have enough room for checking all the shifts in the 16-bit segment or the total image.
|
---|
238 | %rep 8
|
---|
239 | %if iIndex == 0
|
---|
240 | %assign iIndex_Value LEA_EAX
|
---|
241 | %elif iIndex == 1
|
---|
242 | %assign iIndex_Value LEA_ECX
|
---|
243 | %elif iIndex == 2
|
---|
244 | %assign iIndex_Value LEA_EDX
|
---|
245 | %elif iIndex == 3
|
---|
246 | %assign iIndex_Value LEA_EBX
|
---|
247 | %elif iIndex == 4
|
---|
248 | %assign iIndex_Value 0
|
---|
249 | %elif iIndex == 5
|
---|
250 | %assign iIndex_Value LEA_EBP
|
---|
251 | %elif iIndex == 6
|
---|
252 | %assign iIndex_Value LEA_ESI
|
---|
253 | %elif iIndex == 7
|
---|
254 | %assign iIndex_Value LEA_EDI
|
---|
255 | %else
|
---|
256 | %error iIndex
|
---|
257 | %endif
|
---|
258 |
|
---|
259 | ;
|
---|
260 | ; We don't test all shift combinations, there just isn't enough space
|
---|
261 | ; in the image (32-bit case) or the segment (16-bit case) unfortunately.
|
---|
262 | ;
|
---|
263 | %if TMPL_BITS == 32
|
---|
264 | %assign cShiftLoops 2
|
---|
265 | %else
|
---|
266 | %assign cShiftLoops 1
|
---|
267 | %endif
|
---|
268 | %rep cShiftLoops
|
---|
269 |
|
---|
270 | ;
|
---|
271 | ; LEA+SIB w/ 32-bit operand size.
|
---|
272 | ;
|
---|
273 | call .load_regs
|
---|
274 | %if iBase == 4 || iDstReg == 4
|
---|
275 | mov esp, LEA_ESP
|
---|
276 | %endif
|
---|
277 |
|
---|
278 | ; lea
|
---|
279 | %assign iValue iBase_Value + (iIndex_Value << cShift)
|
---|
280 | db MY_O32 8dh, X86_MODRM_MAKE(iMod, iDstReg, iMemReg), X86_SIB_MAKE(iBase, iIndex, cShift)
|
---|
281 | %if iMod == X86_MOD_MEM1
|
---|
282 | db -119
|
---|
283 | %assign iValue iValue - 119
|
---|
284 | %elif iMod == X86_MOD_MEM4 || (iMod == 0 && iBase == 5)
|
---|
285 | dd -04353f1ech
|
---|
286 | %assign iValue iValue - 04353f1ech
|
---|
287 | %endif
|
---|
288 |
|
---|
289 | ; cmp iDstReg, iValue
|
---|
290 | db MY_CMP_O32 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg)
|
---|
291 | dd iValue & 0ffffffffh
|
---|
292 | %if iBase == 4 || iDstReg == 4
|
---|
293 | mov esp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
|
---|
294 | %endif
|
---|
295 | jz $+3
|
---|
296 | int3
|
---|
297 | %assign cShift (cShift + 1) & 3
|
---|
298 |
|
---|
299 | ;
|
---|
300 | ; LEA+SIB w/ 16-bit operand size.
|
---|
301 | ;
|
---|
302 | %if TMPL_BITS == 32 ; No room in the 16-bit segment for all of this.
|
---|
303 | call .load_regs
|
---|
304 | %if iBase == 4 || iDstReg == 4
|
---|
305 | mov esp, LEA_ESP
|
---|
306 | %endif
|
---|
307 |
|
---|
308 | ; lea
|
---|
309 | %assign iValue iBase_Value + (iIndex_Value << cShift)
|
---|
310 | db MY_O16 8dh, X86_MODRM_MAKE(iMod, iDstReg, iMemReg), X86_SIB_MAKE(iBase, iIndex, cShift)
|
---|
311 | %if iMod == X86_MOD_MEM1
|
---|
312 | db -7
|
---|
313 | %assign iValue iValue - 7
|
---|
314 | %elif iMod == X86_MOD_MEM4 || (iMod == 0 && iBase == 5)
|
---|
315 | dd -073d676e4h
|
---|
316 | %assign iValue iValue - 073d676e4h
|
---|
317 | %endif
|
---|
318 |
|
---|
319 | ; cmp iDstReg, iValue
|
---|
320 | db MY_CMP_O32 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg)
|
---|
321 | dd (iValue & 00000ffffh) | (iDstReg_Value & 0ffff0000h)
|
---|
322 | %if 1 || iBase == 4 || iDstReg == 4
|
---|
323 | mov esp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
|
---|
324 | %endif
|
---|
325 | jz $+3
|
---|
326 | int3
|
---|
327 | %assign cShift (cShift + 2) & 3
|
---|
328 | %endif ; TMPL_BITS == 32
|
---|
329 | %endrep
|
---|
330 | %assign iIndex iIndex + 1
|
---|
331 | %endrep
|
---|
332 | %assign iBase iBase + 1
|
---|
333 | %endrep
|
---|
334 |
|
---|
335 | %else ; !SIB
|
---|
336 | ;
|
---|
337 | ; Plain lea reg, [reg] with disp according to iMod,
|
---|
338 | ; or lea reg, [disp32] if iMemReg == 5 && iMod == 0.
|
---|
339 | ;
|
---|
340 | %if iMemReg == 0
|
---|
341 | %assign iMemReg_Value LEA_EAX
|
---|
342 | %elif iMemReg == 1
|
---|
343 | %assign iMemReg_Value LEA_ECX
|
---|
344 | %elif iMemReg == 2
|
---|
345 | %assign iMemReg_Value LEA_EDX
|
---|
346 | %elif iMemReg == 3
|
---|
347 | %assign iMemReg_Value LEA_EBX
|
---|
348 | %elif iMemReg == 5 && iMod == 0
|
---|
349 | %assign iMemReg_Value 0
|
---|
350 | %elif iMemReg == 5
|
---|
351 | %assign iMemReg_Value LEA_EBP
|
---|
352 | %elif iMemReg == 6
|
---|
353 | %assign iMemReg_Value LEA_ESI
|
---|
354 | %elif iMemReg == 7
|
---|
355 | %assign iMemReg_Value LEA_EDI
|
---|
356 | %else
|
---|
357 | %error iMemReg
|
---|
358 | %endif
|
---|
359 |
|
---|
360 | ;
|
---|
361 | ; 32-bit operand size first.
|
---|
362 | ;
|
---|
363 | call .load_regs
|
---|
364 | %if iDstReg == 4
|
---|
365 | mov esp, LEA_ESP
|
---|
366 | %endif
|
---|
367 |
|
---|
368 | ; lea
|
---|
369 | %assign iValue iMemReg_Value
|
---|
370 | db MY_O32 8dh, X86_MODRM_MAKE(iMod, iDstReg, iMemReg)
|
---|
371 | %if iMod == X86_MOD_MEM1
|
---|
372 | db 89
|
---|
373 | %assign iValue iValue + 89
|
---|
374 | %elif iMod == X86_MOD_MEM4 || (iMod == 0 && iMemReg == 5)
|
---|
375 | dd 058739af8h
|
---|
376 | %assign iValue iValue + 058739af8h
|
---|
377 | %endif
|
---|
378 |
|
---|
379 | ; cmp iDstReg, iValue
|
---|
380 | db MY_CMP_O32 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg)
|
---|
381 | dd iValue & 0ffffffffh
|
---|
382 | %if iDstReg == 4
|
---|
383 | mov esp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
|
---|
384 | %endif
|
---|
385 | jz $+3
|
---|
386 | int3
|
---|
387 |
|
---|
388 | ;
|
---|
389 | ; 16-bit operand size next.
|
---|
390 | ;
|
---|
391 | call .load_regs
|
---|
392 | %if iDstReg == 4
|
---|
393 | mov esp, LEA_ESP
|
---|
394 | %endif
|
---|
395 |
|
---|
396 | ; lea
|
---|
397 | %assign iValue iMemReg_Value
|
---|
398 | db MY_O16 8dh, X86_MODRM_MAKE(iMod, iDstReg, iMemReg)
|
---|
399 | %if iMod == X86_MOD_MEM1
|
---|
400 | db -98
|
---|
401 | %assign iValue iValue - 98
|
---|
402 | %elif iMod == X86_MOD_MEM4 || (iMod == 0 && iMemReg == 5)
|
---|
403 | dd 0f3694352h
|
---|
404 | %assign iValue iValue + 0f3694352h
|
---|
405 | %endif
|
---|
406 |
|
---|
407 | ; cmp iDstReg, iValue
|
---|
408 | db MY_CMP_O32 81h, X86_MODRM_MAKE(X86_MOD_REG, 7, iDstReg)
|
---|
409 | dd (iValue & 00000ffffh) | (iDstReg_Value & 0ffff0000h)
|
---|
410 | %if iDstReg == 4
|
---|
411 | mov esp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
|
---|
412 | %endif
|
---|
413 | jz $+3
|
---|
414 | int3
|
---|
415 |
|
---|
416 | %endif ; !SIB
|
---|
417 | %assign iMemReg iMemReg + 1
|
---|
418 | %endrep
|
---|
419 | %assign iDstReg iDstReg + 1
|
---|
420 | %endrep
|
---|
421 | %assign iMod iMod + 1
|
---|
422 | %endrep
|
---|
423 |
|
---|
424 | mov esp, [BS3_DATA16_WRT(BS3_DATA_NM(g_bs3CpuBasic3_lea_rsp))]
|
---|
425 | popad
|
---|
426 | BS3_HYBRID_RET
|
---|
427 |
|
---|
428 | .load_regs:
|
---|
429 | mov eax, LEA_EAX
|
---|
430 | mov ecx, LEA_ECX
|
---|
431 | mov edx, LEA_EDX
|
---|
432 | mov ebx, LEA_EBX
|
---|
433 | mov ebp, LEA_EBP
|
---|
434 | mov esi, LEA_ESI
|
---|
435 | mov edi, LEA_EDI
|
---|
436 | ret
|
---|
437 | BS3_PROC_END_CMN bs3CpuBasic3_lea_32
|
---|
438 |
|
---|
439 | %endif ; TMPL_BITS != 64
|
---|
440 |
|
---|
441 |
|
---|
442 | %include "bs3kit-template-footer.mac" ; reset environment
|
---|
443 |
|
---|