{
if (isValueType && ((floatFieldFlags & (uint)StructFloatFieldInfoFlags.STRUCT_HAS_ONE_FLOAT_MASK) != 0))
{
+ Debug.Assert(cFPRegs == 1);
if ((_loongarch64IdxFPReg < 8) && (_loongarch64IdxGenReg < 8))
{
_argLocDescForStructInRegs = new ArgLocDesc();
_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;
}
_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;
{
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
codeSize += 4; /* jilr */
}
- // the offset value of data.
+ // the offset value of data_label.
uint dataOffset = codeSize;
codeSize += indirectionsDataSize;
*(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;
}
// 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
{
// 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
}
}
// CALL HELPER:
if(pBLECall != NULL)
- *(DWORD*)pBLECall |= ((UINT32)(p - pBLECall) << 10);
+ *(DWORD*)pBLECall |= ((UINT32)(p - pBLECall) << 8);
// ori $a0,$t3,0
*(DWORD*)p = 0x038001e4;
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)