Skip to content

Commit f203fa4

Browse files
committed
WIP
1 parent 6138978 commit f203fa4

22 files changed

+2309
-434
lines changed

arch/arm64/arch_arm64.cpp

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2648,6 +2648,209 @@ class Arm64CallingConvention : public CallingConvention
26482648

26492649

26502650
virtual uint32_t GetFloatReturnValueRegister() override { return REG_V0; }
2651+
2652+
2653+
ValueLocation GetReturnValueLocation(const ReturnValue& returnValue) override
2654+
{
2655+
if (returnValue.type->GetWidth() <= 8)
2656+
return Variable(RegisterVariableSourceType, 0, REG_X0);
2657+
2658+
if (returnValue.type->GetWidth() <= 16)
2659+
{
2660+
return ValueLocation({
2661+
ValueLocationComponent(Variable(RegisterVariableSourceType, 0, REG_X0), 0, 8),
2662+
ValueLocationComponent(
2663+
Variable(RegisterVariableSourceType, 0, REG_X1), 8, returnValue.type->GetWidth() - 8),
2664+
});
2665+
}
2666+
2667+
return ValueLocation({ValueLocationComponent(
2668+
Variable(RegisterVariableSourceType, 0, REG_X8), 0, returnValue.type->GetWidth(), true)});
2669+
}
2670+
2671+
2672+
virtual bool AreStackParametersNaturallyAligned()
2673+
{
2674+
return false;
2675+
}
2676+
2677+
2678+
vector<ValueLocation> GetParameterLocations(const std::optional<ValueLocation>& returnValue,
2679+
const vector<FunctionParameter>& params, const std::optional<set<uint32_t>>& permittedRegs) override
2680+
{
2681+
vector<ValueLocation> result;
2682+
result.reserve(params.size());
2683+
2684+
vector<uint32_t> intArgs = GetIntegerArgumentRegisters();
2685+
vector<uint32_t> floatArgs = GetFloatArgumentRegisters();
2686+
2687+
auto intArgIter = intArgs.begin();
2688+
auto floatArgIter = floatArgs.begin();
2689+
int64_t stackOffset = 0;
2690+
2691+
for (auto& param : params)
2692+
{
2693+
size_t width = param.type->GetWidth();
2694+
2695+
if (!param.defaultLocation)
2696+
{
2697+
// Parameter not storage in a normal location, use custom variable
2698+
result.push_back(param.location);
2699+
for (auto& component : param.location.components)
2700+
{
2701+
if (component.indirect)
2702+
continue;
2703+
2704+
if (component.variable.type == RegisterVariableSourceType)
2705+
{
2706+
// If non-default location matches the next register in the register parameter
2707+
// lists, advance the iterators. It may just be a type mismatch, and we still
2708+
// want to maintain the state for future parameters.
2709+
if (intArgIter != intArgs.end() && *intArgIter == component.variable.storage)
2710+
intArgIter++;
2711+
else if (floatArgIter != floatArgs.end() && *floatArgIter == component.variable.storage)
2712+
floatArgIter++;
2713+
}
2714+
else if (component.variable.type == StackVariableSourceType
2715+
&& component.variable.storage >= stackOffset)
2716+
{
2717+
// Adjust next automatic stack location to after this one
2718+
stackOffset = component.variable.storage;
2719+
if (width < 8)
2720+
width = 8;
2721+
else if ((width % 8) != 0)
2722+
width += 8 - (width % 8);
2723+
stackOffset += width;
2724+
}
2725+
}
2726+
continue;
2727+
}
2728+
2729+
bool indirect = false;
2730+
size_t finalWidth = width;
2731+
if (width > 16)
2732+
{
2733+
indirect = true;
2734+
finalWidth = 8;
2735+
}
2736+
2737+
if (finalWidth <= 8)
2738+
{
2739+
if (!indirect && param.type->IsFloat())
2740+
{
2741+
if (permittedRegs.has_value() && floatArgIter != floatArgs.end()
2742+
&& permittedRegs.value().count(*floatArgIter) == 0)
2743+
{
2744+
// Disallowed register parameter, start spilling to stack. This is used in calling
2745+
// conventions that place all variable argument parameters on the stack.
2746+
floatArgIter = floatArgs.end();
2747+
}
2748+
else if (floatArgIter != floatArgs.end())
2749+
{
2750+
BNRegisterInfo regInfo = GetArchitecture()->GetRegisterInfo(*floatArgIter);
2751+
if (finalWidth <= regInfo.size)
2752+
{
2753+
result.emplace_back(RegisterVariableSourceType, 0, *floatArgIter);
2754+
floatArgIter++;
2755+
continue;
2756+
}
2757+
}
2758+
}
2759+
else
2760+
{
2761+
if (permittedRegs.has_value() && intArgIter != intArgs.end()
2762+
&& permittedRegs.value().count(*intArgIter) == 0)
2763+
{
2764+
// Disallowed register parameter, start spilling to stack. This is used in calling
2765+
// conventions that place all variable argument parameters on the stack.
2766+
intArgIter = intArgs.end();
2767+
}
2768+
else if (intArgIter != intArgs.end())
2769+
{
2770+
BNRegisterInfo regInfo = GetArchitecture()->GetRegisterInfo(*intArgIter);
2771+
if (finalWidth <= regInfo.size)
2772+
{
2773+
if (indirect)
2774+
{
2775+
result.push_back(ValueLocation({ValueLocationComponent(
2776+
Variable(RegisterVariableSourceType, 0, *intArgIter), 0, width, true)}));
2777+
}
2778+
else
2779+
{
2780+
result.emplace_back(RegisterVariableSourceType, 0, *intArgIter);
2781+
}
2782+
intArgIter++;
2783+
continue;
2784+
}
2785+
}
2786+
}
2787+
}
2788+
else if (finalWidth <= 16)
2789+
{
2790+
if (permittedRegs.has_value() && intArgIter != intArgs.end()
2791+
&& permittedRegs.value().count(*intArgIter) == 0)
2792+
{
2793+
// Disallowed register parameter, start spilling to stack. This is used in calling
2794+
// conventions that place all variable argument parameters on the stack.
2795+
intArgIter = intArgs.end();
2796+
}
2797+
else if (intArgIter != intArgs.end())
2798+
{
2799+
uint32_t first = *intArgIter;
2800+
intArgIter++;
2801+
if (permittedRegs.has_value() && intArgIter != intArgs.end()
2802+
&& permittedRegs.value().count(*intArgIter) == 0)
2803+
{
2804+
// Disallowed register parameter, start spilling to stack. This is used in calling
2805+
// conventions that place all variable argument parameters on the stack.
2806+
intArgIter = intArgs.end();
2807+
}
2808+
else if (intArgIter != intArgs.end())
2809+
{
2810+
uint32_t second = *intArgIter;
2811+
intArgIter++;
2812+
result.push_back(
2813+
ValueLocation({ValueLocationComponent(Variable(RegisterVariableSourceType, 0, first), 0, 8),
2814+
ValueLocationComponent(
2815+
Variable(RegisterVariableSourceType, 0, second), 8, finalWidth - 8)}));
2816+
continue;
2817+
}
2818+
}
2819+
}
2820+
2821+
if (indirect)
2822+
{
2823+
result.push_back(ValueLocation(
2824+
{ValueLocationComponent(Variable(StackVariableSourceType, 0, stackOffset), 0, width, true)}));
2825+
}
2826+
else
2827+
{
2828+
result.emplace_back(StackVariableSourceType, 0, stackOffset);
2829+
}
2830+
2831+
if (AreStackParametersNaturallyAligned() && !indirect)
2832+
{
2833+
size_t align = param.type->GetAlignment();
2834+
if (align == 0)
2835+
align = 1;
2836+
if (finalWidth < align)
2837+
finalWidth = align;
2838+
else if (finalWidth % align != 0)
2839+
finalWidth += align - (finalWidth % align);
2840+
stackOffset += finalWidth;
2841+
}
2842+
else
2843+
{
2844+
if (finalWidth < 8)
2845+
finalWidth = 8;
2846+
else if ((finalWidth % 8) != 0)
2847+
finalWidth += 8 - (finalWidth % 8);
2848+
stackOffset += finalWidth;
2849+
}
2850+
}
2851+
2852+
return result;
2853+
}
26512854
};
26522855

26532856

@@ -2663,6 +2866,12 @@ class AppleArm64CallingConvention: public Arm64CallingConvention
26632866
{
26642867
return false;
26652868
}
2869+
2870+
2871+
virtual bool AreStackParametersNaturallyAligned() override
2872+
{
2873+
return true;
2874+
}
26662875
};
26672876

26682877

0 commit comments

Comments
 (0)