| 250 | } |
| 251 | |
| 252 | void OpDispatchBuilder::FDIV(OpcodeArgs, IR::OpSize Width, bool Integer, bool Reverse, OpDispatchBuilder::OpResult ResInST0) { |
| 253 | if (Op->Src[0].IsNone()) { |
| 254 | const uint8_t Offset = Op->OP & 7; |
| 255 | const uint8_t St0 = 0; |
| 256 | const uint8_t Result = (ResInST0 == OpResult::RES_STI) ? Offset : St0; |
| 257 | |
| 258 | if (Reverse ^ (ResInST0 == OpResult::RES_STI)) { |
| 259 | _F80DivStack(Result, Offset, St0); |
| 260 | } else { |
| 261 | _F80DivStack(Result, St0, Offset); |
| 262 | } |
| 263 | |
| 264 | if (Op->TableInfo->Flags & X86Tables::InstFlags::FLAGS_POP) { |
| 265 | _PopStackDestroy(); |
| 266 | } |
| 267 | return; |
| 268 | } |
| 269 | |
| 270 | LOGMAN_THROW_A_FMT(Width != OpSize::f80Bit, "No 80-bit floats from memory"); |
| 271 | // We have one memory argument |
| 272 | Ref arg {}; |
| 273 | if (Integer) { |
| 274 | arg = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags); |
| 275 | arg = _F80CVTToInt(arg, Width); |
| 276 | } else { |
| 277 | arg = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags); |
| 278 | arg = _F80CVTTo(arg, Width); |
| 279 | } |
| 280 | |
| 281 | // top of stack is at offset zero |
| 282 | if (Reverse) { |
| 283 | _F80DivRValue(arg, 0); |
| 284 | } else { |
| 285 | _F80DivValue(0, arg); |
| 286 | } |
| 287 | |
| 288 | if (Op->TableInfo->Flags & X86Tables::InstFlags::FLAGS_POP) { |
| 289 | _PopStackDestroy(); |
| 290 | } |
| 291 | } |
| 292 | |
| 293 | void OpDispatchBuilder::FSUB(OpcodeArgs, IR::OpSize Width, bool Integer, bool Reverse, OpDispatchBuilder::OpResult ResInST0) { |
| 294 | if (Op->Src[0].IsNone()) { |