summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/vm/arm64/stubs.cpp97
1 files changed, 75 insertions, 22 deletions
diff --git a/src/vm/arm64/stubs.cpp b/src/vm/arm64/stubs.cpp
index dd9e43a062..61c758c864 100644
--- a/src/vm/arm64/stubs.cpp
+++ b/src/vm/arm64/stubs.cpp
@@ -2222,9 +2222,18 @@ PCODE DynamicHelpers::CreateDictionaryLookupHelper(LoaderAllocator * pAllocator,
{
int indirectionsCodeSize = 0;
int indirectionsDataSize = 0;
- for (WORD i = 0; i < pLookup->indirections; i++) {
- indirectionsCodeSize += (pLookup->offsets[i] > 32760 ? 8 : 4); // if( > 32760) (8 code bytes) else 4 bytes for instruction with offset encoded in instruction
- indirectionsDataSize += (pLookup->offsets[i] > 32760 ? 4 : 0); // 4 bytes for storing indirection offset values
+ for (WORD i = 0; i < pLookup->indirections; i++)
+ {
+ if ((i == 0 && pLookup->indirectFirstOffset) || (i == 1 && pLookup->indirectSecondOffset))
+ {
+ indirectionsCodeSize += (pLookup->offsets[i] > 4095 ? 16 : 12); // if( > 4095) (16 code bytes) else 12 bytes for instruction with offset encoded in instruction
+ indirectionsDataSize += (pLookup->offsets[i] > 4095 ? 4 : 0); // 4 bytes for storing indirection offset values
+ }
+ else
+ {
+ indirectionsCodeSize += (pLookup->offsets[i] > 32760 ? 8 : 4); // if( > 32760) (8 code bytes) else 4 bytes for instruction with offset encoded in instruction
+ indirectionsDataSize += (pLookup->offsets[i] > 32760 ? 4 : 0); // 4 bytes for storing indirection offset values
+ }
}
int codeSize = indirectionsCodeSize;
@@ -2257,27 +2266,60 @@ PCODE DynamicHelpers::CreateDictionaryLookupHelper(LoaderAllocator * pAllocator,
uint dataOffset = codeSize - indirectionsDataSize - (pLookup->testForNull ? 4 : 0);
for (WORD i = 0; i < pLookup->indirections; i++)
{
- if(pLookup->offsets[i] > 32760)
+ if ((i == 0 && pLookup->indirectFirstOffset) || (i == 1 && pLookup->indirectSecondOffset))
{
- // ldr w10, [PC, #dataOffset]
- *(DWORD*)p = 0x1800000a | ((dataOffset>>2)<<5);
+ if(pLookup->offsets[i] > 4095)
+ {
+ // ldr w10, [PC, #dataOffset]
+ *(DWORD*)p = 0x1800000a | ((dataOffset>>2)<<5);
+ p += 4;
+ // add x0, x0, x10
+ *(DWORD*)p = 0x8b0a0000;
+ p += 4;
+
+ // move to next indirection offset data
+ dataOffset = dataOffset - 16 + 4; // subtract 16 as we have moved PC by 16 and add 4 as next data is at 4 bytes from previous data
+ }
+ else
+ {
+ // add x0, #(pLookup->offsets[i])
+ *(DWORD*)p = 0x91000000 | (((UINT32)pLookup->offsets[i])<<10);
+ p += 4;
+
+ dataOffset -= 12; // subtract 12 as we have moved PC by 12
+ }
+
+ // ldr x10, [x0]
+ *(DWORD*)p = 0xf940000a;
p += 4;
- // ldr x0, [x0, x10]
- *(DWORD*)p = 0xf86a6800;
+ // add x0, x0, x10
+ *(DWORD*)p = 0x8b0a0000;
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
{
- // offset must be 8 byte aligned
- _ASSERTE((pLookup->offsets[i] & 0x7) == 0);
-
- // ldr x0, [x0, #(pLookup->offsets[i])]
- *(DWORD*)p = 0xf9400000 | ( ((UINT32)pLookup->offsets[i]>>3) <<10 );
- p += 4;
- dataOffset -= 4; // subtract 4 as we have moved PC by 4
+ if(pLookup->offsets[i] > 32760)
+ {
+ // ldr w10, [PC, #dataOffset]
+ *(DWORD*)p = 0x1800000a | ((dataOffset>>2)<<5);
+ p += 4;
+ // ldr x0, [x0, x10]
+ *(DWORD*)p = 0xf86a6800;
+ 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
+ {
+ // offset must be 8 byte aligned
+ _ASSERTE((pLookup->offsets[i] & 0x7) == 0);
+
+ // ldr x0, [x0, #(pLookup->offsets[i])]
+ *(DWORD*)p = 0xf9400000 | ( ((UINT32)pLookup->offsets[i]>>3) <<10 );
+ p += 4;
+ dataOffset -= 4; // subtract 4 as we have moved PC by 4
+ }
}
}
@@ -2309,11 +2351,22 @@ PCODE DynamicHelpers::CreateDictionaryLookupHelper(LoaderAllocator * pAllocator,
// datalabel:
for (WORD i = 0; i < pLookup->indirections; i++)
{
- if(pLookup->offsets[i] > 32760)
+ if ((i == 0 && pLookup->indirectFirstOffset) || (i == 1 && pLookup->indirectSecondOffset))
{
- _ASSERTE((pLookup->offsets[i] & 0xffffffff00000000) == 0);
- *(UINT32*)p = (UINT32)pLookup->offsets[i];
- p += 4;
+ if(pLookup->offsets[i] > 4095)
+ {
+ *(UINT32*)p = (UINT32)pLookup->offsets[i];
+ p += 4;
+ }
+ }
+ else
+ {
+ if(pLookup->offsets[i] > 32760)
+ {
+ _ASSERTE((pLookup->offsets[i] & 0xffffffff00000000) == 0);
+ *(UINT32*)p = (UINT32)pLookup->offsets[i];
+ p += 4;
+ }
}
}