| 216 | } |
| 217 | |
| 218 | void OpDispatchBuilder::FMUL(OpcodeArgs, IR::OpSize Width, bool Integer, OpDispatchBuilder::OpResult ResInST0) { |
| 219 | if (Op->Src[0].IsNone()) { // Implicit argument case |
| 220 | auto offset = Op->OP & 7; |
| 221 | auto st0 = 0; |
| 222 | if (ResInST0 == OpResult::RES_STI) { |
| 223 | _F80MulStack(offset, st0); |
| 224 | } else { |
| 225 | _F80MulStack(st0, offset); |
| 226 | } |
| 227 | if (Op->TableInfo->Flags & X86Tables::InstFlags::FLAGS_POP) { |
| 228 | _PopStackDestroy(); |
| 229 | } |
| 230 | return; |
| 231 | } |
| 232 | |
| 233 | LOGMAN_THROW_A_FMT(Width != OpSize::f80Bit, "No 80-bit floats from memory"); |
| 234 | // We have one memory argument |
| 235 | Ref arg {}; |
| 236 | if (Integer) { |
| 237 | arg = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags); |
| 238 | arg = _F80CVTToInt(arg, Width); |
| 239 | } else { |
| 240 | arg = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags); |
| 241 | arg = _F80CVTTo(arg, Width); |
| 242 | } |
| 243 | |
| 244 | // top of stack is at offset zero |
| 245 | _F80MulValue(0, arg); |
| 246 | |
| 247 | if (Op->TableInfo->Flags & X86Tables::InstFlags::FLAGS_POP) { |
| 248 | _PopStackDestroy(); |
| 249 | } |
| 250 | } |
| 251 | |
| 252 | void OpDispatchBuilder::FDIV(OpcodeArgs, IR::OpSize Width, bool Integer, bool Reverse, OpDispatchBuilder::OpResult ResInST0) { |
| 253 | if (Op->Src[0].IsNone()) { |