Skip to content

Commit 172c65a

Browse files
committed
WIP
1 parent 6138978 commit 172c65a

22 files changed

+2263
-434
lines changed

arch/arm64/arch_arm64.cpp

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2648,6 +2648,189 @@ 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+
vector<ValueLocation> GetParameterLocations(const std::optional<ValueLocation>& returnValue,
2673+
const vector<FunctionParameter>& params, const std::optional<set<uint32_t>>& permittedRegs) override
2674+
{
2675+
vector<ValueLocation> result;
2676+
result.reserve(params.size());
2677+
2678+
vector<uint32_t> intArgs = GetIntegerArgumentRegisters();
2679+
vector<uint32_t> floatArgs = GetFloatArgumentRegisters();
2680+
2681+
auto intArgIter = intArgs.begin();
2682+
auto floatArgIter = floatArgs.begin();
2683+
int64_t stackOffset = 0;
2684+
2685+
for (auto& param : params)
2686+
{
2687+
size_t width = param.type->GetWidth();
2688+
2689+
if (!param.defaultLocation)
2690+
{
2691+
// Parameter not storage in a normal location, use custom variable
2692+
result.push_back(param.location);
2693+
for (auto& component : param.location.components)
2694+
{
2695+
if (component.indirect)
2696+
continue;
2697+
2698+
if (component.variable.type == RegisterVariableSourceType)
2699+
{
2700+
// If non-default location matches the next register in the register parameter
2701+
// lists, advance the iterators. It may just be a type mismatch, and we still
2702+
// want to maintain the state for future parameters.
2703+
if (intArgIter != intArgs.end() && *intArgIter == component.variable.storage)
2704+
intArgIter++;
2705+
else if (floatArgIter != floatArgs.end() && *floatArgIter == component.variable.storage)
2706+
floatArgIter++;
2707+
}
2708+
else if (component.variable.type == StackVariableSourceType
2709+
&& component.variable.storage >= stackOffset)
2710+
{
2711+
// Adjust next automatic stack location to after this one
2712+
stackOffset = component.variable.storage;
2713+
if (width < 8)
2714+
width = 8;
2715+
else if ((width % 8) != 0)
2716+
width += 8 - (width % 8);
2717+
stackOffset += width;
2718+
}
2719+
}
2720+
continue;
2721+
}
2722+
2723+
bool indirect = false;
2724+
size_t finalWidth = width;
2725+
if (width > 16)
2726+
{
2727+
indirect = true;
2728+
finalWidth = 8;
2729+
}
2730+
2731+
if (finalWidth <= 8)
2732+
{
2733+
if (!indirect && param.type->IsFloat())
2734+
{
2735+
if (permittedRegs.has_value() && floatArgIter != floatArgs.end()
2736+
&& permittedRegs.value().count(*floatArgIter) == 0)
2737+
{
2738+
// Disallowed register parameter, start spilling to stack. This is used in calling
2739+
// conventions that place all variable argument parameters on the stack.
2740+
floatArgIter = floatArgs.end();
2741+
}
2742+
else if (floatArgIter != floatArgs.end())
2743+
{
2744+
BNRegisterInfo regInfo = GetArchitecture()->GetRegisterInfo(*floatArgIter);
2745+
if (finalWidth <= regInfo.size)
2746+
{
2747+
result.emplace_back(RegisterVariableSourceType, 0, *floatArgIter);
2748+
floatArgIter++;
2749+
continue;
2750+
}
2751+
}
2752+
}
2753+
else
2754+
{
2755+
if (permittedRegs.has_value() && intArgIter != intArgs.end()
2756+
&& permittedRegs.value().count(*intArgIter) == 0)
2757+
{
2758+
// Disallowed register parameter, start spilling to stack. This is used in calling
2759+
// conventions that place all variable argument parameters on the stack.
2760+
intArgIter = intArgs.end();
2761+
}
2762+
else if (intArgIter != intArgs.end())
2763+
{
2764+
BNRegisterInfo regInfo = GetArchitecture()->GetRegisterInfo(*intArgIter);
2765+
if (finalWidth <= regInfo.size)
2766+
{
2767+
if (indirect)
2768+
{
2769+
result.push_back(ValueLocation({ValueLocationComponent(
2770+
Variable(RegisterVariableSourceType, 0, *intArgIter), 0, width, true)}));
2771+
}
2772+
else
2773+
{
2774+
result.emplace_back(RegisterVariableSourceType, 0, *intArgIter);
2775+
}
2776+
intArgIter++;
2777+
continue;
2778+
}
2779+
}
2780+
}
2781+
}
2782+
else if (finalWidth <= 16)
2783+
{
2784+
if (permittedRegs.has_value() && intArgIter != intArgs.end()
2785+
&& permittedRegs.value().count(*intArgIter) == 0)
2786+
{
2787+
// Disallowed register parameter, start spilling to stack. This is used in calling
2788+
// conventions that place all variable argument parameters on the stack.
2789+
intArgIter = intArgs.end();
2790+
}
2791+
else if (intArgIter != intArgs.end())
2792+
{
2793+
uint32_t first = *intArgIter;
2794+
intArgIter++;
2795+
if (permittedRegs.has_value() && intArgIter != intArgs.end()
2796+
&& permittedRegs.value().count(*intArgIter) == 0)
2797+
{
2798+
// Disallowed register parameter, start spilling to stack. This is used in calling
2799+
// conventions that place all variable argument parameters on the stack.
2800+
intArgIter = intArgs.end();
2801+
}
2802+
else if (intArgIter != intArgs.end())
2803+
{
2804+
uint32_t second = *intArgIter;
2805+
intArgIter++;
2806+
result.push_back(
2807+
ValueLocation({ValueLocationComponent(Variable(RegisterVariableSourceType, 0, first), 0, 8),
2808+
ValueLocationComponent(
2809+
Variable(RegisterVariableSourceType, 0, second), 8, finalWidth - 8)}));
2810+
continue;
2811+
}
2812+
}
2813+
}
2814+
2815+
if (indirect)
2816+
{
2817+
result.push_back(ValueLocation(
2818+
{ValueLocationComponent(Variable(StackVariableSourceType, 0, stackOffset), 0, width, true)}));
2819+
}
2820+
else
2821+
{
2822+
result.emplace_back(StackVariableSourceType, 0, stackOffset);
2823+
}
2824+
2825+
if (finalWidth < 8)
2826+
finalWidth = 8;
2827+
else if ((finalWidth % 8) != 0)
2828+
finalWidth += 8 - (finalWidth % 8);
2829+
stackOffset += finalWidth;
2830+
}
2831+
2832+
return result;
2833+
}
26512834
};
26522835

26532836

0 commit comments

Comments
 (0)