Skip to content

Commit

Permalink
[LoongArch64] amend the crossgen2 for LA64. (#75118)
Browse files Browse the repository at this point in the history
* [LoongArch64] amend the crossgen2 for LA64.

* amend the `ComputeReturnValueTreatment` for CR.
  • Loading branch information
shushanhf authored Sep 7, 2022
1 parent fdf505a commit ba065be
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1364,6 +1364,7 @@ public int GetNextOffset()
{
if (isValueType && ((floatFieldFlags & (uint)StructFloatFieldInfoFlags.STRUCT_HAS_ONE_FLOAT_MASK) != 0))
{
Debug.Assert(cFPRegs == 1);
if ((_loongarch64IdxFPReg < 8) && (_loongarch64IdxGenReg < 8))
{
_argLocDescForStructInRegs = new ArgLocDesc();
Expand All @@ -1381,15 +1382,23 @@ public int GetNextOffset()
_loongarch64IdxGenReg++;
return argOfsInner;
}
else
{
_loongarch64IdxFPReg = 8;
}
}
else if (cFPRegs + _loongarch64IdxFPReg <= 8)
{
// Each floating point register in the argument area is 8 bytes.
int argOfsInner = _transitionBlock.OffsetOfFloatArgumentRegisters + _loongarch64IdxFPReg * 8;
if (floatFieldFlags == (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_ONLY_TWO)
{
// struct with two single-float fields.
_argLocDescForStructInRegs = new ArgLocDesc();
_argLocDescForStructInRegs.m_idxFloatReg = _loongarch64IdxFPReg;
_argLocDescForStructInRegs.m_cFloatReg = 2;
Debug.Assert(cFPRegs == 2);
Debug.Assert(argSize == 8);

_hasArgLocDescForStructInRegs = true;
_argLocDescForStructInRegs.m_floatFlags = (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_ONLY_TWO;
}
_loongarch64IdxFPReg += cFPRegs;
return argOfsInner;
}
Expand Down Expand Up @@ -1418,11 +1427,6 @@ public int GetNextOffset()
_loongarch64OfsStack += 8;
return argOfsInner;
}
else
{
// Don't use reg slots for this. It will be passed purely on the stack arg space.
_loongarch64IdxGenReg = 8;
}
}

argOfs = _transitionBlock.OffsetOfArgs + _loongarch64OfsStack;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,12 @@ public void ComputeReturnValueTreatment(CorElementType type, TypeHandle thRetTyp
}

if (size <= EnregisteredReturnTypeIntegerMaxSize)
{
if (IsLoongArch64)
fpReturnSize = LoongArch64PassStructInRegister.GetLoongArch64PassStructInRegisterFlags(thRetType.GetRuntimeTypeHandle()) & 0xff;
break;
}

}
}

Expand Down
29 changes: 18 additions & 11 deletions src/coreclr/vm/loongarch64/stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1791,22 +1791,26 @@ PCODE DynamicHelpers::CreateDictionaryLookupHelper(LoaderAllocator * pAllocator,
{
int codeSize = 0;
int indirectionsDataSize = 0;
if (pLookup->sizeOffset != CORINFO_NO_SIZE_CHECK)
if (pLookup->testForNull || pLookup->sizeOffset != CORINFO_NO_SIZE_CHECK)
{
codeSize += (pLookup->sizeOffset > 2047 ? 8 : 4);
indirectionsDataSize += (pLookup->sizeOffset > 2047 ? 4 : 0);
codeSize += 12;
codeSize += 4;
}

for (WORD i = 0; i < pLookup->indirections; i++) {
_ASSERTE(pLookup->offsets[i] >= 0);
if (i == pLookup->indirections - 1 && pLookup->sizeOffset != CORINFO_NO_SIZE_CHECK)
{
codeSize += (pLookup->sizeOffset > 2047 ? 24 : 16);
indirectionsDataSize += (pLookup->sizeOffset > 2047 ? 4 : 0);
}

codeSize += (pLookup->offsets[i] > 2047 ? 8 : 4); // if( > 2047) (8 bytes) else 4 bytes for instructions.
indirectionsDataSize += (pLookup->offsets[i] > 2047 ? 4 : 0); // 4 bytes for storing indirection offset values
}

codeSize += indirectionsDataSize ? 4 : 0; // pcaddi

if(pLookup->testForNull)
if (pLookup->testForNull)
{
codeSize += 12; // ori-beq-jr

Expand All @@ -1821,7 +1825,7 @@ PCODE DynamicHelpers::CreateDictionaryLookupHelper(LoaderAllocator * pAllocator,
codeSize += 4; /* jilr */
}

// the offset value of data.
// the offset value of data_label.
uint dataOffset = codeSize;

codeSize += indirectionsDataSize;
Expand Down Expand Up @@ -1877,9 +1881,9 @@ PCODE DynamicHelpers::CreateDictionaryLookupHelper(LoaderAllocator * pAllocator,
*(DWORD*)p = 0x03800210 | (((UINT32)slotOffset & 0xfff) << 10); p += 4;
dataOffset -= 8;

// bge $t4,$t3, // CALL HELPER:
// bge $t4,$t5, // CALL HELPER:
pBLECall = p; // Offset filled later
*(DWORD*)p = 0x6400020f; p += 4;
*(DWORD*)p = 0x64000211; p += 4;
dataOffset -= 4;
}

Expand All @@ -1889,10 +1893,12 @@ PCODE DynamicHelpers::CreateDictionaryLookupHelper(LoaderAllocator * pAllocator,
// ld.wu $t4,$r21,0
*(DWORD*)p = 0x2a8002b0 | (dataOffset<<10);
p += 4;
dataOffset += 4;
// ldx.d $a0,$a0,$t4
*(DWORD*)p = 0x380c4084;
p += 4;

// move to next indirection offset data
dataOffset = dataOffset - 8 + 4; // subtract 8 as we have moved PC by 8 and add 4 as next data is at 4 bytes from previous data
}
else
{
Expand All @@ -1902,6 +1908,7 @@ PCODE DynamicHelpers::CreateDictionaryLookupHelper(LoaderAllocator * pAllocator,
// ld.d $a0,$a0,pLookup->offsets[i]
*(DWORD*)p = 0x28c00084 | ((pLookup->offsets[i] & 0xfff)<<10);
p += 4;
dataOffset -= 4; // subtract 4 as we have moved PC by 4
}
}

Expand All @@ -1925,7 +1932,7 @@ PCODE DynamicHelpers::CreateDictionaryLookupHelper(LoaderAllocator * pAllocator,

// CALL HELPER:
if(pBLECall != NULL)
*(DWORD*)pBLECall |= ((UINT32)(p - pBLECall) << 10);
*(DWORD*)pBLECall |= ((UINT32)(p - pBLECall) << 8);

// ori $a0,$t3,0
*(DWORD*)p = 0x038001e4;
Expand All @@ -1943,7 +1950,7 @@ PCODE DynamicHelpers::CreateDictionaryLookupHelper(LoaderAllocator * pAllocator,
EmitHelperWithArg(p, rxOffset, pAllocator, (TADDR)pArgs, helperAddress);
}

// datalabel:
// data_label:
for (WORD i = 0; i < pLookup->indirections; i++)
{
if (i == pLookup->indirections - 1 && pLookup->sizeOffset != CORINFO_NO_SIZE_CHECK && pLookup->sizeOffset > 2047)
Expand Down

0 comments on commit ba065be

Please sign in to comment.