MCPcopy Create free account
hub / github.com/FEX-Emu/FEX / LoadSource_WithOpSize

Method LoadSource_WithOpSize

FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp:4221–4267  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

4219
4220
4221Ref OpDispatchBuilder::LoadSource_WithOpSize(RegisterClassType Class, const X86Tables::DecodedOp& Op, const X86Tables::DecodedOperand& Operand,
4222 IR::OpSize OpSize, uint32_t Flags, const LoadSourceOptions& Options) {
4223 auto [Align, LoadData, ForceLoad, AccessType, AllowUpperGarbage] = Options;
4224 AddressMode A = DecodeAddress(Op, Operand, AccessType, true /* IsLoad */);
4225
4226 if (Operand.IsGPR()) {
4227 const auto gpr = Operand.Data.GPR.GPR;
4228 const auto highIndex = Operand.Data.GPR.HighBits ? 1 : 0;
4229
4230 if (gpr >= FEXCore::X86State::REG_MM_0) {
4231 LOGMAN_THROW_A_FMT(OpSize == OpSize::i64Bit, "full");
4232
4233 A.Base = LoadContext(OpSize::i64Bit, MM0Index + gpr - FEXCore::X86State::REG_MM_0);
4234 } else if (gpr >= FEXCore::X86State::REG_XMM_0) {
4235 const auto gprIndex = gpr - X86State::REG_XMM_0;
4236
4237 // Load the full register size if it is a XMM register source.
4238 A.Base = LoadXMMRegister(gprIndex);
4239
4240 // Now extract the subregister if it was a partial load /smaller/ than SSE size
4241 // TODO: Instead of doing the VMov implicitly on load, hunt down all use cases that require partial loads and do it after load.
4242 // We don't have information here to know if the operation needs zero upper bits or can contain data.
4243 if (!AllowUpperGarbage && OpSize < OpSize::i128Bit) {
4244 A.Base = _VMov(OpSize, A.Base);
4245 }
4246 } else {
4247 A.Base = LoadGPRRegister(gpr, OpSize, highIndex ? 8 : 0, AllowUpperGarbage);
4248 }
4249 }
4250
4251 if ((IsOperandMem(Operand, true) && LoadData) || ForceLoad) {
4252 if (OpSize == OpSize::f80Bit) {
4253 Ref MemSrc = LoadEffectiveAddress(this, A, GetGPROpSize(), true);
4254 if (CTX->HostFeatures.SupportsSVE128 || CTX->HostFeatures.SupportsSVE256) {
4255 return _LoadMemX87SVEOptPredicate(OpSize::i128Bit, OpSize::i16Bit, MemSrc);
4256 } else {
4257 // For X87 extended doubles, Split the load.
4258 auto Res = _LoadMem(Class, OpSize::i64Bit, MemSrc, Align == OpSize::iInvalid ? OpSize : Align);
4259 return _VLoadVectorElement(OpSize::i128Bit, OpSize::i16Bit, Res, 4, Add(OpSize::i64Bit, MemSrc, 8));
4260 }
4261 }
4262
4263 return _LoadMemAutoTSO(Class, OpSize, A, Align == OpSize::iInvalid ? OpSize : Align);
4264 } else {
4265 return LoadEffectiveAddress(this, A, GetGPROpSize(), false, AllowUpperGarbage);
4266 }
4267}
4268
4269Ref OpDispatchBuilder::LoadGPRRegister(uint32_t GPR, IR::OpSize Size, uint8_t Offset, bool AllowUpperGarbage) {
4270 const auto GPRSize = GetGPROpSize();

Callers

nothing calls this directly

Calls 2

LoadEffectiveAddressFunction · 0.85
IsGPRMethod · 0.45

Tested by

no test coverage detected