| 3983 | } |
| 3984 | |
| 3985 | BeMCOperand BeMCContext::AllocRelativeVirtualReg(BeType* type, const BeMCOperand& relTo, const BeMCOperand& relOffset, int relScale) |
| 3986 | { |
| 3987 | if (!relTo.IsVRegAny()) |
| 3988 | { |
| 3989 | auto relToType = GetType(relTo); |
| 3990 | auto tempRelTo = AllocVirtualReg(relToType, 1); |
| 3991 | CreateDefineVReg(tempRelTo); |
| 3992 | AllocInst(BeMCInstKind_Mov, tempRelTo, relTo); |
| 3993 | tempRelTo.mKind = BeMCOperandKind_VReg; |
| 3994 | return AllocRelativeVirtualReg(type, tempRelTo, relOffset, relScale); |
| 3995 | } |
| 3996 | |
| 3997 | BEMC_ASSERT(relTo.IsVRegAny()); |
| 3998 | auto relToVRegInfo = GetVRegInfo(relTo); |
| 3999 | |
| 4000 | if ((relToVRegInfo->mRelTo) && (relToVRegInfo->mRelOffsetScale == 1) && (relToVRegInfo->mRelOffset.IsImmediate()) && |
| 4001 | (relOffset.IsImmediate()) && (relScale == 1)) |
| 4002 | { |
| 4003 | if (relTo.mKind == BeMCOperandKind_VReg) |
| 4004 | { |
| 4005 | int offset = (int)relOffset.mImmediate; |
| 4006 | if (relToVRegInfo->mRelOffset) |
| 4007 | offset += relToVRegInfo->mRelOffset.mImmediate; |
| 4008 | return AllocRelativeVirtualReg(type, relToVRegInfo->mRelTo, GetImmediate(offset), 1); |
| 4009 | } |
| 4010 | } |
| 4011 | |
| 4012 | if ((relTo.mKind == BeMCOperandKind_VRegAddr) && (!relToVRegInfo->mRelOffset) && (relOffset.IsZero()) && (relScale == 1)) |
| 4013 | { |
| 4014 | auto vregInfo = GetVRegInfo(relTo); |
| 4015 | if (vregInfo->IsDirectRelToAny()) |
| 4016 | { |
| 4017 | if (vregInfo->mRelTo.mKind == BeMCOperandKind_Symbol) |
| 4018 | { |
| 4019 | return AllocRelativeVirtualReg(type, BeMCOperand::FromSymbolAddr(vregInfo->mRelTo.mSymbolIdx), BeMCOperand(), 1); |
| 4020 | } |
| 4021 | } |
| 4022 | } |
| 4023 | |
| 4024 | auto mcVReg = AllocVirtualReg(type); |
| 4025 | auto vregInfo = GetVRegInfo(mcVReg); |
| 4026 | vregInfo->mIsExpr = true; |
| 4027 | vregInfo->mRelTo = relTo; |
| 4028 | if (!relOffset.IsZero()) |
| 4029 | vregInfo->mRelOffset = relOffset; |
| 4030 | vregInfo->mRelOffsetScale = relScale; |
| 4031 | mcVReg.mKind = BeMCOperandKind_VReg; |
| 4032 | return mcVReg; |
| 4033 | } |
| 4034 | |
| 4035 | BeMCVRegInfo* BeMCContext::GetVRegInfo(const BeMCOperand& operand) |
| 4036 | { |
nothing calls this directly
no test coverage detected