PCem
view src/x86_ops_mul.h @ 163:b7ff0dbb7baf
Fixed incorrect flags on some versions of IMUL.
| author | TomW |
|---|---|
| date | Sat Sep 27 12:13:46 2014 +0100 |
| parents | 9c201151bb4b |
| children | 1dda97300a32 |
line source
1 static int opIMUL_w_iw_a16(uint32_t fetchdat)
2 {
3 uint32_t templ;
4 int16_t tempw, tempw2;
6 fetch_ea_16(fetchdat);
8 tempw = geteaw(); if (abrt) return 0;
9 tempw2 = getword(); if (abrt) return 0;
11 templ = ((int)tempw) * ((int)tempw2);
12 flags_rebuild();
13 if ((templ >> 16) != 0 && (templ >> 16) != 0xffff) flags |= C_FLAG | V_FLAG;
14 else flags &= ~(C_FLAG | V_FLAG);
15 regs[reg].w = templ & 0xffff;
17 cycles -= (mod == 3) ? 14 : 17;
18 return 0;
19 }
20 static int opIMUL_w_iw_a32(uint32_t fetchdat)
21 {
22 uint32_t templ;
23 int16_t tempw, tempw2;
25 fetch_ea_32(fetchdat);
27 tempw = geteaw(); if (abrt) return 0;
28 tempw2 = getword(); if (abrt) return 0;
30 templ = ((int)tempw) * ((int)tempw2);
31 flags_rebuild();
32 if ((templ >> 16) != 0 && (templ >> 16) != 0xffff) flags |= C_FLAG | V_FLAG;
33 else flags &= ~(C_FLAG | V_FLAG);
34 regs[reg].w = templ & 0xffff;
36 cycles -= (mod == 3) ? 14 : 17;
37 return 0;
38 }
40 static int opIMUL_l_il_a16(uint32_t fetchdat)
41 {
42 int64_t temp64;
43 int32_t templ, templ2;
45 fetch_ea_16(fetchdat);
47 templ = geteal(); if (abrt) return 0;
48 templ2 = getlong(); if (abrt) return 0;
50 temp64 = ((int64_t)templ) * ((int64_t)templ2);
51 flags_rebuild();
52 if ((temp64 >> 32) != 0 && (temp64 >> 32) != 0xffffffff) flags |= C_FLAG | V_FLAG;
53 else flags &= ~(C_FLAG | V_FLAG);
54 regs[reg].l = temp64 & 0xffffffff;
56 cycles-=25;
57 return 0;
58 }
59 static int opIMUL_l_il_a32(uint32_t fetchdat)
60 {
61 int64_t temp64;
62 int32_t templ, templ2;
64 fetch_ea_32(fetchdat);
66 templ = geteal(); if (abrt) return 0;
67 templ2 = getlong(); if (abrt) return 0;
69 temp64 = ((int64_t)templ) * ((int64_t)templ2);
70 flags_rebuild();
71 if ((temp64 >> 32) != 0 && (temp64 >> 32) != 0xffffffff) flags |= C_FLAG | V_FLAG;
72 else flags &= ~(C_FLAG | V_FLAG);
73 regs[reg].l = temp64 & 0xffffffff;
75 cycles-=25;
76 return 0;
77 }
79 static int opIMUL_w_ib_a16(uint32_t fetchdat)
80 {
81 uint32_t templ;
82 int16_t tempw, tempw2;
84 fetch_ea_16(fetchdat);
86 tempw = geteaw(); if (abrt) return 0;
87 tempw2 = getbyte(); if (abrt) return 0;
88 if (tempw2 & 0x80) tempw2 |= 0xff00;
90 templ = ((int)tempw) * ((int)tempw2);
91 flags_rebuild();
92 if ((templ >> 16) != 0 && ((templ >> 16) & 0xffff) != 0xffff) flags |= C_FLAG | V_FLAG;
93 else flags &= ~(C_FLAG | V_FLAG);
94 regs[reg].w = templ & 0xffff;
96 cycles -= (mod == 3) ? 14 : 17;
97 return 0;
98 }
99 static int opIMUL_w_ib_a32(uint32_t fetchdat)
100 {
101 uint32_t templ;
102 int16_t tempw, tempw2;
104 fetch_ea_32(fetchdat);
106 tempw = geteaw(); if (abrt) return 0;
107 tempw2 = getbyte(); if (abrt) return 0;
108 if (tempw2 & 0x80) tempw2 |= 0xff00;
110 templ = ((int)tempw) * ((int)tempw2);
111 flags_rebuild();
112 if ((templ >> 16) != 0 && ((templ >> 16) & 0xffff) != 0xffff) flags |= C_FLAG | V_FLAG;
113 else flags &= ~(C_FLAG | V_FLAG);
114 regs[reg].w = templ & 0xffff;
116 cycles -= (mod == 3) ? 14 : 17;
117 return 0;
118 }
120 static int opIMUL_l_ib_a16(uint32_t fetchdat)
121 {
122 uint64_t temp64;
123 int32_t templ, templ2;
125 fetch_ea_16(fetchdat);
126 templ = geteal(); if (abrt) return 0;
127 templ2 = getbyte(); if (abrt) return 0;
128 if (templ2 & 0x80) templ2 |= 0xffffff00;
130 temp64 = ((int64_t)templ)*((int64_t)templ2);
131 flags_rebuild();
132 if ((temp64 >> 32) != 0 && (temp64 >> 32) != 0xffffffff) flags |= C_FLAG | V_FLAG;
133 else flags &= ~(C_FLAG | V_FLAG);
134 regs[reg].l = temp64 & 0xffffffff;
136 cycles -= 20;
137 return 0;
138 }
139 static int opIMUL_l_ib_a32(uint32_t fetchdat)
140 {
141 uint64_t temp64;
142 int32_t templ, templ2;
144 fetch_ea_32(fetchdat);
145 templ = geteal(); if (abrt) return 0;
146 templ2 = getbyte(); if (abrt) return 0;
147 if (templ2 & 0x80) templ2 |= 0xffffff00;
149 temp64 = ((int64_t)templ)*((int64_t)templ2);
150 flags_rebuild();
151 if ((temp64 >> 32) != 0 && (temp64 >> 32) != 0xffffffff) flags |= C_FLAG | V_FLAG;
152 else flags &= ~(C_FLAG | V_FLAG);
153 regs[reg].l = temp64 & 0xffffffff;
155 cycles -= 20;
156 return 0;
157 }
161 static int opIMUL_w_w_a16(uint32_t fetchdat)
162 {
163 uint32_t templ;
165 fetch_ea_16(fetchdat);
166 templ = (int32_t)(int16_t)regs[reg].w * (int32_t)(int16_t)geteaw();
167 if (abrt) return 0;
168 regs[reg].w = templ & 0xFFFF;
169 flags_rebuild();
170 if ((templ >> 16) && (templ >> 16) != 0xFFFF) flags |= C_FLAG | V_FLAG;
171 else flags &= ~(C_FLAG | V_FLAG);
173 cycles -= 18;
174 return 0;
175 }
176 static int opIMUL_w_w_a32(uint32_t fetchdat)
177 {
178 uint32_t templ;
180 fetch_ea_32(fetchdat);
181 templ = (int32_t)(int16_t)regs[reg].w * (int32_t)(int16_t)geteaw();
182 if (abrt) return 0;
183 regs[reg].w = templ & 0xFFFF;
184 flags_rebuild();
185 if ((templ >> 16) && (templ >> 16) != 0xFFFF) flags |= C_FLAG | V_FLAG;
186 else flags &= ~(C_FLAG | V_FLAG);
188 cycles -= 18;
189 return 0;
190 }
192 static int opIMUL_l_l_a16(uint32_t fetchdat)
193 {
194 uint64_t temp64;
196 fetch_ea_16(fetchdat);
197 temp64 = (int64_t)(int32_t)regs[reg].l * (int64_t)(int32_t)geteal();
198 if (abrt) return 0;
199 regs[reg].l = temp64 & 0xFFFFFFFF;
200 flags_rebuild();
201 if ((temp64 >> 32) && (temp64 >> 32) != 0xFFFFFFFF) flags |= C_FLAG | V_FLAG;
202 else flags &= ~(C_FLAG | V_FLAG);
204 cycles -= 30;
205 return 0;
206 }
207 static int opIMUL_l_l_a32(uint32_t fetchdat)
208 {
209 uint64_t temp64;
211 fetch_ea_32(fetchdat);
212 temp64 = (int64_t)(int32_t)regs[reg].l * (int64_t)(int32_t)geteal();
213 if (abrt) return 0;
214 regs[reg].l = temp64 & 0xFFFFFFFF;
215 flags_rebuild();
216 if ((temp64 >> 32) && (temp64 >> 32) != 0xFFFFFFFF) flags |= C_FLAG | V_FLAG;
217 else flags &= ~(C_FLAG | V_FLAG);
219 cycles -= 30;
220 return 0;
221 }
