| 8 | namespace FEXCore::IR { |
| 9 | |
| 10 | Ref LoadEffectiveAddress(IREmitter* IREmit, AddressMode A, IR::OpSize GPRSize, bool AddSegmentBase, bool AllowUpperGarbage) { |
| 11 | Ref Tmp = A.Base; |
| 12 | |
| 13 | if (A.Offset) { |
| 14 | Tmp = Tmp ? IREmit->Add(GPRSize, Tmp, A.Offset) : IREmit->Constant(A.Offset); |
| 15 | } |
| 16 | |
| 17 | if (A.Index) { |
| 18 | if (A.IndexScale != 1) { |
| 19 | uint32_t Log2 = FEXCore::ilog2(A.IndexScale); |
| 20 | |
| 21 | if (Tmp) { |
| 22 | Tmp = IREmit->_AddShift(GPRSize, Tmp, A.Index, ShiftType::LSL, Log2); |
| 23 | } else { |
| 24 | Tmp = IREmit->_Lshl(GPRSize, A.Index, IREmit->Constant(Log2)); |
| 25 | } |
| 26 | } else { |
| 27 | Tmp = Tmp ? IREmit->Add(GPRSize, Tmp, A.Index) : A.Index; |
| 28 | } |
| 29 | } |
| 30 | |
| 31 | // For 64-bit AddrSize can be 32-bit or 64-bit |
| 32 | // For 32-bit AddrSize can be 32-bit or 16-bit |
| 33 | // |
| 34 | // If the AddrSize is not the GPRSize then we need to clear the upper bits. |
| 35 | if ((A.AddrSize < GPRSize) && !AllowUpperGarbage && Tmp) { |
| 36 | uint32_t Bits = IR::OpSizeAsBits(A.AddrSize); |
| 37 | |
| 38 | if (A.Base || A.Index) { |
| 39 | Tmp = IREmit->_Bfe(GPRSize, Bits, 0, Tmp); |
| 40 | } else if (A.Offset) { |
| 41 | uint64_t X = A.Offset; |
| 42 | X &= (1ull << Bits) - 1; |
| 43 | Tmp = IREmit->Constant(X); |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | if (A.Segment && AddSegmentBase) { |
| 48 | Tmp = Tmp ? IREmit->Add(GPRSize, Tmp, A.Segment) : A.Segment; |
| 49 | } |
| 50 | |
| 51 | return Tmp ?: IREmit->Constant(0); |
| 52 | } |
| 53 | |
| 54 | AddressMode SelectAddressMode(IREmitter* IREmit, AddressMode A, IR::OpSize GPRSize, bool HostSupportsTSOImm9, bool AtomicTSO, bool Vector, |
| 55 | IR::OpSize AccessSize) { |
no test coverage detected