1 /////////////////////////////////////////////////////////////////////////
2 // $Id: mult16.cc 13466 2018-02-16 07:57:32Z sshwarts $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 //  Copyright (C) 2001-2018  The Bochs Project
6 //
7 //  This library is free software; you can redistribute it and/or
8 //  modify it under the terms of the GNU Lesser General Public
9 //  License as published by the Free Software Foundation; either
10 //  version 2 of the License, or (at your option) any later version.
11 //
12 //  This library is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 //  Lesser General Public License for more details.
16 //
17 //  You should have received a copy of the GNU Lesser General Public
18 //  License along with this library; if not, write to the Free Software
19 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA
20 /////////////////////////////////////////////////////////////////////////
21 
22 #define NEED_CPU_REG_SHORTCUTS 1
23 #include "bochs.h"
24 #include "cpu.h"
25 #define LOG_THIS BX_CPU_THIS_PTR
26 
MUL_AXEwR(bxInstruction_c * i)27 void BX_CPP_AttrRegparmN(1) BX_CPU_C::MUL_AXEwR(bxInstruction_c *i)
28 {
29   Bit16u op1_16 = AX;
30   Bit16u op2_16 = BX_READ_16BIT_REG(i->src());
31 
32   Bit32u product_32  = ((Bit32u) op1_16) * ((Bit32u) op2_16);
33   Bit16u product_16l = (product_32 & 0xFFFF);
34   Bit16u product_16h =  product_32 >> 16;
35 
36   /* now write product back to destination */
37   AX = product_16l;
38   DX = product_16h;
39 
40   /* set EFLAGS */
41   SET_FLAGS_OSZAPC_LOGIC_16(product_16l);
42   if(product_16h != 0)
43   {
44     BX_CPU_THIS_PTR oszapc.assert_flags_OxxxxC();
45   }
46 
47   BX_NEXT_INSTR(i);
48 }
49 
IMUL_AXEwR(bxInstruction_c * i)50 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IMUL_AXEwR(bxInstruction_c *i)
51 {
52   Bit16s op1_16 = AX;
53   Bit16s op2_16 = BX_READ_16BIT_REG(i->src());
54 
55   Bit32s product_32  = ((Bit32s) op1_16) * ((Bit32s) op2_16);
56   Bit16u product_16l = (product_32 & 0xFFFF);
57   Bit16u product_16h = product_32 >> 16;
58 
59   /* now write product back to destination */
60   AX = product_16l;
61   DX = product_16h;
62 
63   /* set eflags:
64    * IMUL r/m16: condition for clearing CF & OF:
65    *   DX:AX = sign-extend of AX
66    */
67   SET_FLAGS_OSZAPC_LOGIC_16(product_16l);
68   if(product_32 != (Bit16s)product_32)
69   {
70     BX_CPU_THIS_PTR oszapc.assert_flags_OxxxxC();
71   }
72 
73   BX_NEXT_INSTR(i);
74 }
75 
DIV_AXEwR(bxInstruction_c * i)76 void BX_CPP_AttrRegparmN(1) BX_CPU_C::DIV_AXEwR(bxInstruction_c *i)
77 {
78   Bit16u op2_16 = BX_READ_16BIT_REG(i->src());
79   if (op2_16 == 0)
80     exception(BX_DE_EXCEPTION, 0);
81 
82   Bit32u op1_32 = (((Bit32u) DX) << 16) | ((Bit32u) AX);
83 
84   Bit32u quotient_32  = op1_32 / op2_16;
85   Bit16u remainder_16 = op1_32 % op2_16;
86   Bit16u quotient_16l = quotient_32 & 0xFFFF;
87 
88   if (quotient_32 != quotient_16l)
89     exception(BX_DE_EXCEPTION, 0);
90 
91   /* now write quotient back to destination */
92   AX = quotient_16l;
93   DX = remainder_16;
94 
95   BX_NEXT_INSTR(i);
96 }
97 
IDIV_AXEwR(bxInstruction_c * i)98 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IDIV_AXEwR(bxInstruction_c *i)
99 {
100   Bit32s op1_32 = ((((Bit32u) DX) << 16) | ((Bit32u) AX));
101 
102   /* check MIN_INT case */
103   if (op1_32 == ((Bit32s)0x80000000))
104     exception(BX_DE_EXCEPTION, 0);
105 
106   Bit16s op2_16 = BX_READ_16BIT_REG(i->src());
107 
108   if (op2_16 == 0)
109     exception(BX_DE_EXCEPTION, 0);
110 
111   Bit32s quotient_32  = op1_32 / op2_16;
112   Bit16s remainder_16 = op1_32 % op2_16;
113   Bit16s quotient_16l = quotient_32 & 0xFFFF;
114 
115   if (quotient_32 != quotient_16l)
116     exception(BX_DE_EXCEPTION, 0);
117 
118   /* now write quotient back to destination */
119   AX = quotient_16l;
120   DX = remainder_16;
121 
122   BX_NEXT_INSTR(i);
123 }
124 
IMUL_GwEwIwR(bxInstruction_c * i)125 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IMUL_GwEwIwR(bxInstruction_c *i)
126 {
127   Bit16s op2_16 = BX_READ_16BIT_REG(i->src());
128   Bit16s op3_16 = i->Iw();
129 
130   Bit32s product_32  = op2_16 * op3_16;
131   Bit16u product_16 = (product_32 & 0xFFFF);
132 
133   /* now write product back to destination */
134   BX_WRITE_16BIT_REG(i->dst(), product_16);
135 
136   /* set eflags:
137    * IMUL r16,r/m16,imm16: condition for clearing CF & OF:
138    *   result exactly fits within r16
139    */
140   SET_FLAGS_OSZAPC_LOGIC_16(product_16);
141   if(product_32 != (Bit16s) product_32)
142   {
143     BX_CPU_THIS_PTR oszapc.assert_flags_OxxxxC();
144   }
145 
146   BX_NEXT_INSTR(i);
147 }
148 
IMUL_GwEwR(bxInstruction_c * i)149 void BX_CPP_AttrRegparmN(1) BX_CPU_C::IMUL_GwEwR(bxInstruction_c *i)
150 {
151   Bit16s op1_16 = BX_READ_16BIT_REG(i->dst());
152   Bit16s op2_16 = BX_READ_16BIT_REG(i->src());
153 
154   Bit32s product_32 = op1_16 * op2_16;
155   Bit16u product_16 = (product_32 & 0xFFFF);
156 
157   /* now write product back to destination */
158   BX_WRITE_16BIT_REG(i->dst(), product_16);
159 
160   /* set eflags:
161    * IMUL r16,r/m16: condition for clearing CF & OF:
162    *   result exactly fits within r16
163    */
164   SET_FLAGS_OSZAPC_LOGIC_16(product_16);
165   if(product_32 != (Bit16s) product_32)
166   {
167     BX_CPU_THIS_PTR oszapc.assert_flags_OxxxxC();
168   }
169 
170   BX_NEXT_INSTR(i);
171 }
172