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

Method DecodeAddress

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

Source from the content-addressed store, hash-verified

4154}
4155
4156AddressMode OpDispatchBuilder::DecodeAddress(const X86Tables::DecodedOp& Op, const X86Tables::DecodedOperand& Operand,
4157 MemoryAccessType AccessType, bool IsLoad) {
4158 const auto GPRSize = GetGPROpSize();
4159
4160 AddressMode A {};
4161 A.Segment = GetSegment(Op->Flags);
4162 A.AddrSize = (Op->Flags & X86Tables::DecodeFlags::FLAG_ADDRESS_SIZE) != 0 ? (GPRSize >> 1) : GPRSize;
4163 A.NonTSO = AccessType == MemoryAccessType::NONTSO || AccessType == MemoryAccessType::STREAM;
4164
4165 if (Operand.IsLiteral()) {
4166 A.Offset = Operand.Literal();
4167
4168 if (Operand.Data.Literal.Size != 8 && IsLoad) {
4169 // zero extend
4170 uint64_t width = Operand.Data.Literal.Size * 8;
4171 A.Offset &= ((1ULL << width) - 1);
4172 }
4173 } else if (Operand.IsGPR()) {
4174 // Not an address, let the caller deal with it
4175 A.AddrSize = GPRSize;
4176 } else if (Operand.IsGPRDirect()) {
4177 A.Base = LoadGPRRegister(Operand.Data.GPR.GPR, GPRSize);
4178 A.NonTSO |= IsNonTSOReg(AccessType, Operand.Data.GPR.GPR);
4179 } else if (Operand.IsGPRIndirect()) {
4180 A.Base = LoadGPRRegister(Operand.Data.GPRIndirect.GPR, GPRSize);
4181 A.Offset = Operand.Data.GPRIndirect.Displacement;
4182 A.NonTSO |= IsNonTSOReg(AccessType, Operand.Data.GPRIndirect.GPR);
4183 } else if (Operand.IsRIPRelative()) {
4184 if (Is64BitMode) {
4185 A.Base = GetRelocatedPC(Op, Operand.Data.RIPLiteral.Value.s);
4186 } else {
4187 // 32bit this isn't RIP relative but instead absolute
4188 A.Offset = Operand.Data.RIPLiteral.Value.u;
4189 }
4190 } else if (Operand.IsSIB()) {
4191 const bool IsVSIB = IsLoad && ((Op->Flags & X86Tables::DecodeFlags::FLAG_VSIB_BYTE) != 0);
4192
4193 if (Operand.Data.SIB.Base != FEXCore::X86State::REG_INVALID) {
4194 A.Base = LoadGPRRegister(Operand.Data.SIB.Base, GPRSize);
4195 }
4196
4197 // NOTE: VSIB cannot have the index * scale portion calculated ahead of time,
4198 // since the index in this case is a vector. So, we can't just apply the scale
4199 // to it, since this needs to be applied to each element in the index register
4200 // after said element has been sign extended. So, we pass this through for the
4201 // instruction implementation to handle.
4202 //
4203 // What we do handle though, is the applying the displacement value to
4204 // the base register (if a base register is provided), since this is a
4205 // part of the address calculation that can be done ahead of time.
4206 if (!IsVSIB && Operand.Data.SIB.Index != FEXCore::X86State::REG_INVALID) {
4207 A.Index = LoadGPRRegister(Operand.Data.SIB.Index, GPRSize);
4208 A.IndexScale = Operand.Data.SIB.Scale;
4209 }
4210
4211 A.Offset = Operand.Data.SIB.Offset;
4212 A.NonTSO |= IsNonTSOReg(AccessType, Operand.Data.SIB.Base) || IsNonTSOReg(AccessType, Operand.Data.SIB.Index);
4213 } else {

Callers

nothing calls this directly

Calls 7

IsLiteralMethod · 0.80
LiteralMethod · 0.80
IsGPRDirectMethod · 0.80
IsGPRIndirectMethod · 0.80
IsRIPRelativeMethod · 0.80
IsSIBMethod · 0.80
IsGPRMethod · 0.45

Tested by

no test coverage detected