| 4832 | } |
| 4833 | |
| 4834 | void OpDispatchBuilder::CRC32(OpcodeArgs) { |
| 4835 | if (!CTX->HostFeatures.SupportsCRC) { |
| 4836 | UnimplementedOp(Op); |
| 4837 | return; |
| 4838 | } |
| 4839 | const auto GPRSize = GetGPROpSize(); |
| 4840 | |
| 4841 | // Destination GPR size is always 4 or 8 bytes depending on widening |
| 4842 | const auto DstSize = Op->Flags & FEXCore::X86Tables::DecodeFlags::FLAG_REX_WIDENING ? OpSize::i64Bit : OpSize::i32Bit; |
| 4843 | Ref Dest = LoadSource_WithOpSize(GPRClass, Op, Op->Dest, GPRSize, Op->Flags); |
| 4844 | |
| 4845 | // Incoming memory is 8, 16, 32, or 64 |
| 4846 | Ref Src {}; |
| 4847 | if (Op->Src[0].IsGPR()) { |
| 4848 | Src = LoadSource_WithOpSize(GPRClass, Op, Op->Src[0], GPRSize, Op->Flags); |
| 4849 | } else { |
| 4850 | Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, {.Align = OpSize::i8Bit}); |
| 4851 | } |
| 4852 | auto Result = _CRC32(Dest, Src, OpSizeFromSrc(Op)); |
| 4853 | StoreResult_WithOpSize(GPRClass, Op, Op->Dest, Result, DstSize, OpSize::iInvalid); |
| 4854 | } |
| 4855 | |
| 4856 | template<bool Reseed> |
| 4857 | void OpDispatchBuilder::RDRANDOp(OpcodeArgs) { |