- update sector count before calling write completion function (SF patch #2144692)
[bochs-mirror.git] / cpu / mult32.cc
blob10719938b696e6e7d43a58c298a61796a973ba39
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: mult32.cc,v 1.31 2008/08/10 21:16:12 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
26 /////////////////////////////////////////////////////////////////////////
28 #define NEED_CPU_REG_SHORTCUTS 1
29 #include "bochs.h"
30 #include "cpu.h"
31 #define LOG_THIS BX_CPU_THIS_PTR
33 #if BX_SUPPORT_X86_64==0
34 #define RAX EAX
35 #define RDX EDX
36 #endif
38 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MUL_EAXEdR(bxInstruction_c *i)
40 Bit32u op1_32 = EAX;
41 Bit32u op2_32 = BX_READ_32BIT_REG(i->rm());
43 Bit64u product_64 = ((Bit64u) op1_32) * ((Bit64u) op2_32);
44 Bit32u product_32l = GET32L(product_64);
45 Bit32u product_32h = GET32H(product_64);
47 /* now write product back to destination */
48 RAX = product_32l;
49 RDX = product_32h;
51 /* set EFLAGS */
52 SET_FLAGS_OSZAPC_LOGIC_32(product_32l);
53 if(product_32h != 0)
55 ASSERT_FLAGS_OxxxxC();
59 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IMUL_EAXEdR(bxInstruction_c *i)
61 Bit32s op1_32 = EAX;
62 Bit32s op2_32 = BX_READ_32BIT_REG(i->rm());
64 Bit64s product_64 = ((Bit64s) op1_32) * ((Bit64s) op2_32);
65 Bit32u product_32l = GET32L(product_64);
66 Bit32u product_32h = GET32H(product_64);
68 /* now write product back to destination */
69 RAX = product_32l;
70 RDX = product_32h;
72 /* set eflags:
73 * IMUL r/m32: condition for clearing CF & OF:
74 * EDX:EAX = sign-extend of EAX
76 SET_FLAGS_OSZAPC_LOGIC_32(product_32l);
77 if(product_64 != (Bit32s)product_64)
79 ASSERT_FLAGS_OxxxxC();
83 void BX_CPP_AttrRegparmN(1) BX_CPU_C::DIV_EAXEdR(bxInstruction_c *i)
85 Bit32u op2_32 = BX_READ_32BIT_REG(i->rm());
86 if (op2_32 == 0) {
87 exception(BX_DE_EXCEPTION, 0, 0);
90 Bit64u op1_64 = (((Bit64u) EDX) << 32) + ((Bit64u) EAX);
92 Bit64u quotient_64 = op1_64 / op2_32;
93 Bit32u remainder_32 = (Bit32u) (op1_64 % op2_32);
94 Bit32u quotient_32l = (Bit32u) (quotient_64 & 0xFFFFFFFF);
96 if (quotient_64 != quotient_32l)
98 exception(BX_DE_EXCEPTION, 0, 0);
101 /* set EFLAGS:
102 * DIV affects the following flags: O,S,Z,A,P,C are undefined
105 /* now write quotient back to destination */
106 RAX = quotient_32l;
107 RDX = remainder_32;
110 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IDIV_EAXEdR(bxInstruction_c *i)
112 Bit64s op1_64 = (((Bit64u) EDX) << 32) | ((Bit64u) EAX);
114 /* check MIN_INT case */
115 if (op1_64 == ((Bit64s)BX_CONST64(0x8000000000000000)))
116 exception(BX_DE_EXCEPTION, 0, 0);
118 Bit32s op2_32 = BX_READ_32BIT_REG(i->rm());
120 if (op2_32 == 0)
121 exception(BX_DE_EXCEPTION, 0, 0);
123 Bit64s quotient_64 = op1_64 / op2_32;
124 Bit32s remainder_32 = (Bit32s) (op1_64 % op2_32);
125 Bit32s quotient_32l = (Bit32s) (quotient_64 & 0xFFFFFFFF);
127 if (quotient_64 != quotient_32l)
129 exception(BX_DE_EXCEPTION, 0, 0);
132 /* set EFLAGS:
133 * IDIV affects the following flags: O,S,Z,A,P,C are undefined
136 /* now write quotient back to destination */
137 RAX = quotient_32l;
138 RDX = remainder_32;
141 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IMUL_GdEdIdR(bxInstruction_c *i)
143 Bit32s op2_32 = BX_READ_32BIT_REG(i->rm());
144 Bit32s op3_32 = i->Id();
146 Bit64s product_64 = ((Bit64s) op2_32) * ((Bit64s) op3_32);
147 Bit32u product_32 = (Bit32u)(product_64 & 0xFFFFFFFF);
149 /* now write product back to destination */
150 BX_WRITE_32BIT_REGZ(i->nnn(), product_32);
152 /* set eflags:
153 * IMUL r32,r/m32,imm32: condition for clearing CF & OF:
154 * result exactly fits within r32
156 SET_FLAGS_OSZAPC_LOGIC_32(product_32);
157 if(product_64 != (Bit32s) product_64)
159 ASSERT_FLAGS_OxxxxC();
163 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IMUL_GdEdR(bxInstruction_c *i)
165 Bit32s op1_32 = BX_READ_32BIT_REG(i->nnn());
166 Bit32s op2_32 = BX_READ_32BIT_REG(i->rm());
168 Bit64s product_64 = ((Bit64s) op1_32) * ((Bit64s) op2_32);
169 Bit32u product_32 = (Bit32u)(product_64 & 0xFFFFFFFF);
171 /* now write product back to destination */
172 BX_WRITE_32BIT_REGZ(i->nnn(), product_32);
174 /* set eflags:
175 * IMUL r32,r/m32: condition for clearing CF & OF:
176 * result exactly fits within r32
178 SET_FLAGS_OSZAPC_LOGIC_32(product_32);
179 if(product_64 != (Bit32s) product_64)
181 ASSERT_FLAGS_OxxxxC();