| 95 | } |
| 96 | |
| 97 | void OpDispatchBuilder::FILD(OpcodeArgs) { |
| 98 | const auto ReadWidth = OpSizeFromSrc(Op); |
| 99 | // Read from memory |
| 100 | Ref Data = LoadSource_WithOpSize(GPRClass, Op, Op->Src[0], ReadWidth, Op->Flags); |
| 101 | |
| 102 | // Sign extend to 64bits |
| 103 | if (ReadWidth != OpSize::i64Bit) { |
| 104 | Data = _Sbfe(OpSize::i64Bit, IR::OpSizeAsBits(ReadWidth), 0, Data); |
| 105 | } |
| 106 | |
| 107 | // We're about to clobber flags to grab the sign, so save NZCV. |
| 108 | SaveNZCV(); |
| 109 | |
| 110 | // Extract sign and make integer absolute |
| 111 | auto zero = Constant(0); |
| 112 | _SubNZCV(OpSize::i64Bit, Data, zero); |
| 113 | auto sign = _NZCVSelect(OpSize::i64Bit, CondClassType {COND_SLT}, Constant(0x8000), zero); |
| 114 | auto absolute = _Neg(OpSize::i64Bit, Data, CondClassType {COND_MI}); |
| 115 | |
| 116 | // left justify the absolute integer |
| 117 | auto shift = Sub(OpSize::i64Bit, Constant(63), _FindMSB(IR::OpSize::i64Bit, absolute)); |
| 118 | auto shifted = _Lshl(OpSize::i64Bit, absolute, shift); |
| 119 | |
| 120 | auto adjusted_exponent = Sub(OpSize::i64Bit, Constant(0x3fff + 63), shift); |
| 121 | auto zeroed_exponent = _Select(COND_EQ, absolute, zero, zero, adjusted_exponent); |
| 122 | auto upper = _Or(OpSize::i64Bit, sign, zeroed_exponent); |
| 123 | |
| 124 | Ref ConvertedData = _VLoadTwoGPRs(shifted, upper); |
| 125 | _PushStack(ConvertedData, Data, ReadWidth, false); |
| 126 | } |
| 127 | |
| 128 | void OpDispatchBuilder::FST(OpcodeArgs, IR::OpSize Width) { |
| 129 | const auto SourceSize = ReducedPrecisionMode ? OpSize::i64Bit : OpSize::i128Bit; |
nothing calls this directly
no test coverage detected