From 8ca39037e54af57baaa1950dbdc499ad1fc93d13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomek=20Sowi=C5=84ski?= Date: Mon, 17 Jun 2024 14:21:03 +0200 Subject: [PATCH] Classify stack arguments as single segment --- src/coreclr/jit/targetriscv64.cpp | 40 ++++++++++++++++++------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/coreclr/jit/targetriscv64.cpp b/src/coreclr/jit/targetriscv64.cpp index ea4c99872b7949..4df767d8cbfcc2 100644 --- a/src/coreclr/jit/targetriscv64.cpp +++ b/src/coreclr/jit/targetriscv64.cpp @@ -138,32 +138,38 @@ ABIPassingInformation RiscV64Classifier::Classify(Compiler* comp, else { // Integer calling convention - auto passSlot = [this](unsigned offset, unsigned size) -> ABIPassingSegment { + auto passOnStack = [this](unsigned offset, unsigned size) -> ABIPassingSegment { assert(size > 0); - assert(size <= TARGET_POINTER_SIZE); - if (m_intRegs.Count() > 0) + assert(size <= 2 * TARGET_POINTER_SIZE); + assert((m_stackArgSize % TARGET_POINTER_SIZE) == 0); + ABIPassingSegment seg = ABIPassingSegment::OnStack(m_stackArgSize, offset, size); + m_stackArgSize += (size > TARGET_POINTER_SIZE) ? (2 * TARGET_POINTER_SIZE) : TARGET_POINTER_SIZE; + return seg; + }; + + if (m_intRegs.Count() > 0) + { + if (passedSize <= TARGET_POINTER_SIZE) { - return ABIPassingSegment::InRegister(m_intRegs.Dequeue(), offset, size); + ABIPassingSegment seg = ABIPassingSegment::InRegister(m_intRegs.Dequeue(), 0, passedSize); + return ABIPassingInformation::FromSegment(comp, seg); } else { - assert((m_stackArgSize % TARGET_POINTER_SIZE) == 0); - ABIPassingSegment seg = ABIPassingSegment::OnStack(m_stackArgSize, offset, size); - m_stackArgSize += TARGET_POINTER_SIZE; - return seg; + assert(varTypeIsStruct(type)); + unsigned int tailSize = passedSize - TARGET_POINTER_SIZE; + + ABIPassingSegment head = ABIPassingSegment::InRegister(m_intRegs.Dequeue(), 0, TARGET_POINTER_SIZE); + ABIPassingSegment tail = + (m_intRegs.Count() > 0) + ? ABIPassingSegment::InRegister(m_intRegs.Dequeue(), TARGET_POINTER_SIZE, tailSize) + : passOnStack(TARGET_POINTER_SIZE, tailSize); + return {2, new (comp, CMK_ABI) ABIPassingSegment[2]{head, tail}}; } - }; - - if (passedSize <= TARGET_POINTER_SIZE) - { - return ABIPassingInformation::FromSegment(comp, passSlot(0, passedSize)); } else { - assert(varTypeIsStruct(type)); - return {2, new (comp, CMK_ABI) - ABIPassingSegment[2]{passSlot(0, TARGET_POINTER_SIZE), - passSlot(TARGET_POINTER_SIZE, passedSize - TARGET_POINTER_SIZE)}}; + return ABIPassingInformation::FromSegment(comp, passOnStack(0, passedSize)); } } }