1 /////////////////////////////////////////////////////////////////////////
2 // $Id: mult32.cc,v 1.31 2008/08/10 21:16:12 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (C) 2001 MandrakeSoft S.A.
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
31 #define LOG_THIS BX_CPU_THIS_PTR
33 #if BX_SUPPORT_X86_64==0
38 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MUL_EAXEdR(bxInstruction_c
*i
)
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 */
52 SET_FLAGS_OSZAPC_LOGIC_32(product_32l
);
55 ASSERT_FLAGS_OxxxxC();
59 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IMUL_EAXEdR(bxInstruction_c
*i
)
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 */
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());
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);
102 * DIV affects the following flags: O,S,Z,A,P,C are undefined
105 /* now write quotient back to destination */
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());
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);
133 * IDIV affects the following flags: O,S,Z,A,P,C are undefined
136 /* now write quotient back to destination */
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
);
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
);
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();