summaryrefslogtreecommitdiff
path: root/src/vm/arm
diff options
context:
space:
mode:
authorSujin Kim <sjsujin.kim@samsung.com>2017-10-17 22:33:51 +0900
committerJan Kotas <jkotas@microsoft.com>2017-10-17 06:33:51 -0700
commitd5f7e467d0ae1265370e18fdc17d5a55e8b45b99 (patch)
tree30ca11d93e417023316956e12538c66b0f929dfa /src/vm/arm
parentfe88586cf7da09f4e6a90461239262d8c7d8eb61 (diff)
downloadcoreclr-d5f7e467d0ae1265370e18fdc17d5a55e8b45b99.tar.gz
coreclr-d5f7e467d0ae1265370e18fdc17d5a55e8b45b99.tar.bz2
coreclr-d5f7e467d0ae1265370e18fdc17d5a55e8b45b99.zip
[RyuJIT/ARM32] Add the optimization case on CreateDictionaryLookupHelper (#13933)
* Implement optimization case for CreateDictionaryLookupHelper Signed-off-by: Hyung-Kyu Choi <hk0110.choi@samsung.com> * Reenable mainv1/mainv2 tests
Diffstat (limited to 'src/vm/arm')
-rw-r--r--src/vm/arm/stubs.cpp117
1 files changed, 111 insertions, 6 deletions
diff --git a/src/vm/arm/stubs.cpp b/src/vm/arm/stubs.cpp
index e0574762b1..f2500c302e 100644
--- a/src/vm/arm/stubs.cpp
+++ b/src/vm/arm/stubs.cpp
@@ -3600,16 +3600,121 @@ PCODE DynamicHelpers::CreateDictionaryLookupHelper(LoaderAllocator * pAllocator,
pArgs->module = (CORINFO_MODULE_HANDLE)pModule;
// It's available only via the run-time helper function,
- // since optimization cases are not yet implemented.
- assert(pLookup->indirections == CORINFO_USEHELPER);
- BEGIN_DYNAMIC_HELPER_EMIT(18);
+ if (pLookup->indirections == CORINFO_USEHELPER)
+ {
+ BEGIN_DYNAMIC_HELPER_EMIT(18);
- EmitHelperWithArg(p, pAllocator, (TADDR)pArgs, helperAddress);
+ EmitHelperWithArg(p, pAllocator, (TADDR)pArgs, helperAddress);
- END_DYNAMIC_HELPER_EMIT();
+ END_DYNAMIC_HELPER_EMIT();
+ }
+ else
+ {
+ int indirectionsSize = 0;
+ for (WORD i = 0; i < pLookup->indirections; i++)
+ {
+ if ((i == 0 && pLookup->indirectFirstOffset) || (i == 1 && pLookup->indirectSecondOffset))
+ {
+ indirectionsSize += (pLookup->offsets[i] >= 0xFFF ? 10 : 2);
+ indirectionsSize += 4;
+ }
+ else
+ {
+ indirectionsSize += (pLookup->offsets[i] >= 0xFFF ? 10 : 4);
+ }
+ }
+
+ int codeSize = indirectionsSize + (pLookup->testForNull ? 26 : 2);
+
+ BEGIN_DYNAMIC_HELPER_EMIT(codeSize);
+
+ if (pLookup->testForNull)
+ {
+ // mov r3, r0
+ *(WORD *)p = 0x4603;
+ p += 2;
+ }
- // @TODO : Additional implementation is required for optimization cases.
+ for (WORD i = 0; i < pLookup->indirections; i++)
+ {
+ if ((i == 0 && pLookup->indirectFirstOffset) || (i == 1 && pLookup->indirectSecondOffset))
+ {
+ if (pLookup->offsets[i] >= 0xFF)
+ {
+ // mov r2, offset
+ MovRegImm(p, 2, pLookup->offsets[i]);
+ p += 8;
+
+ // add r0, r2
+ *(WORD *)p = 0x4410;
+ p += 2;
+ }
+ else
+ {
+ // add r0, <offset>
+ *(WORD *)p = (WORD)((WORD)0x3000 | (WORD)((0x00FF) & pLookup->offsets[i]));
+ p += 2;
+ }
+
+ // r0 is pointer + offset[0]
+ // ldr r2, [r0]
+ *(WORD *)p = 0x6802;
+ p += 2;
+
+ // r2 is offset1
+ // add r0, r2
+ *(WORD *)p = 0x4410;
+ p += 2;
+ }
+ else
+ {
+ if (pLookup->offsets[i] >= 0xFFF)
+ {
+ // mov r2, offset
+ MovRegImm(p, 2, pLookup->offsets[i]);
+ p += 8;
+
+ // ldr r0, [r0, r2]
+ *(WORD *)p = 0x5880;
+ p += 2;
+ }
+ else
+ {
+ // ldr r0, [r0 + offset]
+ *(WORD *)p = 0xF8D0;
+ p += 2;
+ *(WORD *)p = (WORD)(0xFFF & pLookup->offsets[i]);
+ p += 2;
+ }
+ }
+ }
+
+ // No null test required
+ if (!pLookup->testForNull)
+ {
+ // mov pc, lr
+ *(WORD *)p = 0x46F7;
+ p += 2;
+ }
+ else
+ {
+ // cbz r0, nullvaluelabel
+ *(WORD *)p = 0xB100;
+ p += 2;
+ // mov pc, lr
+ *(WORD *)p = 0x46F7;
+ p += 2;
+ // nullvaluelabel:
+ // mov r0, r3
+ *(WORD *)p = 0x4618;
+ p += 2;
+
+ EmitHelperWithArg(p, pAllocator, (TADDR)pArgs, helperAddress);
+ }
+
+ END_DYNAMIC_HELPER_EMIT();
+ }
}
#endif // FEATURE_READYTORUN