- tftp_send_optack() was not 64-bit clean (patch from SF bug #1787500)
[bochs-mirror.git] / cpu / shift32.cc
blobbbd18c35a9298d6f68a61e1d023e08f437597b29
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: shift32.cc,v 1.31 2006/03/26 18:58:01 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (C) 2001 MandrakeSoft S.A.
6 //
7 // MandrakeSoft S.A.
8 // 43, rue d'Aboukir
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #define NEED_CPU_REG_SHORTCUTS 1
29 #include "bochs.h"
30 #include "cpu.h"
31 #define LOG_THIS BX_CPU_THIS_PTR
34 void BX_CPU_C::SHLD_EdGd(bxInstruction_c *i)
36 Bit32u op1_32, op2_32, result_32;
37 unsigned count;
39 /* op1:op2 << count. result stored in op1 */
41 if (i->b1() == 0x1a4)
42 count = i->Ib() & 0x1f;
43 else // 0x1a5
44 count = CL & 0x1f;
46 /* op1 is a register or memory reference */
47 if (i->modC0()) {
48 op1_32 = BX_READ_32BIT_REG(i->rm());
50 else {
51 /* pointer, segment address pair */
52 read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
55 if (!count) return;
57 op2_32 = BX_READ_32BIT_REG(i->nnn());
59 result_32 = (op1_32 << count) | (op2_32 >> (32 - count));
61 /* now write result back to destination */
62 if (i->modC0()) {
63 BX_WRITE_32BIT_REGZ(i->rm(), result_32);
65 else {
66 write_RMW_virtual_dword(result_32);
69 /* set eflags:
70 * SHLD count affects the following flags: O,S,Z,A,P,C
72 SET_FLAGS_OSZAPC_32(op1_32, count, result_32, BX_INSTR_SHL32);
75 void BX_CPU_C::SHRD_EdGd(bxInstruction_c *i)
77 Bit32u op1_32, op2_32, result_32;
78 unsigned count;
80 if (i->b1() == 0x1ac)
81 count = i->Ib() & 0x1f;
82 else // 0x1ad
83 count = CL & 0x1f;
85 /* op1 is a register or memory reference */
86 if (i->modC0()) {
87 op1_32 = BX_READ_32BIT_REG(i->rm());
89 else {
90 /* pointer, segment address pair */
91 read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
94 if (!count) return;
96 op2_32 = BX_READ_32BIT_REG(i->nnn());
98 result_32 = (op2_32 << (32 - count)) | (op1_32 >> count);
100 /* now write result back to destination */
101 if (i->modC0()) {
102 BX_WRITE_32BIT_REGZ(i->rm(), result_32);
104 else {
105 write_RMW_virtual_dword(result_32);
108 /* set eflags:
109 * SHRD count affects the following flags: O,S,Z,A,P,C
111 SET_FLAGS_OSZAPC_32(op1_32, count, result_32, BX_INSTR_SHRD32);
114 void BX_CPU_C::ROL_Ed(bxInstruction_c *i)
116 Bit32u op1_32, result_32;
117 unsigned count;
119 if (i->b1() == 0xc1)
120 count = i->Ib() & 0x1f;
121 else if (i->b1() == 0xd1)
122 count = 1;
123 else // (i->b1() == 0xd3)
124 count = CL & 0x1f;
126 /* op1 is a register or memory reference */
127 if (i->modC0()) {
128 op1_32 = BX_READ_32BIT_REG(i->rm());
130 else {
131 /* pointer, segment address pair */
132 read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
135 if (! count) return;
137 result_32 = (op1_32 << count) | (op1_32 >> (32 - count));
139 /* now write result back to destination */
140 if (i->modC0()) {
141 BX_WRITE_32BIT_REGZ(i->rm(), result_32);
143 else {
144 write_RMW_virtual_dword(result_32);
147 /* set eflags:
148 * ROL count affects the following flags: C, O
150 bx_bool temp_CF = (result_32 & 0x01);
152 set_CF(temp_CF);
153 set_OF(temp_CF ^ (result_32 >> 31));
156 void BX_CPU_C::ROR_Ed(bxInstruction_c *i)
158 Bit32u op1_32, result_32;
159 unsigned count;
161 if (i->b1() == 0xc1)
162 count = i->Ib() & 0x1f;
163 else if (i->b1() == 0xd1)
164 count = 1;
165 else // (i->b1() == 0xd3)
166 count = CL & 0x1f;
168 /* op1 is a register or memory reference */
169 if (i->modC0()) {
170 op1_32 = BX_READ_32BIT_REG(i->rm());
172 else {
173 /* pointer, segment address pair */
174 read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
177 if (! count) return;
179 result_32 = (op1_32 >> count) | (op1_32 << (32 - count));
181 /* now write result back to destination */
182 if (i->modC0()) {
183 BX_WRITE_32BIT_REGZ(i->rm(), result_32);
185 else {
186 write_RMW_virtual_dword(result_32);
189 /* set eflags:
190 * ROR count affects the following flags: C, O
192 bx_bool result_b31 = (result_32 & 0x80000000) != 0;
193 bx_bool result_b30 = (result_32 & 0x40000000) != 0;
195 set_CF(result_b31);
196 set_OF(result_b31 ^ result_b30);
199 void BX_CPU_C::RCL_Ed(bxInstruction_c *i)
201 Bit32u op1_32, result_32;
202 unsigned count;
204 if (i->b1() == 0xc1)
205 count = i->Ib() & 0x1f;
206 else if (i->b1() == 0xd1)
207 count = 1;
208 else // (i->b1() == 0xd3)
209 count = CL & 0x1f;
211 /* op1 is a register or memory reference */
212 if (i->modC0()) {
213 op1_32 = BX_READ_32BIT_REG(i->rm());
215 else {
216 /* pointer, segment address pair */
217 read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
220 if (!count) return;
222 if (count==1) {
223 result_32 = (op1_32 << 1) | getB_CF();
225 else {
226 result_32 = (op1_32 << count) | (getB_CF() << (count - 1)) |
227 (op1_32 >> (33 - count));
230 /* now write result back to destination */
231 if (i->modC0()) {
232 BX_WRITE_32BIT_REGZ(i->rm(), result_32);
234 else {
235 write_RMW_virtual_dword(result_32);
238 /* set eflags:
239 * RCL count affects the following flags: C, O
241 bx_bool temp_CF = (op1_32 >> (32 - count)) & 0x01;
243 set_CF(temp_CF);
244 set_OF(temp_CF ^ (result_32 >> 31));
247 void BX_CPU_C::RCR_Ed(bxInstruction_c *i)
249 Bit32u op1_32, result_32;
250 unsigned count;
252 if (i->b1() == 0xc1)
253 count = i->Ib() & 0x1f;
254 else if (i->b1() == 0xd1)
255 count = 1;
256 else // (i->b1() == 0xd3)
257 count = CL & 0x1f;
259 /* op1 is a register or memory reference */
260 if (i->modC0()) {
261 op1_32 = BX_READ_32BIT_REG(i->rm());
263 else {
264 /* pointer, segment address pair */
265 read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
268 if (!count) return;
270 if (count==1) {
271 result_32 = (op1_32 >> 1) | (getB_CF() << 31);
273 else {
274 result_32 = (op1_32 >> count) | (getB_CF() << (32 - count)) |
275 (op1_32 << (33 - count));
278 /* now write result back to destination */
279 if (i->modC0()) {
280 BX_WRITE_32BIT_REGZ(i->rm(), result_32);
282 else {
283 write_RMW_virtual_dword(result_32);
286 /* set eflags:
287 * RCR count affects the following flags: C, O
290 set_CF((op1_32 >> (count - 1)) & 0x01);
291 set_OF((((result_32 << 1) ^ result_32) & 0x80000000) > 0);
294 void BX_CPU_C::SHL_Ed(bxInstruction_c *i)
296 Bit32u op1_32, result_32;
297 unsigned count;
299 if (i->b1() == 0xc1)
300 count = i->Ib() & 0x1f;
301 else if (i->b1() == 0xd1)
302 count = 1;
303 else // (i->b1() == 0xd3)
304 count = CL & 0x1f;
306 /* op1 is a register or memory reference */
307 if (i->modC0()) {
308 op1_32 = BX_READ_32BIT_REG(i->rm());
310 else {
311 /* pointer, segment address pair */
312 read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
315 if (!count) return;
317 result_32 = (op1_32 << count);
319 /* now write result back to destination */
320 if (i->modC0()) {
321 BX_WRITE_32BIT_REGZ(i->rm(), result_32);
323 else {
324 write_RMW_virtual_dword(result_32);
327 SET_FLAGS_OSZAPC_32(op1_32, count, result_32, BX_INSTR_SHL32);
330 void BX_CPU_C::SHR_Ed(bxInstruction_c *i)
332 Bit32u op1_32, result_32;
333 unsigned count;
335 if (i->b1() == 0xc1)
336 count = i->Ib() & 0x1f;
337 else if (i->b1() == 0xd1)
338 count = 1;
339 else // (i->b1() == 0xd3)
340 count = CL & 0x1f;
342 /* op1 is a register or memory reference */
343 if (i->modC0()) {
344 op1_32 = BX_READ_32BIT_REG(i->rm());
346 else {
347 /* pointer, segment address pair */
348 read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
351 if (!count) return;
353 #if defined(BX_HostAsm_Shr32)
354 Bit32u flags32;
355 asmShr32(result_32, op1_32, count, flags32);
356 setEFlagsOSZAPC(flags32);
357 #else
358 result_32 = (op1_32 >> count);
359 SET_FLAGS_OSZAPC_32(op1_32, count, result_32, BX_INSTR_SHR32);
360 #endif
362 /* now write result back to destination */
363 if (i->modC0()) {
364 BX_WRITE_32BIT_REGZ(i->rm(), result_32);
366 else {
367 write_RMW_virtual_dword(result_32);
371 void BX_CPU_C::SAR_Ed(bxInstruction_c *i)
373 Bit32u op1_32, result_32;
374 unsigned count;
376 if (i->b1() == 0xc1)
377 count = i->Ib() & 0x1f;
378 else if (i->b1() == 0xd1)
379 count = 1;
380 else // (i->b1() == 0xd3)
381 count = CL & 0x1f;
383 /* op1 is a register or memory reference */
384 if (i->modC0()) {
385 op1_32 = BX_READ_32BIT_REG(i->rm());
387 else {
388 /* pointer, segment address pair */
389 read_RMW_virtual_dword(i->seg(), RMAddr(i), &op1_32);
392 if (!count) return;
394 /* count < 32, since only lower 5 bits used */
395 if (op1_32 & 0x80000000) {
396 result_32 = (op1_32 >> count) | (0xffffffff << (32 - count));
398 else {
399 result_32 = (op1_32 >> count);
402 /* now write result back to destination */
403 if (i->modC0()) {
404 BX_WRITE_32BIT_REGZ(i->rm(), result_32);
406 else {
407 write_RMW_virtual_dword(result_32);
410 SET_FLAGS_OSZAPC_32(op1_32, count, result_32, BX_INSTR_SAR32);