1 /////////////////////////////////////////////////////////////////////////
2 // $Id: load32.cc,v 1.3 2008/12/11 21:19:38 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (c) 2008 Stanislav Shwartsman
6 // Written by Stanislav Shwartsman [sshwarts at sourceforge net]
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /////////////////////////////////////////////////////////////////////////
24 #define NEED_CPU_REG_SHORTCUTS 1
27 #define LOG_THIS BX_CPU_THIS_PTR
29 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Eb(bxInstruction_c
*i
)
31 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
32 TMP8L
= read_virtual_byte(i
->seg(), eaddr
);
33 BX_CPU_CALL_METHOD(i
->execute2
, (i
));
36 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Eb_Resolve16BaseIndex(bxInstruction_c
*i
)
38 Bit16u offset
= BX_READ_16BIT_REG(i
->sibBase()) + BX_READ_16BIT_REG(i
->sibIndex()) + (Bit16s
) i
->displ16u();
41 unsigned s
= i
->seg();
42 bx_segment_reg_t
*seg
= &BX_CPU_THIS_PTR sregs
[s
];
43 BX_INSTR_MEM_DATA_ACCESS(BX_CPU_ID
, s
, offset
, 1, BX_READ
);
45 BX_ASSERT(BX_CPU_THIS_PTR cpu_mode
!= BX_MODE_LONG_64
);
47 if (seg
->cache
.valid
& SegAccessROK
) {
48 if (offset
<= seg
->cache
.u
.segment
.limit_scaled
) {
50 laddr
= BX_CPU_THIS_PTR
get_laddr32(s
, offset
);
51 unsigned tlbIndex
= BX_TLB_INDEX_OF(laddr
, 0);
52 Bit32u lpf
= LPFOf(laddr
);
53 bx_TLB_entry
*tlbEntry
= &BX_CPU_THIS_PTR TLB
.entry
[tlbIndex
];
54 if (tlbEntry
->lpf
== lpf
&& ! (tlbEntry
->accessBits
& USER_PL
)) {
55 // See if the TLB entry privilege level allows us read access
57 bx_hostpageaddr_t hostPageAddr
= tlbEntry
->hostPageAddr
;
58 Bit32u pageOffset
= PAGE_OFFSET(laddr
);
59 Bit8u
*hostAddr
= (Bit8u
*) (hostPageAddr
| pageOffset
);
61 BX_INSTR_LIN_ACCESS(BX_CPU_ID
, laddr
, tlbEntry
->ppf
| pageOffset
, 1, BX_READ
);
62 BX_DBG_LIN_MEMORY_ACCESS(BX_CPU_ID
, laddr
,
63 tlbEntry
->ppf
| pageOffset
, 1, CPL
, BX_READ
, (Bit8u
*) &TMP8L
);
66 access_read_linear(laddr
, 1, CPL
, BX_READ
, (void *) &TMP8L
);
69 BX_CPU_CALL_METHOD(i
->execute2
, (i
));
73 BX_ERROR(("LOAD_Eb(): segment limit violation"));
74 exception(int_number(s
), 0, 0);
78 if (!read_virtual_checks(seg
, offset
, 1))
79 exception(int_number(s
), 0, 0);
83 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Eb_Resolve32Base(bxInstruction_c
*i
)
85 Bit32u offset
= BX_READ_32BIT_REG(i
->sibBase()) + (Bit32s
) i
->displ32u();
88 unsigned s
= i
->seg();
89 bx_segment_reg_t
*seg
= &BX_CPU_THIS_PTR sregs
[s
];
90 BX_INSTR_MEM_DATA_ACCESS(BX_CPU_ID
, s
, offset
, 1, BX_READ
);
92 BX_ASSERT(BX_CPU_THIS_PTR cpu_mode
!= BX_MODE_LONG_64
);
94 if (seg
->cache
.valid
& SegAccessROK
) {
95 if (offset
<= seg
->cache
.u
.segment
.limit_scaled
) {
97 laddr
= BX_CPU_THIS_PTR
get_laddr32(s
, offset
);
98 unsigned tlbIndex
= BX_TLB_INDEX_OF(laddr
, 0);
99 Bit32u lpf
= LPFOf(laddr
);
100 bx_TLB_entry
*tlbEntry
= &BX_CPU_THIS_PTR TLB
.entry
[tlbIndex
];
101 if (tlbEntry
->lpf
== lpf
&& ! (tlbEntry
->accessBits
& USER_PL
)) {
102 // See if the TLB entry privilege level allows us read access
104 bx_hostpageaddr_t hostPageAddr
= tlbEntry
->hostPageAddr
;
105 Bit32u pageOffset
= PAGE_OFFSET(laddr
);
106 Bit8u
*hostAddr
= (Bit8u
*) (hostPageAddr
| pageOffset
);
108 BX_INSTR_LIN_ACCESS(BX_CPU_ID
, laddr
, tlbEntry
->ppf
| pageOffset
, 1, BX_READ
);
109 BX_DBG_LIN_MEMORY_ACCESS(BX_CPU_ID
, laddr
,
110 tlbEntry
->ppf
| pageOffset
, 1, CPL
, BX_READ
, (Bit8u
*) &TMP8L
);
113 access_read_linear(laddr
, 1, CPL
, BX_READ
, (void *) &TMP8L
);
116 BX_CPU_CALL_METHOD(i
->execute2
, (i
));
120 BX_ERROR(("LOAD_Eb(): segment limit violation"));
121 exception(int_number(s
), 0, 0);
125 if (!read_virtual_checks(seg
, offset
, 1))
126 exception(int_number(s
), 0, 0);
130 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Eb_Resolve32BaseIndex(bxInstruction_c
*i
)
132 Bit32u offset
= BX_READ_32BIT_REG(i
->sibBase()) + (BX_READ_32BIT_REG(i
->sibIndex()) << i
->sibScale()) + (Bit32s
) i
->displ32u();
135 unsigned s
= i
->seg();
136 bx_segment_reg_t
*seg
= &BX_CPU_THIS_PTR sregs
[s
];
137 BX_INSTR_MEM_DATA_ACCESS(BX_CPU_ID
, s
, offset
, 1, BX_READ
);
139 BX_ASSERT(BX_CPU_THIS_PTR cpu_mode
!= BX_MODE_LONG_64
);
141 if (seg
->cache
.valid
& SegAccessROK
) {
142 if (offset
<= seg
->cache
.u
.segment
.limit_scaled
) {
144 laddr
= BX_CPU_THIS_PTR
get_laddr32(s
, offset
);
145 unsigned tlbIndex
= BX_TLB_INDEX_OF(laddr
, 0);
146 Bit32u lpf
= LPFOf(laddr
);
147 bx_TLB_entry
*tlbEntry
= &BX_CPU_THIS_PTR TLB
.entry
[tlbIndex
];
148 if (tlbEntry
->lpf
== lpf
&& ! (tlbEntry
->accessBits
& USER_PL
)) {
149 // See if the TLB entry privilege level allows us read access
151 bx_hostpageaddr_t hostPageAddr
= tlbEntry
->hostPageAddr
;
152 Bit32u pageOffset
= PAGE_OFFSET(laddr
);
153 Bit8u
*hostAddr
= (Bit8u
*) (hostPageAddr
| pageOffset
);
155 BX_INSTR_LIN_ACCESS(BX_CPU_ID
, laddr
, tlbEntry
->ppf
| pageOffset
, 1, BX_READ
);
156 BX_DBG_LIN_MEMORY_ACCESS(BX_CPU_ID
, laddr
,
157 tlbEntry
->ppf
| pageOffset
, 1, CPL
, BX_READ
, (Bit8u
*) &TMP8L
);
160 access_read_linear(laddr
, 1, CPL
, BX_READ
, (void *) &TMP8L
);
163 BX_CPU_CALL_METHOD(i
->execute2
, (i
));
167 BX_ERROR(("LOAD_Eb(): segment limit violation"));
168 exception(int_number(s
), 0, 0);
172 if (!read_virtual_checks(seg
, offset
, 1))
173 exception(int_number(s
), 0, 0);
177 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Ew(bxInstruction_c
*i
)
179 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
180 TMP16
= read_virtual_word(i
->seg(), eaddr
);
181 BX_CPU_CALL_METHOD(i
->execute2
, (i
));
184 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Ew_Resolve16BaseIndex(bxInstruction_c
*i
)
186 Bit16u offset
= BX_READ_16BIT_REG(i
->sibBase()) + BX_READ_16BIT_REG(i
->sibIndex()) + (Bit16s
) i
->displ16u();
189 unsigned s
= i
->seg();
190 bx_segment_reg_t
*seg
= &BX_CPU_THIS_PTR sregs
[s
];
191 BX_INSTR_MEM_DATA_ACCESS(BX_CPU_ID
, s
, offset
, 2, BX_READ
);
193 BX_ASSERT(BX_CPU_THIS_PTR cpu_mode
!= BX_MODE_LONG_64
);
195 if (seg
->cache
.valid
& SegAccessROK
) {
196 if (offset
< seg
->cache
.u
.segment
.limit_scaled
) {
198 laddr
= BX_CPU_THIS_PTR
get_laddr32(s
, offset
);
199 unsigned tlbIndex
= BX_TLB_INDEX_OF(laddr
, 1);
200 Bit32u lpf
= LPFOf(laddr
);
201 bx_TLB_entry
*tlbEntry
= &BX_CPU_THIS_PTR TLB
.entry
[tlbIndex
];
202 if (tlbEntry
->lpf
== lpf
&& ! (tlbEntry
->accessBits
& USER_PL
)) {
203 // See if the TLB entry privilege level allows us read access
205 bx_hostpageaddr_t hostPageAddr
= tlbEntry
->hostPageAddr
;
206 Bit32u pageOffset
= PAGE_OFFSET(laddr
);
207 Bit16u
*hostAddr
= (Bit16u
*) (hostPageAddr
| pageOffset
);
208 ReadHostWordFromLittleEndian(hostAddr
, TMP16
);
209 BX_INSTR_LIN_ACCESS(BX_CPU_ID
, laddr
, tlbEntry
->ppf
| pageOffset
, 2, BX_READ
);
210 BX_DBG_LIN_MEMORY_ACCESS(BX_CPU_ID
, laddr
,
211 tlbEntry
->ppf
| pageOffset
, 2, CPL
, BX_READ
, (Bit8u
*) &TMP16
);
214 access_read_linear(laddr
, 2, CPL
, BX_READ
, (void *) &TMP16
);
217 BX_CPU_CALL_METHOD(i
->execute2
, (i
));
221 BX_ERROR(("LOAD_Ew(): segment limit violation"));
222 exception(int_number(s
), 0, 0);
226 if (!read_virtual_checks(seg
, offset
, 2))
227 exception(int_number(s
), 0, 0);
231 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Ew_Resolve32Base(bxInstruction_c
*i
)
233 Bit32u offset
= BX_READ_32BIT_REG(i
->sibBase()) + (Bit32s
) i
->displ32u();
236 unsigned s
= i
->seg();
237 bx_segment_reg_t
*seg
= &BX_CPU_THIS_PTR sregs
[s
];
238 BX_INSTR_MEM_DATA_ACCESS(BX_CPU_ID
, s
, offset
, 2, BX_READ
);
240 BX_ASSERT(BX_CPU_THIS_PTR cpu_mode
!= BX_MODE_LONG_64
);
242 if (seg
->cache
.valid
& SegAccessROK
) {
243 if (offset
< seg
->cache
.u
.segment
.limit_scaled
) {
245 laddr
= BX_CPU_THIS_PTR
get_laddr32(s
, offset
);
246 unsigned tlbIndex
= BX_TLB_INDEX_OF(laddr
, 1);
247 Bit32u lpf
= LPFOf(laddr
);
248 bx_TLB_entry
*tlbEntry
= &BX_CPU_THIS_PTR TLB
.entry
[tlbIndex
];
249 if (tlbEntry
->lpf
== lpf
&& ! (tlbEntry
->accessBits
& USER_PL
)) {
250 // See if the TLB entry privilege level allows us read access
252 bx_hostpageaddr_t hostPageAddr
= tlbEntry
->hostPageAddr
;
253 Bit32u pageOffset
= PAGE_OFFSET(laddr
);
254 Bit16u
*hostAddr
= (Bit16u
*) (hostPageAddr
| pageOffset
);
255 ReadHostWordFromLittleEndian(hostAddr
, TMP16
);
256 BX_INSTR_LIN_ACCESS(BX_CPU_ID
, laddr
, tlbEntry
->ppf
| pageOffset
, 2, BX_READ
);
257 BX_DBG_LIN_MEMORY_ACCESS(BX_CPU_ID
, laddr
,
258 tlbEntry
->ppf
| pageOffset
, 2, CPL
, BX_READ
, (Bit8u
*) &TMP16
);
261 access_read_linear(laddr
, 2, CPL
, BX_READ
, (void *) &TMP16
);
264 BX_CPU_CALL_METHOD(i
->execute2
, (i
));
268 BX_ERROR(("LOAD_Ew(): segment limit violation"));
269 exception(int_number(s
), 0, 0);
273 if (!read_virtual_checks(seg
, offset
, 2))
274 exception(int_number(s
), 0, 0);
278 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Ew_Resolve32BaseIndex(bxInstruction_c
*i
)
280 Bit32u offset
= BX_READ_32BIT_REG(i
->sibBase()) + (BX_READ_32BIT_REG(i
->sibIndex()) << i
->sibScale()) + (Bit32s
) i
->displ32u();
283 unsigned s
= i
->seg();
284 bx_segment_reg_t
*seg
= &BX_CPU_THIS_PTR sregs
[s
];
285 BX_INSTR_MEM_DATA_ACCESS(BX_CPU_ID
, s
, offset
, 2, BX_READ
);
287 BX_ASSERT(BX_CPU_THIS_PTR cpu_mode
!= BX_MODE_LONG_64
);
289 if (seg
->cache
.valid
& SegAccessROK
) {
290 if (offset
< seg
->cache
.u
.segment
.limit_scaled
) {
292 laddr
= BX_CPU_THIS_PTR
get_laddr32(s
, offset
);
293 unsigned tlbIndex
= BX_TLB_INDEX_OF(laddr
, 1);
294 Bit32u lpf
= LPFOf(laddr
);
295 bx_TLB_entry
*tlbEntry
= &BX_CPU_THIS_PTR TLB
.entry
[tlbIndex
];
296 if (tlbEntry
->lpf
== lpf
&& ! (tlbEntry
->accessBits
& USER_PL
)) {
297 // See if the TLB entry privilege level allows us read access
299 bx_hostpageaddr_t hostPageAddr
= tlbEntry
->hostPageAddr
;
300 Bit32u pageOffset
= PAGE_OFFSET(laddr
);
301 Bit16u
*hostAddr
= (Bit16u
*) (hostPageAddr
| pageOffset
);
302 ReadHostWordFromLittleEndian(hostAddr
, TMP16
);
303 BX_INSTR_LIN_ACCESS(BX_CPU_ID
, laddr
, tlbEntry
->ppf
| pageOffset
, 2, BX_READ
);
304 BX_DBG_LIN_MEMORY_ACCESS(BX_CPU_ID
, laddr
,
305 tlbEntry
->ppf
| pageOffset
, 2, CPL
, BX_READ
, (Bit8u
*) &TMP16
);
308 access_read_linear(laddr
, 2, CPL
, BX_READ
, (void *) &TMP16
);
311 BX_CPU_CALL_METHOD(i
->execute2
, (i
));
315 BX_ERROR(("LOAD_Ew(): segment limit violation"));
316 exception(int_number(s
), 0, 0);
320 if (!read_virtual_checks(seg
, offset
, 2))
321 exception(int_number(s
), 0, 0);
325 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Ed(bxInstruction_c
*i
)
327 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
328 TMP32
= read_virtual_dword(i
->seg(), eaddr
);
329 BX_CPU_CALL_METHOD(i
->execute2
, (i
));
332 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Ed_Resolve16BaseIndex(bxInstruction_c
*i
)
334 Bit16u offset
= BX_READ_16BIT_REG(i
->sibBase()) + BX_READ_16BIT_REG(i
->sibIndex()) + (Bit16s
) i
->displ16u();
337 unsigned s
= i
->seg();
338 bx_segment_reg_t
*seg
= &BX_CPU_THIS_PTR sregs
[s
];
339 BX_INSTR_MEM_DATA_ACCESS(BX_CPU_ID
, s
, offset
, 4, BX_READ
);
341 BX_ASSERT(BX_CPU_THIS_PTR cpu_mode
!= BX_MODE_LONG_64
);
343 if (seg
->cache
.valid
& SegAccessROK
) {
344 if (offset
< (seg
->cache
.u
.segment
.limit_scaled
-2)) {
346 laddr
= BX_CPU_THIS_PTR
get_laddr32(s
, offset
);
347 unsigned tlbIndex
= BX_TLB_INDEX_OF(laddr
, 3);
348 Bit32u lpf
= LPFOf(laddr
);
349 bx_TLB_entry
*tlbEntry
= &BX_CPU_THIS_PTR TLB
.entry
[tlbIndex
];
350 if (tlbEntry
->lpf
== lpf
&& ! (tlbEntry
->accessBits
& USER_PL
)) {
351 // See if the TLB entry privilege level allows us read access
353 bx_hostpageaddr_t hostPageAddr
= tlbEntry
->hostPageAddr
;
354 Bit32u pageOffset
= PAGE_OFFSET(laddr
);
355 Bit32u
*hostAddr
= (Bit32u
*) (hostPageAddr
| pageOffset
);
356 ReadHostDWordFromLittleEndian(hostAddr
, TMP32
);
357 BX_INSTR_LIN_ACCESS(BX_CPU_ID
, laddr
, tlbEntry
->ppf
| pageOffset
, 4, BX_READ
);
358 BX_DBG_LIN_MEMORY_ACCESS(BX_CPU_ID
, laddr
,
359 tlbEntry
->ppf
| pageOffset
, 4, CPL
, BX_READ
, (Bit8u
*) &TMP32
);
362 access_read_linear(laddr
, 4, CPL
, BX_READ
, (void *) &TMP32
);
365 BX_CPU_CALL_METHOD(i
->execute2
, (i
));
369 BX_ERROR(("LOAD_Ed(): segment limit violation"));
370 exception(int_number(s
), 0, 0);
374 if (!read_virtual_checks(seg
, offset
, 4))
375 exception(int_number(s
), 0, 0);
379 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Ed_Resolve32Base(bxInstruction_c
*i
)
381 Bit32u offset
= BX_READ_32BIT_REG(i
->sibBase()) + (Bit32s
) i
->displ32u();
384 unsigned s
= i
->seg();
385 bx_segment_reg_t
*seg
= &BX_CPU_THIS_PTR sregs
[s
];
386 BX_INSTR_MEM_DATA_ACCESS(BX_CPU_ID
, s
, offset
, 4, BX_READ
);
388 BX_ASSERT(BX_CPU_THIS_PTR cpu_mode
!= BX_MODE_LONG_64
);
390 if (seg
->cache
.valid
& SegAccessROK
) {
391 if (offset
< (seg
->cache
.u
.segment
.limit_scaled
-2)) {
393 laddr
= BX_CPU_THIS_PTR
get_laddr32(s
, offset
);
394 unsigned tlbIndex
= BX_TLB_INDEX_OF(laddr
, 3);
395 Bit32u lpf
= LPFOf(laddr
);
396 bx_TLB_entry
*tlbEntry
= &BX_CPU_THIS_PTR TLB
.entry
[tlbIndex
];
397 if (tlbEntry
->lpf
== lpf
&& ! (tlbEntry
->accessBits
& USER_PL
)) {
398 // See if the TLB entry privilege level allows us read access
400 bx_hostpageaddr_t hostPageAddr
= tlbEntry
->hostPageAddr
;
401 Bit32u pageOffset
= PAGE_OFFSET(laddr
);
402 Bit32u
*hostAddr
= (Bit32u
*) (hostPageAddr
| pageOffset
);
403 ReadHostDWordFromLittleEndian(hostAddr
, TMP32
);
404 BX_INSTR_LIN_ACCESS(BX_CPU_ID
, laddr
, tlbEntry
->ppf
| pageOffset
, 4, BX_READ
);
405 BX_DBG_LIN_MEMORY_ACCESS(BX_CPU_ID
, laddr
,
406 tlbEntry
->ppf
| pageOffset
, 4, CPL
, BX_READ
, (Bit8u
*) &TMP32
);
409 access_read_linear(laddr
, 4, CPL
, BX_READ
, (void *) &TMP32
);
412 BX_CPU_CALL_METHOD(i
->execute2
, (i
));
416 BX_ERROR(("LOAD_Ed(): segment limit violation"));
417 exception(int_number(s
), 0, 0);
421 if (!read_virtual_checks(seg
, offset
, 4))
422 exception(int_number(s
), 0, 0);
426 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Ed_Resolve32BaseIndex(bxInstruction_c
*i
)
428 Bit32u offset
= BX_READ_32BIT_REG(i
->sibBase()) + (BX_READ_32BIT_REG(i
->sibIndex()) << i
->sibScale()) + (Bit32s
) i
->displ32u();
431 unsigned s
= i
->seg();
432 bx_segment_reg_t
*seg
= &BX_CPU_THIS_PTR sregs
[s
];
433 BX_INSTR_MEM_DATA_ACCESS(BX_CPU_ID
, s
, offset
, 4, BX_READ
);
435 BX_ASSERT(BX_CPU_THIS_PTR cpu_mode
!= BX_MODE_LONG_64
);
437 if (seg
->cache
.valid
& SegAccessROK
) {
438 if (offset
< (seg
->cache
.u
.segment
.limit_scaled
-2)) {
440 laddr
= BX_CPU_THIS_PTR
get_laddr32(s
, offset
);
441 unsigned tlbIndex
= BX_TLB_INDEX_OF(laddr
, 3);
442 Bit32u lpf
= LPFOf(laddr
);
443 bx_TLB_entry
*tlbEntry
= &BX_CPU_THIS_PTR TLB
.entry
[tlbIndex
];
444 if (tlbEntry
->lpf
== lpf
&& !(tlbEntry
->accessBits
& USER_PL
)) {
445 // See if the TLB entry privilege level allows us read access
447 bx_hostpageaddr_t hostPageAddr
= tlbEntry
->hostPageAddr
;
448 Bit32u pageOffset
= PAGE_OFFSET(laddr
);
449 Bit32u
*hostAddr
= (Bit32u
*) (hostPageAddr
| pageOffset
);
450 ReadHostDWordFromLittleEndian(hostAddr
, TMP32
);
451 BX_INSTR_LIN_ACCESS(BX_CPU_ID
, laddr
, tlbEntry
->ppf
| pageOffset
, 4, BX_READ
);
452 BX_DBG_LIN_MEMORY_ACCESS(BX_CPU_ID
, laddr
,
453 tlbEntry
->ppf
| pageOffset
, 4, CPL
, BX_READ
, (Bit8u
*) &TMP32
);
456 access_read_linear(laddr
, 4, CPL
, BX_READ
, (void *) &TMP32
);
459 BX_CPU_CALL_METHOD(i
->execute2
, (i
));
463 BX_ERROR(("LOAD_Ed(): segment limit violation"));
464 exception(int_number(s
), 0, 0);
468 if (!read_virtual_checks(seg
, offset
, 4))
469 exception(int_number(s
), 0, 0);
473 #if BX_SUPPORT_X86_64
474 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Eq(bxInstruction_c
*i
)
476 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
477 TMP64
= read_virtual_qword_64(i
->seg(), eaddr
);
478 BX_CPU_CALL_METHOD(i
->execute2
, (i
));
482 #if BX_SUPPORT_SSE >= 1
484 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Wdq(bxInstruction_c
*i
)
486 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
487 readVirtualDQwordAligned(i
->seg(), eaddr
, (Bit8u
*)(&BX_READ_XMM_REG(BX_TMP_REGISTER
)));
488 BX_CPU_CALL_METHOD(i
->execute2
, (i
));
491 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Wss(bxInstruction_c
*i
)
493 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
494 Bit32u val_32
= read_virtual_dword(i
->seg(), eaddr
);
495 BX_WRITE_XMM_REG_LO_DWORD(BX_TMP_REGISTER
, val_32
);
496 BX_CPU_CALL_METHOD(i
->execute2
, (i
));
499 void BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Wsd(bxInstruction_c
*i
)
501 bx_address eaddr
= BX_CPU_CALL_METHODR(i
->ResolveModrm
, (i
));
502 Bit64u val_64
= read_virtual_qword(i
->seg(), eaddr
);
503 BX_WRITE_XMM_REG_LO_QWORD(BX_TMP_REGISTER
, val_64
);
504 BX_CPU_CALL_METHOD(i
->execute2
, (i
));