Home | History | Annotate | Download | only in arm

Lines Matching full:cunit

30 static void markCard(CompilationUnit *cUnit, int valReg, int tgtAddrReg)
32 int regCardBase = dvmCompilerAllocTemp(cUnit);
33 int regCardNo = dvmCompilerAllocTemp(cUnit);
34 ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondEq, valReg, 0);
35 loadWordDisp(cUnit, r6SELF, offsetof(Thread, cardTable),
37 opRegRegImm(cUnit, kOpLsr, regCardNo, tgtAddrReg, GC_CARD_SHIFT);
38 storeBaseIndexed(cUnit, regCardBase, regCardNo, regCardBase, 0,
40 ArmLIR *target = newLIR0(cUnit, kArmPseudoTargetLabel);
43 dvmCompilerFreeTemp(cUnit, regCardBase);
44 dvmCompilerFreeTemp(cUnit, regCardNo);
47 static bool genConversionCall(CompilationUnit *cUnit, MIR *mir, void *funct,
56 dvmCompilerFlushAllRegs(cUnit); /* Send everything to home location */
58 rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
59 loadValueDirectFixed(cUnit, rlSrc, r0);
61 rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1);
62 loadValueDirectWideFixed(cUnit, rlSrc, r0, r1);
64 LOAD_FUNC_ADDR(cUnit, r2, (int)funct);
65 opReg(cUnit, kOpBlx, r2);
66 dvmCompilerClobberCallRegs(cUnit);
69 rlDest = dvmCompilerGetDest(cUnit, mir, 0);
70 rlResult = dvmCompilerGetReturn(cUnit);
71 storeValue(cUnit, rlDest, rlResult);
74 rlDest = dvmCompilerGetDestWide(cUnit, mir, 0, 1);
75 rlResult = dvmCompilerGetReturnWide(cUnit);
76 storeValueWide(cUnit, rlDest, rlResult);
81 static bool genArithOpFloatPortable(CompilationUnit *cUnit, MIR *mir,
110 genNegFloat(cUnit, rlDest, rlSrc1);
116 dvmCompilerFlushAllRegs(cUnit); /* Send everything to home location */
117 loadValueDirectFixed(cUnit, rlSrc1, r0);
118 loadValueDirectFixed(cUnit, rlSrc2, r1);
119 LOAD_FUNC_ADDR(cUnit, r2, (int)funct);
120 opReg(cUnit, kOpBlx, r2);
121 dvmCompilerClobberCallRegs(cUnit);
122 rlResult = dvmCompilerGetReturn(cUnit);
123 storeValue(cUnit, rlDest, rlResult);
127 static bool genArithOpDoublePortable(CompilationUnit *cUnit, MIR *mir,
156 genNegDouble(cUnit, rlDest, rlSrc1);
162 dvmCompilerFlushAllRegs(cUnit); /* Send everything to home location */
163 LOAD_FUNC_ADDR(cUnit, r14lr, (int)funct);
164 loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
165 loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
166 opReg(cUnit, kOpBlx, r14lr);
167 dvmCompilerClobberCallRegs(cUnit);
168 rlResult = dvmCompilerGetReturnWide(cUnit);
169 storeValueWide(cUnit, rlDest, rlResult);
171 cUnit->usesLinkRegister = true;
176 static bool genConversionPortable(CompilationUnit *cUnit, MIR *mir)
182 return genConversionCall(cUnit, mir, (void*)__aeabi_i2f, 1, 1);
184 return genConversionCall(cUnit, mir, (void*)__aeabi_f2iz, 1, 1);
186 return genConversionCall(cUnit, mir, (void*)__aeabi_d2f, 2, 1);
188 return genConversionCall(cUnit, mir, (void*)__aeabi_f2d, 1, 2);
190 return genConversionCall(cUnit, mir, (void*)__aeabi_i2d, 1, 2);
192 return genConversionCall(cUnit, mir, (void*)__aeabi_d2iz, 2, 1);
194 return genConversionCall(cUnit, mir, (void*)dvmJitf2l, 1, 2);
196 return genConversionCall(cUnit, mir, (void*)__aeabi_l2f, 2, 1);
198 return genConversionCall(cUnit, mir, (void*)dvmJitd2l, 2, 2);
200 return genConversionCall(cUnit, mir, (void*)__aeabi_l2d, 2, 2);
244 static void selfVerificationBranchInsertPass(CompilationUnit *cUnit)
249 for (thisLIR = (ArmLIR *) cUnit->firstLIRInsn;
250 thisLIR != (ArmLIR *) cUnit->lastLIRInsn;
261 if (cUnit->usesLinkRegister) {
262 genSelfVerificationPreBranch(cUnit, thisLIR);
274 if (cUnit->usesLinkRegister) {
275 genSelfVerificationPostBranch(cUnit, thisLIR);
283 static ArmLIR *genConditionalBranch(CompilationUnit *cUnit,
287 ArmLIR *branch = opCondBranch(cUnit, cond);
293 static inline ArmLIR *genTrap(CompilationUnit *cUnit, int dOffset,
296 ArmLIR *branch = opNone(cUnit, kOpUncondBr);
297 return genCheckCommon(cUnit, dOffset, branch, pcrLabel);
301 static void genIGetWide(CompilationUnit *cUnit, MIR *mir, int fieldOffset)
303 RegLocation rlObj = dvmCompilerGetSrc(cUnit, mir, 0);
304 RegLocation rlDest = dvmCompilerGetDestWide(cUnit, mir, 0, 1);
306 rlObj = loadValue(cUnit, rlObj, kCoreReg);
307 int regPtr = dvmCompilerAllocTemp(cUnit);
311 genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir->offset,
313 opRegRegImm(cUnit, kOpAdd, regPtr, rlObj.lowReg, fieldOffset);
314 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kAnyReg, true);
317 loadPair(cUnit, regPtr, rlResult.lowReg, rlResult.highReg);
320 dvmCompilerFreeTemp(cUnit, regPtr);
321 storeValueWide(cUnit, rlDest, rlResult);
325 static void genIPutWide(CompilationUnit *cUnit, MIR *mir, int fieldOffset)
327 RegLocation rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1);
328 RegLocation rlObj = dvmCompilerGetSrc(cUnit, mir, 2);
329 rlObj = loadValue(cUnit, rlObj, kCoreReg);
331 rlSrc = loadValueWide(cUnit, rlSrc, kAnyReg);
332 genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir->offset,
334 regPtr = dvmCompilerAllocTemp(cUnit);
335 opRegRegImm(cUnit, kOpAdd, regPtr, rlObj.lowReg, fieldOffset);
338 storePair(cUnit, regPtr, rlSrc.lowReg, rlSrc.highReg);
341 dvmCompilerFreeTemp(cUnit, regPtr);
348 static void genIGet(CompilationUnit *cUnit, MIR *mir, OpSize size,
353 RegLocation rlObj = dvmCompilerGetSrc(cUnit, mir, 0);
354 RegLocation rlDest = dvmCompilerGetDest(cUnit, mir, 0);
355 rlObj = loadValue(cUnit, rlObj, kCoreReg);
356 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, regClass, true);
357 genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir->offset,
361 loadBaseDisp(cUnit, mir, rlObj.lowReg, fieldOffset, rlResult.lowReg,
365 dvmCompilerGenMemBarrier(cUnit, kSY);
368 storeValue(cUnit, rlDest, rlResult);
375 static void genIPut(CompilationUnit *cUnit, MIR *mir, OpSize size,
379 RegLocation rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
380 RegLocation rlObj = dvmCompilerGetSrc(cUnit, mir, 1);
381 rlObj = loadValue(cUnit, rlObj, kCoreReg);
382 rlSrc = loadValue(cUnit, rlSrc, regClass);
383 genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir->offset,
387 dvmCompilerGenMemBarrier(cUnit, kST);
390 storeBaseDisp(cUnit, rlObj.lowReg, fieldOffset, rlSrc.lowReg, size);
393 dvmCompilerGenMemBarrier(cUnit, kSY);
397 markCard(cUnit, rlSrc.lowReg, rlObj.lowReg);
405 static void genArrayGet(CompilationUnit *cUnit, MIR *mir, OpSize size,
413 rlArray = loadValue(cUnit, rlArray, kCoreReg);
414 rlIndex = loadValue(cUnit, rlIndex, kCoreReg);
421 pcrLabel = genNullCheck(cUnit, rlArray.sRegLow,
425 regPtr = dvmCompilerAllocTemp(cUnit);
428 int regLen = dvmCompilerAllocTemp(cUnit);
430 loadWordDisp(cUnit, rlArray.lowReg, lenOffset, regLen);
432 opRegRegImm(cUnit, kOpAdd, regPtr, rlArray.lowReg, dataOffset);
433 genBoundsCheck(cUnit, rlIndex.lowReg, regLen, mir->offset,
435 dvmCompilerFreeTemp(cUnit, regLen);
438 opRegRegImm(cUnit, kOpAdd, regPtr, rlArray.lowReg, dataOffset);
442 int rNewIndex = dvmCompilerAllocTemp(cUnit);
443 opRegRegImm(cUnit, kOpLsl, rNewIndex, rlIndex.lowReg, scale);
444 opRegReg(cUnit, kOpAdd, regPtr, rNewIndex);
445 dvmCompilerFreeTemp(cUnit, rNewIndex);
447 cUnit, kOpAdd, regPtr, rlIndex.lowReg);
449 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, regClass, true);
452 loadPair(cUnit, regPtr, rlResult.lowReg, rlResult.highReg);
455 dvmCompilerFreeTemp(cUnit, regPtr);
456 storeValueWide(cUnit, rlDest, rlResult);
458 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, regClass, true);
461 loadBaseIndexed(cUnit, regPtr, rlIndex.lowReg, rlResult.lowReg,
465 dvmCompilerFreeTemp(cUnit, regPtr);
466 storeValue(cUnit, rlDest, rlResult);
474 static void genArrayPut(CompilationUnit *cUnit, MIR *mir, OpSize size,
483 rlArray = loadValue(cUnit, rlArray, kCoreReg);
484 rlIndex = loadValue(cUnit, rlIndex, kCoreReg);
486 if (dvmCompilerIsTemp(cUnit, rlArray.lowReg)) {
487 dvmCompilerClobber(cUnit, rlArray.lowReg);
490 regPtr = dvmCompilerAllocTemp(cUnit);
491 genRegCopy(cUnit, regPtr, rlArray.lowReg);
498 pcrLabel = genNullCheck(cUnit, rlArray.sRegLow, rlArray.lowReg,
503 int regLen = dvmCompilerAllocTemp(cUnit);
506 loadWordDisp(cUnit, rlArray.lowReg, lenOffset, regLen);
508 opRegImm(cUnit, kOpAdd, regPtr, dataOffset);
509 genBoundsCheck(cUnit, rlIndex.lowReg, regLen, mir->offset,
511 dvmCompilerFreeTemp(cUnit, regLen);
514 opRegImm(cUnit, kOpAdd, regPtr, dataOffset);
520 int rNewIndex = dvmCompilerAllocTemp(cUnit);
521 opRegRegImm(cUnit, kOpLsl, rNewIndex, rlIndex.lowReg, scale);
522 opRegReg(cUnit, kOpAdd, regPtr, rNewIndex);
523 dvmCompilerFreeTemp(cUnit, rNewIndex);
525 opRegReg(cUnit, kOpAdd, regPtr, rlIndex.lowReg);
527 rlSrc = loadValueWide(cUnit, rlSrc, regClass);
530 storePair(cUnit, regPtr, rlSrc.lowReg, rlSrc.highReg);
533 dvmCompilerFreeTemp(cUnit, regPtr);
535 rlSrc = loadValue(cUnit, rlSrc, regClass);
538 storeBaseIndexed(cUnit, regPtr, rlIndex.lowReg, rlSrc.lowReg,
549 static void genArrayObjectPut(CompilationUnit *cUnit, MIR *mir,
556 dvmCompilerFlushAllRegs(cUnit);
563 loadValueDirectFixed(cUnit, rlArray, regArray);
564 loadValueDirectFixed(cUnit, rlIndex, regIndex);
570 pcrLabel = genNullCheck(cUnit, rlArray.sRegLow, regArray,
576 loadWordDisp(cUnit, regArray, lenOffset, regLen);
578 opRegRegImm(cUnit, kOpAdd, regPtr, regArray, dataOffset);
579 genBoundsCheck(cUnit, regIndex, regLen, mir->offset,
583 opRegRegImm(cUnit, kOpAdd, regPtr, regArray, dataOffset);
587 loadValueDirectFixed(cUnit, rlSrc, r0);
588 LOAD_FUNC_ADDR(cUnit, r2, (int)dvmCanPutArrayElement);
591 ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondEq, r0, 0);
594 loadWordDisp(cUnit, regArray, offsetof(Object, clazz), r1);
595 loadWordDisp(cUnit, r0, offsetof(Object, clazz), r0);
596 opReg(cUnit, kOpBlx, r2);
597 dvmCompilerClobberCallRegs(cUnit);
604 dvmCompilerLockTemp(cUnit, regPtr); // r4PC
605 dvmCompilerLockTemp(cUnit, regIndex); // r7
606 dvmCompilerLockTemp(cUnit, r0);
607 dvmCompilerLockTemp(cUnit, r1);
610 genRegImmCheck(cUnit, kArmCondEq, r0, 0, mir->offset, pcrLabel);
613 loadValueDirectFixed(cUnit, rlSrc, r0);
614 loadValueDirectFixed(cUnit, rlArray, r1);
616 ArmLIR *target = newLIR0(cUnit, kArmPseudoTargetLabel);
621 storeBaseIndexed(cUnit, regPtr, regIndex, r0,
625 dvmCompilerFreeTemp(cUnit, regPtr);
626 dvmCompilerFreeTemp(cUnit, regIndex);
629 markCard(cUnit, r0, r1);
632 static bool genShiftOpLong(CompilationUnit *cUnit, MIR *mir,
642 loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
643 loadValueDirect(cUnit, rlShift, r2);
647 genDispatchToHandler(cUnit, TEMPLATE_SHL_LONG);
651 genDispatchToHandler(cUnit, TEMPLATE_SHR_LONG);
655 genDispatchToHandler(cUnit, TEMPLATE_USHR_LONG);
660 rlResult = dvmCompilerGetReturnWide(cUnit);
661 storeValueWide(cUnit, rlDest, rlResult);
665 static bool genArithOpLong(CompilationUnit *cUnit, MIR *mir,
678 rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
679 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
680 opRegReg(cUnit, kOpMvn, rlResult.lowReg, rlSrc2.lowReg);
681 opRegReg(cUnit, kOpMvn, rlResult.highReg, rlSrc2.highReg);
682 storeValueWide(cUnit, rlDest, rlResult);
697 genMulLong(cUnit, rlDest, rlSrc1, rlSrc2);
729 int tReg = dvmCompilerAllocTemp(cUnit);
730 rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
731 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
732 loadConstantNoClobber(cUnit, tReg, 0);
733 opRegRegReg(cUnit, kOpSub, rlResult.lowReg,
735 opRegReg(cUnit, kOpSbc, tReg, rlSrc2.highReg);
736 genRegCopy(cUnit, rlResult.highReg, tReg);
737 storeValueWide(cUnit, rlDest, rlResult);
742 dvmCompilerAbort(cUnit);
745 genLong3Addr(cUnit, mir, firstOp, secondOp, rlDest, rlSrc1, rlSrc2);
748 dvmCompilerFlushAllRegs(cUnit); /* Send everything to home location */
749 loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
750 LOAD_FUNC_ADDR(cUnit, r14lr, (int) callTgt);
751 loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
752 opReg(cUnit, kOpBlx, r14lr);
753 dvmCompilerClobberCallRegs(cUnit);
755 rlResult = dvmCompilerGetReturnWide(cUnit);
757 rlResult = dvmCompilerGetReturnWideAlt(cUnit);
758 storeValueWide(cUnit, rlDest, rlResult);
760 cUnit->usesLinkRegister = true;
766 static bool genArithOpInt(CompilationUnit *cUnit, MIR *mir,
845 dvmCompilerAbort(cUnit);
848 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
850 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
851 opRegReg(cUnit, op, rlResult.lowReg,
854 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
856 int tReg = dvmCompilerAllocTemp(cUnit);
857 opRegRegImm(cUnit, kOpAnd, tReg, rlSrc2.lowReg, 31);
858 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
859 opRegRegReg(cUnit, op, rlResult.lowReg,
861 dvmCompilerFreeTemp(cUnit, tReg);
863 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
864 opRegRegReg(cUnit, op, rlResult.lowReg,
868 storeValue(cUnit, rlDest, rlResult);
871 dvmCompilerFlushAllRegs(cUnit); /* Send everything to home location */
872 loadValueDirectFixed(cUnit, rlSrc2, r1);
873 LOAD_FUNC_ADDR(cUnit, r2, (int) callTgt);
874 loadValueDirectFixed(cUnit, rlSrc1, r0);
876 genNullCheck(cUnit, rlSrc2.sRegLow, r1, mir->offset, NULL);
878 opReg(cUnit, kOpBlx, r2);
879 dvmCompilerClobberCallRegs(cUnit);
881 rlResult = dvmCompilerGetReturn(cUnit);
883 rlResult = dvmCompilerGetReturnAlt(cUnit);
884 storeValue(cUnit, rlDest, rlResult);
889 static bool genArithOp(CompilationUnit *cUnit, MIR *mir)
897 rlSrc1 = dvmCompilerGetSrc(cUnit, mir, 0);
898 rlSrc2 = dvmCompilerGetSrc(cUnit, mir, 1);
900 rlSrc1 = dvmCompilerGetSrcWide(cUnit, mir, 0, 1);
901 rlSrc2 = dvmCompilerGetSrc(cUnit, mir, 2);
903 rlSrc1 = dvmCompilerGetSrcWide(cUnit, mir, 0, 1);
904 rlSrc2 = dvmCompilerGetSrcWide(cUnit, mir, 2, 3);
908 rlDest = dvmCompilerGetDest(cUnit, mir, 0);
911 rlDest = dvmCompilerGetDestWide(cUnit, mir, 0, 1);
915 return genArithOpLong(cUnit,mir, rlDest, rlSrc1, rlSrc2);
918 return genArithOpLong(cUnit,mir, rlDest, rlSrc1, rlSrc2);
921 return genShiftOpLong(cUnit,mir, rlDest, rlSrc1, rlSrc2);
924 return genShiftOpLong(cUnit,mir, rlDest, rlSrc1, rlSrc2);
927 return genArithOpInt(cUnit,mir, rlDest, rlSrc1, rlSrc2);
930 return genArithOpInt(cUnit,mir, rlDest, rlSrc1, rlSrc2);
933 return genArithOpFloat(cUnit,mir, rlDest, rlSrc1, rlSrc2);
936 return genArithOpFloat(cUnit, mir, rlDest, rlSrc1, rlSrc2);
939 return genArithOpDouble(cUnit,mir, rlDest, rlSrc1, rlSrc2);
942 return genArithOpDouble(cUnit,mir, rlDest, rlSrc1, rlSrc2);
948 static ArmLIR *genUnconditionalBranch(CompilationUnit *cUnit, ArmLIR *target)
950 ArmLIR *branch = opNone(cUnit, kOpUncondBr);
956 static void genReturnCommon(CompilationUnit *cUnit, MIR *mir)
958 genDispatchToHandler(cUnit, gDvmJit.methodTraceSupport ?
963 int dPC = (int) (cUnit->method->insns + mir->offset);
965 ArmLIR *branch = genUnconditionalBranch(cUnit, NULL);
972 dvmInsertGrowableList(&cUnit->pcReconstructionList, (intptr_t) pcrLabel);
977 static void genProcessArgsNoRange(CompilationUnit *cUnit, MIR *mir,
991 dvmCompilerLockAllTemps(cUnit);
994 rlArg = dvmCompilerGetSrc(cUnit, mir, numDone++);
995 loadValueDirectFixed(cUnit, rlArg, i);
999 opRegRegImm(cUnit, kOpSub, r7, r5FP,
1003 *pcrLabel = genNullCheck(cUnit, dvmCompilerSSASrc(mir, 0), r0,
1006 storeMultiple(cUnit, r7, regMask);
1010 static void genProcessArgsRange(CompilationUnit *cUnit, MIR *mir,
1025 dvmCompilerLockAllTemps(cUnit);
1031 opRegRegImm(cUnit, kOpAdd, r4PC, r5FP, srcOffset);
1038 if (numArgs != 0) loadMultiple(cUnit, r4PC, regMask);
1040 opRegRegImm(cUnit, kOpSub, r7, r5FP,
1044 *pcrLabel = genNullCheck(cUnit, dvmCompilerSSASrc(mir, 0), r0,
1058 opImm(cUnit, kOpPush, (1 << r0 | 1 << r5FP));
1061 loadConstant(cUnit, 5, ((numArgs - 4) >> 2) << 2);
1062 loopLabel = newLIR0(cUnit, kArmPseudoTargetLabel);
1065 storeMultiple(cUnit, r7, regMask);
1070 loadMultiple(cUnit, r4PC, regMask);
1073 opRegImm(cUnit, kOpSub, r5FP, 4);
1074 genConditionalBranch(cUnit, kArmCondNe, loopLabel);
1079 if (numArgs != 0) storeMultiple(cUnit, r7, regMask);
1088 loadMultiple(cUnit, r4PC, regMask);
1091 opImm(cUnit, kOpPop, (1 << r0 | 1 << r5FP));
1095 storeMultiple(cUnit, r7, regMask);
1103 static void genInvokeSingletonCommon(CompilationUnit *cUnit, MIR *mir,
1113 dvmCompilerLockAllTemps(cUnit);
1117 ArmLIR *addrRetChain = opRegRegImm(cUnit, kOpAdd, r1, r15pc, 0);
1120 loadConstant(cUnit, r4PC,
1121 (int) (cUnit->method->insns + mir->offset));
1125 loadConstant(cUnit, r7, calleeMethod->registersSize);
1134 genDispatchToHandler(cUnit, gDvmJit.methodTraceSupport ?
1142 loadConstant(cUnit, r2, calleeMethod->outsSize);
1143 genDispatchToHandler(cUnit, gDvmJit.methodTraceSupport ?
1150 genUnconditionalBranch(cUnit, &labelList[bb->taken->id]);
1153 genTrap(cUnit, mir->offset, pcrLabel);
1176 static void genInvokeVirtualCommon(CompilationUnit *cUnit, MIR *mir,
1188 dvmCompilerLockAllTemps(cUnit);
1199 loadConstant(cUnit, r4PC,
1200 (int) (cUnit->method->insns + mir->offset));
1203 ArmLIR *addrRetChain = opRegRegImm(cUnit, kOpAdd, r1, r15pc, 0);
1207 ArmLIR *predictedChainingCell = opRegRegImm(cUnit, kOpAdd, r2, r15pc, 0);
1210 genDispatchToHandler(cUnit, gDvmJit.methodTraceSupport ?
1215 genUnconditionalBranch(cUnit, predChainingCell);
1222 int dPC = (int) (cUnit->method->insns + mir->offset);
1228 dvmInsertGrowableList(&cUnit->pcReconstructionList,
1233 genUnconditionalBranch(cUnit, pcrLabel);
1245 loadWordDisp(cUnit, r7, methodIndex * 4, r0);
1248 ArmLIR *bypassRechaining = genCmpImmBranch(cUnit, kArmCondGt, r1, 0);
1250 LOAD_FUNC_ADDR(cUnit, r7, (int) dvmJitToPatchPredictedChain);
1252 genRegCopy(cUnit, r1, r6SELF);
1263 opReg(cUnit, kOpBlx, r7);
1266 addrRetChain = opRegRegImm(cUnit, kOpAdd, r1, r15pc, 0);
1275 genDispatchToHandler(cUnit, gDvmJit.methodTraceSupport ?
1282 genTrap(cUnit, mir->offset, pcrLabel);
1286 static void genInvokeVirtualWholeMethod(CompilationUnit *cUnit,
1292 dvmCompilerLockAllTemps(cUnit);
1294 loadClassPointer(cUnit, r1, (int) callsiteInfo);
1296 loadWordDisp(cUnit, r0, offsetof(Object, clazz), r2);
1298 opRegReg(cUnit, kOpCmp, r1, r2);
1303 ArmLIR *classCheck = opCondBranch(cUnit, kArmCondNe);
1306 loadConstant(cUnit, r0, (int) (cUnit->method->insns + mir->offset));
1308 newLIR2(cUnit, kThumbBl1, (int) calleeAddr, (int) calleeAddr);
1309 newLIR2(cUnit, kThumbBl2, (int) calleeAddr, (int) calleeAddr);
1310 genUnconditionalBranch(cUnit, retChainingCell);
1313 ArmLIR *slowPathLabel = newLIR0(cUnit, kArmPseudoTargetLabel);
1319 cUnit->printMe = true;
1322 static void genInvokeSingletonWholeMethod(CompilationUnit *cUnit,
1328 loadConstant(cUnit, r0, (int) (cUnit->method->insns + mir->offset));
1330 newLIR2(cUnit, kThumbBl1, (int) calleeAddr, (int) calleeAddr);
1331 newLIR2(cUnit, kThumbBl2, (int) calleeAddr, (int) calleeAddr);
1332 genUnconditionalBranch(cUnit, retChainingCell);
1335 cUnit->printMe = true;
1339 static void genPuntToInterp(CompilationUnit *cUnit, unsigned int offset)
1342 dvmCompilerFlushAllRegs(cUnit);
1343 loadConstant(cUnit, r0, (int) (cUnit->method->insns + offset));
1344 loadWordDisp(cUnit, r6SELF, offsetof(Thread,
1346 opReg(cUnit, kOpBlx, r1);
1353 static void genInterpSingleStep(CompilationUnit *cUnit, MIR *mir)
1359 if (cUnit->jitMode == kJitLoop) {
1360 cUnit->quitLoopMode = true;
1369 dvmCompilerFlushAllRegs(cUnit);
1372 genPuntToInterp(cUnit, mir->offset);
1377 loadWordDisp(cUnit, r6SELF, entryAddr, r2);
1379 loadConstant(cUnit, r0, (int) (cUnit->method->insns + mir->offset));
1381 loadConstant(cUnit, r1, (int) (cUnit->method->insns + mir->next->offset));
1382 opReg(cUnit, kOpBlx, r2);
1397 static void genMonitorPortable(CompilationUnit *cUnit, MIR *mir)
1400 genExportPC(cUnit, mir);
1401 dvmCompilerFlushAllRegs(cUnit); /* Send everything to home location */
1402 RegLocation rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
1403 loadValueDirectFixed(cUnit, rlSrc, r1);
1404 genRegCopy(cUnit, r0, r6SELF);
1405 genNullCheck(cUnit, rlSrc.sRegLow, r1, mir->offset, NULL);
1408 loadConstant(cUnit, r4PC, (int)(cUnit->method->insns + mir->offset +
1410 genDispatchToHandler(cUnit, TEMPLATE_MONITOR_ENTER);
1412 LOAD_FUNC_ADDR(cUnit, r2, (int)dvmUnlockObject);
1414 opReg(cUnit, kOpBlx, r2);
1416 ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
1417 loadConstant(cUnit, r0,
1418 (int) (cUnit->method->insns + mir->offset +
1420 genDispatchToHandler(cUnit, TEMPLATE_THROW_EXCEPTION_COMMON);
1421 ArmLIR *target = newLIR0(cUnit, kArmPseudoTargetLabel);
1424 dvmCompilerClobberCallRegs(cUnit);
1433 static void genSuspendPoll(CompilationUnit *cUnit, MIR *mir)
1435 int rTemp = dvmCompilerAllocTemp(cUnit);
1437 ld = loadBaseDisp(cUnit, NULL, r6SELF,
1441 genRegImmCheck(cUnit, kArmCondNe, rTemp, 0, mir->offset, NULL);
1450 static bool handleFmt10t_Fmt20t_Fmt30t(CompilationUnit *cUnit, MIR *mir,
1457 (gDvmJit.genSuspendPoll || cUnit->jitMode == kJitLoop)) {
1458 genSuspendPoll(cUnit, mir);
1468 cUnit->nextCodegenBlock = bb->taken;
1471 genUnconditionalBranch(cUnit, &labelList[bb->taken->id]);
1476 static bool handleFmt10x(CompilationUnit *cUnit, MIR *mir)
1485 dvmCompilerGenMemBarrier(cUnit, kST);
1488 genReturnCommon(cUnit,mir);
1504 static bool handleFmt11n_Fmt31i(CompilationUnit *cUnit, MIR *mir)
1509 rlDest = dvmCompilerGetDestWide(cUnit, mir, 0, 1);
1511 rlDest = dvmCompilerGetDest(cUnit, mir, 0);
1517 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kAnyReg, true);
1518 loadConstantNoClobber(cUnit, rlResult.lowReg, mir->dalvikInsn.vB);
1519 storeValue(cUnit, rlDest, rlResult);
1525 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
1526 loadConstantNoClobber(cUnit, rlResult.lowReg, mir->dalvikInsn.vB);
1527 opRegRegImm(cUnit, kOpAsr, rlResult.highReg,
1529 storeValueWide(cUnit, rlDest, rlResult);
1538 static bool handleFmt21h(CompilationUnit *cUnit, MIR *mir)
1543 rlDest = dvmCompilerGetDestWide(cUnit, mir, 0, 1);
1545 rlDest = dvmCompilerGetDest(cUnit, mir, 0);
1547 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kAnyReg, true);
1551 loadConstantNoClobber(cUnit, rlResult.lowReg,
1553 storeValue(cUnit, rlDest, rlResult);
1557 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
1559 storeValueWide(cUnit, rlDest, rlResult);
1568 static bool handleFmt20bc(CompilationUnit *cUnit, MIR *mir)
1571 genInterpSingleStep(cUnit, mir);
1575 static bool handleFmt21c_Fmt31c(CompilationUnit *cUnit, MIR *mir)
1585 (cUnit->method->clazz->pDvmDex->pResStrings[mir->dalvikInsn.vB]);
1593 rlDest = dvmCompilerGetDest(cUnit, mir, 0);
1594 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
1595 loadConstantNoClobber(cUnit, rlResult.lowReg, (int) strPtr );
1596 storeValue(cUnit, rlDest, rlResult);
1601 (cUnit->method->clazz->pDvmDex->pResClasses[mir->dalvikInsn.vB]);
1609 rlDest = dvmCompilerGetDest(cUnit, mir, 0);
1610 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
1611 loadConstantNoClobber(cUnit, rlResult.lowReg, (int) classPtr );
1612 storeValue(cUnit, rlDest, rlResult);
1624 int tReg = dvmCompilerAllocTemp(cUnit);
1627 mir->meta.calleeMethod : cUnit->method;
1654 rlDest = dvmCompilerGetDest(cUnit, mir, 0);
1655 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kAnyReg, true);
1656 loadConstant(cUnit, tReg, (int) fieldPtr + valOffset);
1659 dvmCompilerGenMemBarrier(cUnit, kSY);
1662 loadWordDisp(cUnit, tReg, 0, rlResult.lowReg);
1665 storeValue(cUnit, rlDest, rlResult);
1671 mir->meta.calleeMethod : cUnit->method;
1681 int tReg = dvmCompilerAllocTemp(cUnit);
1682 rlDest = dvmCompilerGetDestWide(cUnit, mir, 0, 1);
1683 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kAnyReg, true);
1684 loadConstant(cUnit, tReg, (int) fieldPtr + valOffset);
1687 loadPair(cUnit, tReg, rlResult.lowReg, rlResult.highReg);
1690 storeValueWide(cUnit, rlDest, rlResult);
1702 int tReg = dvmCompilerAllocTemp(cUnit);
1707 mir->meta.calleeMethod : cUnit->method;
1729 rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
1730 rlSrc = loadValue(cUnit, rlSrc, kAnyReg);
1731 loadConstant(cUnit, tReg, (int) fieldPtr);
1733 objHead = dvmCompilerAllocTemp(cUnit);
1734 loadWordDisp(cUnit, tReg, OFFSETOF_MEMBER(Field, clazz), objHead);
1737 dvmCompilerGenMemBarrier(cUnit, kST);
1740 storeWordDisp(cUnit, tReg, valOffset ,rlSrc.lowReg);
1741 dvmCompilerFreeTemp(cUnit, tReg);
1744 dvmCompilerGenMemBarrier(cUnit, kSY);
1748 markCard(cUnit, rlSrc.lowReg, objHead);
1749 dvmCompilerFreeTemp(cUnit, objHead);
1755 int tReg = dvmCompilerAllocTemp(cUnit);
1758 mir->meta.calleeMethod : cUnit->method;
1768 rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1);
1769 rlSrc = loadValueWide(cUnit, rlSrc, kAnyReg);
1770 loadConstant(cUnit, tReg, (int) fieldPtr + valOffset);
1773 storePair(cUnit, tReg, rlSrc.lowReg, rlSrc.highReg);
1783 (cUnit->method->clazz->pDvmDex->pResClasses[mir->dalvikInsn.vB]);
1796 dvmCompilerFlushAllRegs(cUnit); /* Everything to home location */
1797 genExportPC(cUnit, mir);
1798 LOAD_FUNC_ADDR(cUnit, r2, (int)dvmAllocObject);
1799 loadConstant(cUnit, r0, (int) classPtr);
1800 loadConstant(cUnit, r1, ALLOC_DONT_TRACK);
1801 opReg(cUnit, kOpBlx, r2);
1802 dvmCompilerClobberCallRegs(cUnit);
1804 ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
1808 cUnit, r0,
1809 (int) (cUnit->method->insns + mir->offset));
1810 genDispatchToHandler(cUnit, TEMPLATE_THROW_EXCEPTION_COMMON);
1813 ArmLIR *target = newLIR0(cUnit, kArmPseudoTargetLabel);
1816 rlDest = dvmCompilerGetDest(cUnit, mir, 0);
1817 rlResult = dvmCompilerGetReturn(cUnit);
1818 storeValue(cUnit, rlDest, rlResult);
1827 (cUnit->method->clazz->pDvmDex->pResClasses[mir->dalvikInsn.vB]);
1839 genInterpSingleStep(cUnit, mir);
1842 dvmCompilerFlushAllRegs(cUnit); /* Everything to home location */
1843 loadConstant(cUnit, r1, (int) classPtr );
1844 rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
1845 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
1847 ArmLIR *branch1 = genCmpImmBranch(cUnit, kArmCondEq,
1856 loadWordDisp(cUnit, rlSrc.lowReg, offsetof(Object, clazz), r0);
1857 LOAD_FUNC_ADDR(cUnit, r2, (int)dvmInstanceofNonTrivial);
1858 opRegReg(cUnit, kOpCmp, r0, r1);
1859 ArmLIR *branch2 = opCondBranch(cUnit, kArmCondEq);
1860 opReg(cUnit, kOpBlx, r2);
1861 dvmCompilerClobberCallRegs(cUnit);
1867 genZeroCheck(cUnit, r0, mir->offset, NULL);
1869 ArmLIR *target = newLIR0(cUnit, kArmPseudoTargetLabel);
1877 genInterpSingleStep(cUnit, mir);
1900 static bool handleFmt11x(CompilationUnit *cUnit, MIR *mir)
1907 int resetReg = dvmCompilerAllocTemp(cUnit);
1908 RegLocation rlDest = dvmCompilerGetDest(cUnit, mir, 0);
1909 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
1910 loadWordDisp(cUnit, r6SELF, exOffset, rlResult.lowReg);
1911 loadConstant(cUnit, resetReg, 0);
1912 storeWordDisp(cUnit, r6SELF, exOffset, resetReg);
1913 storeValue(cUnit, rlDest, rlResult);
1921 RegLocation rlDest = dvmCompilerGetDest(cUnit, mir, 0);
1924 storeValue(cUnit, rlDest, rlSrc);
1931 RegLocation rlDest = dvmCompilerGetDestWide(cUnit, mir, 0, 1);
1934 storeValueWide(cUnit, rlDest, rlSrc);
1938 RegLocation rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1);
1941 storeValueWide(cUnit, rlDest, rlSrc);
1942 genReturnCommon(cUnit,mir);
1947 RegLocation rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
1950 storeValue(cUnit, rlDest, rlSrc);
1951 genReturnCommon(cUnit, mir);
1956 genMonitor(cUnit, mir);
1959 genInterpSingleStep(cUnit, mir);
1967 static bool handleFmt12x(CompilationUnit *cUnit, MIR *mir)
1975 return genArithOp( cUnit, mir );
1979 rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1);
1981 rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
1983 rlDest = dvmCompilerGetDestWide(cUnit, mir, 0, 1);
1985 rlDest = dvmCompilerGetDest(cUnit, mir, 0);
1998 return genConversion(cUnit, mir);
2001 return genArithOpInt(cUnit, mir, rlDest, rlSrc, rlSrc);
2004 return genArithOpLong(cUnit, mir, rlDest, rlSrc, rlSrc);
2006 return genArithOpFloat(cUnit, mir, rlDest, rlSrc, rlSrc);
2008 return genArithOpDouble(cUnit, mir, rlDest, rlSrc, rlSrc);
2010 storeValueWide(cUnit, rlDest, rlSrc);
2013 rlSrc = dvmCompilerUpdateLoc(cUnit, rlSrc);
2014 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
2017 genRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2019 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2021 opRegRegImm(cUnit, kOpAsr, rlResult.highReg,
2023 storeValueWide(cUnit, rlDest, rlResult);
2026 rlSrc = dvmCompilerUpdateLocWide(cUnit, rlSrc);
2027 rlSrc = dvmCompilerWideToNarrow(cUnit, rlSrc);
2031 storeValue(cUnit, rlDest, rlSrc);
2034 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2035 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
2036 opRegReg(cUnit, kOp2Byte, rlResult.lowReg, rlSrc.lowReg);
2037 storeValue(cUnit, rlDest, rlResult);
2040 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2041 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
2042 opRegReg(cUnit, kOp2Short, rlResult.lowReg, rlSrc.lowReg);
2043 storeValue(cUnit, rlDest, rlResult);
2046 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2047 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
2048 opRegReg(cUnit, kOp2Char, rlResult.lowReg, rlSrc.lowReg);
2049 storeValue(cUnit, rlDest, rlResult);
2053 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2054 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg,
2056 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
2057 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset,
2059 storeValue(cUnit, rlDest, rlResult);
2068 static bool handleFmt21s(CompilationUnit *cUnit, MIR *mir)
2075 rlDest = dvmCompilerGetDestWide(cUnit, mir, 0, 1);
2076 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
2077 loadConstantNoClobber(cUnit, rlResult.lowReg, BBBB);
2079 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2080 storeValueWide(cUnit, rlDest, rlResult);
2082 rlDest = dvmCompilerGetDest(cUnit, mir, 0);
2083 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kAnyReg, true);
2084 loadConstantNoClobber(cUnit, rlResult.lowReg, BBBB);
2085 storeValue(cUnit, rlDest, rlResult);
2092 static bool handleFmt21t(CompilationUnit *cUnit, MIR *mir, BasicBlock *bb,
2101 (gDvmJit.genSuspendPoll || cUnit->jitMode == kJitLoop)) {
2102 genSuspendPoll(cUnit, mir);
2105 RegLocation rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
2106 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2108 opRegImm(cUnit, kOpCmp, rlSrc.lowReg, 0);
2133 dvmCompilerAbort(cUnit);
2135 genConditionalBranch(cUnit, cond, &labelList[bb->taken->id]);
2137 genUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
2167 // Returns true if it added instructions to 'cUnit' to divide 'rlSrc' by 'lit'
2169 static bool handleEasyDivide(CompilationUnit *cUnit, Opcode dalvikOpcode,
2181 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2182 RegLocation rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
2184 int tReg = dvmCompilerAllocTemp(cUnit);
2187 opRegRegImm(cUnit, kOpLsr, tReg, rlSrc.lowReg, 32 - k);
2188 opRegRegReg(cUnit, kOpAdd, tReg, tReg, rlSrc.lowReg);
2189 opRegRegImm(cUnit, kOpAsr, rlResult.lowReg, tReg, k);
2191 opRegRegImm(cUnit, kOpAsr, tReg, rlSrc.lowReg, 31);
2192 opRegRegImm(cUnit, kOpLsr, tReg, tReg, 32 - k);
2193 opRegRegReg(cUnit, kOpAdd, tReg, tReg, rlSrc.lowReg);
2194 opRegRegImm(cUnit, kOpAsr, rlResult.lowReg, tReg, k);
2197 int cReg = dvmCompilerAllocTemp(cUnit);
2198 loadConstant(cUnit, cReg, lit - 1);
2199 int tReg1 = dvmCompilerAllocTemp(cUnit);
2200 int tReg2 = dvmCompilerAllocTemp(cUnit);
2202 opRegRegImm(cUnit, kOpLsr, tReg1, rlSrc.lowReg, 32 - k);
2203 opRegRegReg(cUnit, kOpAdd, tReg2, tReg1, rlSrc.lowReg);
2204 opRegRegReg(cUnit, kOpAnd, tReg2, tReg2, cReg);
2205 opRegRegReg(cUnit, kOpSub, rlResult.lowReg, tReg2, tReg1);
2207 opRegRegImm(cUnit, kOpAsr, tReg1, rlSrc.lowReg, 31);
2208 opRegRegImm(cUnit, kOpLsr, tReg1, tReg1, 32 - k);
2209 opRegRegReg(cUnit, kOpAdd, tReg2, tReg1, rlSrc.lowReg);
2210 opRegRegReg(cUnit, kOpAnd, tReg2, tReg2, cReg);
2211 opRegRegReg(cUnit, kOpSub, rlResult.lowReg, tReg2, tReg1);
2214 storeValue(cUnit, rlDest, rlResult);
2218 // Returns true if it added instructions to 'cUnit' to multiply 'rlSrc' by 'lit'
2220 static bool handleEasyMultiply(CompilationUnit *cUnit,
2239 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2240 cUnit, rlDest, kCoreReg, true);
2243 opRegRegImm(cUnit, kOpLsl, rlResult.lowReg, rlSrc.lowReg,
2249 genMultiplyByTwoBitMultiplier(cUnit, rlSrc, rlResult, lit,
2255 int tReg = dvmCompilerAllocTemp(cUnit);
2256 opRegRegImm(cUnit, kOpLsl, tReg, rlSrc.lowReg, lowestSetBit(lit + 1));
2257 opRegRegReg(cUnit, kOpSub, rlResult.lowReg, tReg, rlSrc.lowReg);
2259 storeValue(cUnit, rlDest, rlResult);
2263 static bool handleFmt22b_Fmt22s(CompilationUnit *cUnit, MIR *mir)
2266 RegLocation rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
2267 RegLocation rlDest = dvmCompilerGetDest(cUnit, mir, 0);
2279 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2280 tReg = dvmCompilerAllocTemp(cUnit);
2281 loadConstant(cUnit, tReg, lit);
2282 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
2283 opRegRegReg(cUnit, kOpSub, rlResult.lowReg,
2285 storeValue(cUnit, rlDest, rlResult);
2296 if (handleEasyMultiply(cUnit, rlSrc, rlDest, lit)) {
2336 genInterpSingleStep(cUnit, mir);
2339 if (handleEasyDivide(cUnit, dalvikOpcode, rlSrc, rlDest, lit)) {
2342 dvmCompilerFlushAllRegs(cUnit); /* Everything to home location */
2343 loadValueDirectFixed(cUnit, rlSrc, r0);
2344 dvmCompilerClobber(cUnit, r0);
2347 LOAD_FUNC_ADDR(cUnit, r2, (int)__aeabi_idiv);
2350 LOAD_FUNC_ADDR(cUnit, r2, (int)__aeabi_idivmod);
2353 loadConstant(cUnit, r1, lit);
2354 opReg(cUnit, kOpBlx, r2);
2355 dvmCompilerClobberCallRegs(cUnit);
2357 rlResult = dvmCompilerGetReturn(cUnit);
2359 rlResult = dvmCompilerGetReturnAlt(cUnit);
2360 storeValue(cUnit, rlDest, rlResult);
2366 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2367 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
2370 genRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2372 opRegRegImm(cUnit, op, rlResult.lowReg, rlSrc.lowReg, lit);
2374 storeValue(cUnit, rlDest, rlResult);
2378 static bool handleFmt22c(CompilationUnit *cUnit, MIR *mir)
2413 mir->meta.calleeMethod : cUnit->method;
2438 RegLocation rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
2439 RegLocation rlDest = dvmCompilerGetDest(cUnit, mir, 0);
2442 (cUnit->method->clazz->pDvmDex->pResClasses[mir->dalvikInsn.vC]);
2450 dvmCompilerFlushAllRegs(cUnit); /* Everything to home location */
2451 genExportPC(cUnit, mir);
2452 loadValueDirectFixed(cUnit, rlSrc, r1); /* Len */
2453 loadConstant(cUnit, r0, (int) classPtr );
2454 LOAD_FUNC_ADDR(cUnit, r3, (int)dvmAllocArrayByClass);
2459 genRegImmCheck(cUnit, kArmCondMi, r1, 0, mir->offset, NULL);
2460 loadConstant(cUnit, r2, ALLOC_DONT_TRACK);
2461 opReg(cUnit, kOpBlx, r3);
2462 dvmCompilerClobberCallRegs(cUnit);
2464 ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
2468 loadConstant(cUnit, r0,
2469 (int) (cUnit->method->insns + mir->offset));
2470 genDispatchToHandler(cUnit, TEMPLATE_THROW_EXCEPTION_COMMON);
2473 ArmLIR *target = newLIR0(cUnit, kArmPseudoTargetLabel);
2476 rlResult = dvmCompilerGetReturn(cUnit);
2477 storeValue(cUnit, rlDest, rlResult);
2482 RegLocation rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
2483 RegLocation rlDest = dvmCompilerGetDest(cUnit, mir, 0);
2486 (cUnit->method->clazz->pDvmDex->pResClasses[mir->dalvikInsn.vC]);
2498 genInterpSingleStep(cUnit, mir);
2501 dvmCompilerFlushAllRegs(cUnit); /* Everything to home location */
2502 loadValueDirectFixed(cUnit, rlSrc, r0); /* Ref */
2503 loadConstant(cUnit, r2, (int) classPtr );
2505 ArmLIR *branch1 = genCmpImmBranch(cUnit, kArmCondEq, r0, 0);
2507 loadWordDisp(cUnit, r0, offsetof(Object, clazz), r1);
2509 LOAD_FUNC_ADDR(cUnit, r3, (int)dvmInstanceofNonTrivial);
2510 loadConstant(cUnit, r0, 1); /* Assume true */
2511 opRegReg(cUnit, kOpCmp, r1, r2);
2512 ArmLIR *branch2 = opCondBranch(cUnit, kArmCondEq);
2513 genRegCopy(cUnit, r0, r1);
2514 genRegCopy(cUnit, r1, r2);
2515 opReg(cUnit, kOpBlx, r3);
2516 dvmCompilerClobberCallRegs(cUnit);
2518 ArmLIR *target = newLIR0(cUnit, kArmPseudoTargetLabel);
2520 rlResult = dvmCompilerGetReturn(cUnit);
2521 storeValue(cUnit, rlDest, rlResult);
2527 genIGetWide(cUnit, mir, fieldOffset);
2537 genIGet(cUnit, mir, kWord, fieldOffset, isVolatile);
2540 genIPutWide(cUnit, mir, fieldOffset);
2548 genIPut(cUnit, mir, kWord, fieldOffset, false, isVolatile);
2552 genIPut(cUnit, mir, kWord, fieldOffset, true, isVolatile);
2556 genInterpSingleStep(cUnit, mir);
2564 static bool handleFmt22cs(CompilationUnit *cUnit, MIR *mir)
2571 genIGet(cUnit, mir, kWord, fieldOffset, false);
2574 genIPut(cUnit, mir, kWord, fieldOffset, false, false);
2577 genIPut(cUnit, mir, kWord, fieldOffset, true, false);
2580 genIGetWide(cUnit, mir, fieldOffset);
2583 genIPutWide(cUnit, mir, fieldOffset);
2593 static bool handleFmt22t(CompilationUnit *cUnit, MIR *mir, BasicBlock *bb,
2602 (gDvmJit.genSuspendPoll || cUnit->jitMode == kJitLoop)) {
2603 genSuspendPoll(cUnit, mir);
2606 RegLocation rlSrc1 = dvmCompilerGetSrc(cUnit, mir, 0);
2607 RegLocation rlSrc2 = dvmCompilerGetSrc(cUnit, mir, 1);
2609 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2610 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2612 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2636 dvmCompilerAbort(cUnit);
2638 genConditionalBranch(cUnit, cond, &labelList[bb->taken->id]);
2640 genUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
2644 static bool handleFmt22x_Fmt32x(CompilationUnit *cUnit, MIR *mir)
2653 storeValue(cUnit, dvmCompilerGetDest(cUnit, mir, 0),
2654 dvmCompilerGetSrc(cUnit, mir, 0));
2659 storeValueWide(cUnit, dvmCompilerGetDestWide(cUnit, mir, 0, 1),
2660 dvmCompilerGetSrcWide(cUnit, mir, 0, 1));
2669 static bool handleFmt23x(CompilationUnit *cUnit, MIR *mir)
2677 return genArithOp( cUnit, mir );
2683 rlDest = dvmCompilerGetSrc(cUnit, mir, 0);
2684 rlSrc1 = dvmCompilerGetSrc(cUnit, mir, 1);
2685 rlSrc2 = dvmCompilerGetSrc(cUnit, mir, 2);
2688 rlDest = dvmCompilerGetSrcWide(cUnit, mir, 0, 1);
2689 rlSrc1 = dvmCompilerGetSrc(cUnit, mir, 2);
2690 rlSrc2 = dvmCompilerGetSrc(cUnit, mir, 3);
2695 rlSrc1 = dvmCompilerGetSrcWide(cUnit, mir, 0, 1);
2696 rlSrc2 = dvmCompilerGetSrcWide(cUnit, mir, 2, 3);
2699 rlSrc1 = dvmCompilerGetSrc(cUnit, mir, 0);
2700 rlSrc2 = dvmCompilerGetSrc(cUnit, mir, 1);
2703 rlDest = dvmCompilerGetDestWide(cUnit, mir, 0, 1);
2706 rlDest = dvmCompilerGetDest(cUnit, mir, 0);
2716 return genCmpFP(cUnit, mir, rlDest, rlSrc1, rlSrc2);
2718 genCmpLong(cUnit, mir, rlDest, rlSrc1, rlSrc2);
2721 genArrayGet(cUnit, mir, kLong, rlSrc1, rlSrc2, rlDest, 3);
2725 genArrayGet(cUnit, mir, kWord, rlSrc1, rlSrc2, rlDest, 2);
2728 genArrayGet(cUnit, mir, kUnsignedByte, rlSrc1, rlSrc2, rlDest, 0);
2731 genArrayGet(cUnit, mir, kSignedByte, rlSrc1, rlSrc2, rlDest, 0);
2734 genArrayGet(cUnit, mir, kUnsignedHalf, rlSrc1, rlSrc2, rlDest, 1);
2737 genArrayGet(cUnit, mir, kSignedHalf, rlSrc1, rlSrc2, rlDest, 1);
2740 genArrayPut(cUnit, mir, kLong, rlSrc1, rlSrc2, rlDest, 3);
2743 genArrayPut(cUnit, mir, kWord, rlSrc1, rlSrc2, rlDest, 2);
2746 genArrayObjectPut(cUnit, mir, rlSrc1, rlSrc2, rlDest, 2);
2750 genArrayPut(cUnit, mir, kUnsignedHalf, rlSrc1, rlSrc2, rlDest, 1);
2754 genArrayPut(cUnit, mir, kUnsignedByte, rlSrc1, rlSrc2, rlDest, 0);
2892 static bool handleFmt31t(CompilationUnit *cUnit, MIR *mir)
2897 RegLocation rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
2899 dvmCompilerFlushAllRegs(cUnit); /* Everything to home location */
2900 genExportPC(cUnit, mir);
2901 loadValueDirectFixed(cUnit, rlSrc, r0);
2902 LOAD_FUNC_ADDR(cUnit, r2, (int)dvmInterpHandleFillArrayData);
2903 loadConstant(cUnit, r1,
2904 (int) (cUnit->method->insns + mir->offset + mir->dalvikInsn.vB));
2905 opReg(cUnit, kOpBlx, r2);
2906 dvmCompilerClobberCallRegs(cUnit);
2908 ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
2909 loadConstant(cUnit, r0,
2910 (int) (cUnit->method->insns + mir->offset));
2911 genDispatchToHandler(cUnit, TEMPLATE_THROW_EXCEPTION_COMMON);
2912 ArmLIR *target = newLIR0(cUnit, kArmPseudoTargetLabel);
2924 RegLocation rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
2925 dvmCompilerFlushAllRegs(cUnit); /* Everything to home location */
2926 loadValueDirectFixed(cUnit, rlSrc, r1);
2927 dvmCompilerLockAllTemps(cUnit);
2929 LOAD_FUNC_ADDR(cUnit, r4PC, (int)findPackedSwitchIndex);
2931 LOAD_FUNC_ADDR(cUnit, r4PC, (int)findSparseSwitchIndex);
2934 loadConstant(cUnit, r0,
2935 (int) (cUnit->method->insns + mir->offset + mir->dalvikInsn.vB));
2937 opRegReg(cUnit, kOpMov, r2, r15pc);
2938 opReg(cUnit, kOpBlx, r4PC);
2939 dvmCompilerClobberCallRegs(cUnit);
2941 opRegReg(cUnit, kOpMov, r15pc, r0);
2955 static void genLandingPadForMispredictedCallee(CompilationUnit *cUnit, MIR *mir,
2967 genUnconditionalBranch(cUnit, &labelList[fallThrough->id]);
2970 dvmCompilerResetRegPool(cUnit);
2971 dvmCompilerClobberAllRegs(cUnit);
2972 dvmCompilerResetNullCheck(cUnit);
2975 ArmLIR *target = newLIR0(cUnit, kArmPseudoTargetLabel);
2981 static bool handleFmt35c_3rc(CompilationUnit *cUnit, MIR *mir,
3005 cUnit->method->clazz->pDvmDex->pResMethods[dInsn->vB]->
3014 genLandingPadForMispredictedCallee(cUnit, mir, bb, labelList);
3018 genProcessArgsNoRange(cUnit, mir, dInsn, &pcrLabel);
3020 genProcessArgsRange(cUnit, mir, dInsn, &pcrLabel);
3022 genInvokeVirtualCommon(cUnit, mir, methodIndex,
3036 assert(calleeMethod == cUnit->method->clazz->super->vtable[
3037 cUnit->method->clazz->pDvmDex->
3041 genProcessArgsNoRange(cUnit, mir, dInsn, &pcrLabel);
3043 genProcessArgsRange(cUnit, mir, dInsn, &pcrLabel);
3049 genInvokeSingletonWholeMethod(cUnit, mir, calleeAddr,
3053 loadConstant(cUnit, r0, (int) calleeMethod);
3055 genInvokeSingletonCommon(cUnit, mir, bb, labelList, pcrLabel,
3066 cUnit->method->clazz->pDvmDex->pResMethods[dInsn->vB]);
3069 genProcessArgsNoRange(cUnit, mir, dInsn, &pcrLabel);
3071 genProcessArgsRange(cUnit, mir, dInsn, &pcrLabel);
3074 loadConstant(cUnit, r0, (int) calleeMethod);
3076 genInvokeSingletonCommon(cUnit, mir, bb, labelList, pcrLabel,
3086 cUnit->method->clazz->pDvmDex->pResMethods[dInsn->vB]);
3089 genProcessArgsNoRange(cUnit, mir, dInsn,
3092 genProcessArgsRange(cUnit, mir, dInsn,
3099 genInvokeSingletonWholeMethod(cUnit, mir, calleeAddr,
3103 loadConstant(cUnit, r0, (int) calleeMethod);
3105 genInvokeSingletonCommon(cUnit, mir, bb, labelList, pcrLabel,
3191 genLandingPadForMispredictedCallee(cUnit, mir, bb, labelList);
3195 genProcessArgsNoRange(cUnit, mir, dInsn, &pcrLabel);
3197 genProcessArgsRange(cUnit, mir, dInsn, &pcrLabel);
3202 loadConstant(cUnit, r4PC,
3203 (int) (cUnit->method->insns + mir->offset));
3207 opRegRegImm(cUnit, kOpAdd, r1, r15pc, 0);
3212 opRegRegImm(cUnit, kOpAdd, r2, r15pc, 0);
3215 genDispatchToHandler(cUnit, gDvmJit.methodTraceSupport ?
3220 genUnconditionalBranch(cUnit, predChainingCell);
3227 int dPC = (int) (cUnit->method->insns + mir->offset);
3233 dvmInsertGrowableList(&cUnit->pcReconstructionList,
3238 genUnconditionalBranch(cUnit, pcrLabel);
3250 genRegCopy(cUnit, r8, r1);
3251 genRegCopy(cUnit, r9, r2);
3252 genRegCopy(cUnit, r10, r3);
3255 genRegCopy(cUnit, r0, r3);
3258 loadConstant(cUnit, r1, dInsn->vB);
3261 loadConstant(cUnit, r2, (int) cUnit->method);
3264 loadConstant(cUnit, r3, (int) cUnit->method->clazz->pDvmDex);
3266 LOAD_FUNC_ADDR(cUnit, r7,
3268 opReg(cUnit, kOpBlx, r7);
3271 dvmCompilerClobberCallRegs(cUnit);
3273 ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
3277 loadConstant(cUnit, r0,
3278 (int) (cUnit->method->insns + mir->offset));
3279 genDispatchToHandler(cUnit, TEMPLATE_THROW_EXCEPTION_COMMON);
3282 ArmLIR *target = newLIR0(cUnit, kArmPseudoTargetLabel);
3286 genRegCopy(cUnit, r1, r8);
3289 ArmLIR *bypassRechaining = genCmpImmBranch(cUnit, kArmCondGt,
3292 LOAD_FUNC_ADDR(cUnit, r7, (int) dvmJitToPatchPredictedChain);
3294 genRegCopy(cUnit, r1, r6SELF);
3295 genRegCopy(cUnit, r2, r9);
3296 genRegCopy(cUnit, r3, r10);
3307 opReg(cUnit, kOpBlx, r7);
3310 addrRetChain = opRegRegImm(cUnit, kOpAdd, r1, r15pc, 0);
3320 genDispatchToHandler(cUnit, gDvmJit.methodTraceSupport ?
3327 genTrap(cUnit, mir->offset, pcrLabel);
3334 genInterpSingleStep(cUnit, mir);
3343 static bool handleFmt35ms_3rms(CompilationUnit *cUnit, MIR *mir,
3367 genLandingPadForMispredictedCallee(cUnit, mir, bb, labelList);
3371 genProcessArgsNoRange(cUnit, mir, dInsn, &pcrLabel);
3373 genProcessArgsRange(cUnit, mir, dInsn, &pcrLabel);
3380 genInvokeVirtualWholeMethod(cUnit, mir, calleeAddr,
3384 genInvokeVirtualCommon(cUnit, mir, methodIndex,
3396 cUnit->method->clazz->super->vtable[dInsn->vB]);
3399 genProcessArgsNoRange(cUnit, mir, dInsn, &pcrLabel);
3401 genProcessArgsRange(cUnit, mir, dInsn, &pcrLabel);
3404 loadConstant(cUnit, r0, (int) calleeMethod);
3406 genInvokeSingletonCommon(cUnit, mir, bb, labelList, pcrLabel,
3422 static bool genInlinedCompareTo(CompilationUnit *cUnit, MIR *mir)
3425 return handleExecuteInlineC(cUnit, mir);
3428 RegLocation rlThis = dvmCompilerGetSrc(cUnit, mir, 0);
3429 RegLocation rlComp = dvmCompilerGetSrc(cUnit, mir, 1);
3431 loadValueDirectFixed(cUnit, rlThis, r0);
3432 loadValueDirectFixed(cUnit, rlComp, r1);
3434 rollback = genNullCheck(cUnit, rlThis.sRegLow, r0, mir->offset, NULL);
3435 genNullCheck(cUnit, rlComp.sRegLow, r1, mir->offset, rollback);
3441 genDispatchToHandler(cUnit, TEMPLATE_STRING_COMPARETO);
3442 storeValue(cUnit, inlinedTarget(cUnit, mir, false),
3443 dvmCompilerGetReturn(cUnit));
3448 static bool genInlinedFastIndexOf(CompilationUnit *cUnit, MIR *mir)
3451 return handleExecuteInlineC(cUnit, mir);
3453 RegLocation rlThis = dvmCompilerGetSrc(cUnit, mir, 0);
3454 RegLocation rlChar = dvmCompilerGetSrc(cUnit, mir, 1);
3456 loadValueDirectFixed(cUnit, rlThis, r0);
3457 loadValueDirectFixed(cUnit, rlChar, r1);
3458 RegLocation rlStart = dvmCompilerGetSrc(cUnit, mir, 2);
3459 loadValueDirectFixed(cUnit, rlStart, r2);
3461 genNullCheck(cUnit, rlThis.sRegLow, r0, mir->offset, NULL);
3462 genDispatchToHandler(cUnit, TEMPLATE_STRING_INDEXOF);
3463 storeValue(cUnit, inlinedTarget(cUnit, mir, false),
3464 dvmCompilerGetReturn(cUnit));
3470 static bool genInlinedStringIsEmptyOrLength(CompilationUnit *cUnit, MIR *mir,
3474 RegLocation rlObj = dvmCompilerGetSrc(cUnit, mir, 0);
3475 RegLocation rlDest = inlinedTarget(cUnit, mir, false);
3476 rlObj = loadValue(cUnit, rlObj, kCoreReg);
3477 RegLocation rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
3478 genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir->offset, NULL);
3479 loadWordDisp(cUnit, rlObj.lowReg, gDvm.offJavaLangString_count,
3483 int tReg = dvmCompilerAllocTemp(cUnit);
3484 opRegReg(cUnit, kOpNeg, tReg, rlResult.lowReg);
3485 opRegRegReg(cUnit, kOpAdc, rlResult.lowReg, rlResult.lowReg, tReg);
3487 storeValue(cUnit, rlDest, rlResult);
3491 static bool genInlinedStringLength(CompilationUnit *cUnit, MIR *mir)
3493 return genInlinedStringIsEmptyOrLength(cUnit, mir, false);
3496 static bool genInlinedStringIsEmpty(CompilationUnit *cUnit, MIR *mir)
3498 return genInlinedStringIsEmptyOrLength(cUnit, mir, true);
3501 static bool genInlinedStringCharAt(CompilationUnit *cUnit, MIR *mir)
3504 RegLocation rlObj = dvmCompilerGetSrc(cUnit, mir, 0);
3505 RegLocation rlIdx = dvmCompilerGetSrc(cUnit, mir, 1);
3506 RegLocation rlDest = inlinedTarget(cUnit, mir, false);
3508 rlObj = loadValue(cUnit, rlObj, kCoreReg);
3509 rlIdx = loadValue(cUnit, rlIdx, kCoreReg);
3510 int regMax = dvmCompilerAllocTemp(cUnit);
3511 int regOff = dvmCompilerAllocTemp(cUnit);
3512 int regPtr = dvmCompilerAllocTemp(cUnit);
3513 ArmLIR *pcrLabel = genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg,
3515 loadWordDisp(cUnit, rlObj.lowReg, gDvm.offJavaLangString_count, regMax);
3516 loadWordDisp(cUnit, rlObj.lowReg, gDvm.offJavaLangString_offset, regOff);
3517 loadWordDisp(cUnit, rlObj.lowReg, gDvm.offJavaLangString_value, regPtr);
3518 genBoundsCheck(cUnit, rlIdx.lowReg, regMax, mir->offset, pcrLabel);
3519 dvmCompilerFreeTemp(cUnit, regMax);
3520 opRegImm(cUnit, kOpAdd, regPtr, contents);
3521 opRegReg(cUnit, kOpAdd, regOff, rlIdx.lowReg);
3522 rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
3523 loadBaseIndexed(cUnit, regPtr, regOff, rlResult.lowReg, 1, kUnsignedHalf);
3524 storeValue(cUnit
3528 static bool genInlinedAbsInt(CompilationUnit *cUnit, MIR *mir)
3530 RegLocation rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
3531 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
3532 RegLocation rlDest = inlinedTarget(cUnit, mir, false);
3533 RegLocation rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
3534 int signReg = dvmCompilerAllocTemp(cUnit);
3540 opRegRegImm(cUnit, kOpAsr, signReg, rlSrc.lowReg, 31);
3541 opRegRegReg(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, signReg);
3542 opRegReg(cUnit, kOpXor, rlResult.lowReg, signReg);
3543 storeValue(cUnit, rlDest, rlResult);
3547 static bool genInlinedAbsLong(CompilationUnit *cUnit, MIR *mir)
3549 RegLocation rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1);
3550 RegLocation rlDest = inlinedTargetWide(cUnit, mir, false);
3551 rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
3552 RegLocation rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
3553 int signReg = dvmCompilerAllocTemp(cUnit);
3560 opRegRegImm(cUnit, kOpAsr, signReg, rlSrc.highReg, 31);
3561 opRegRegReg(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, signReg);
3562 opRegRegReg(cUnit, kOpAdc, rlResult.highReg, rlSrc.highReg, signReg);
3563 opRegReg(cUnit, kOpXor, rlResult.lowReg, signReg);
3564 opRegReg(cUnit, kOpXor, rlResult.highReg, signReg);
3565 storeValueWide(cUnit, rlDest, rlResult);
3569 static bool genInlinedIntFloatConversion(CompilationUnit *cUnit, MIR *mir)
3572 RegLocation rlSrc = dvmCompilerGetSrc(cUnit, mir, 0);
3573 RegLocation rlDest = inlinedTarget(cUnit, mir, false);
3574 storeValue(cUnit, rlDest, rlSrc);
3578 static bool genInlinedLongDoubleConversion(CompilationUnit *cUnit, MIR *mir)
3581 RegLocation rlSrc = dvmCompilerGetSrcWide(cUnit, mir, 0, 1);
3582 RegLocation rlDest = inlinedTargetWide(cUnit, mir, false);
3583 storeValueWide(cUnit, rlDest, rlSrc);
3592 static bool handleExecuteInlineC(CompilationUnit *cUnit, MIR *mir)
3600 dvmCompilerAbort(cUnit);
3602 dvmCompilerFlushAllRegs(cUnit); /* Everything to home location */
3603 dvmCompilerClobberCallRegs(cUnit);
3604 dvmCompilerClobber(cUnit, r4PC);
3605 dvmCompilerClobber(cUnit, r7);
3607 opRegRegImm(cUnit, kOpAdd, r4PC, r6SELF, offset);
3608 opImm(cUnit, kOpPush, (1<<r4PC) | (1<<r7));
3609 LOAD_FUNC_ADDR(cUnit, r4PC, fn);
3610 genExportPC(cUnit, mir);
3612 loadValueDirect(cUnit, dvmCompilerGetSrc(cUnit, mir, i), i);
3614 opReg(cUnit, kOpBlx, r4PC);
3615 opRegImm(cUnit, kOpAdd, r13sp, 8);
3617 ArmLIR *branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
3618 loadConstant(cUnit, r0, (int) (cUnit->method->insns + mir->offset));
3619 genDispatchToHandler(cUnit, TEMPLATE_THROW_EXCEPTION_COMMON);
3620 ArmLIR *target = newLIR0(cUnit, kArmPseudoTargetLabel);
3630 static bool handleExecuteInline(CompilationUnit *cUnit, MIR *mir)
3641 return genInlinedStringLength(cUnit, mir);
3643 return genInlinedStringIsEmpty(cUnit, mir);
3645 return genInlinedAbsInt(cUnit, mir);
3647 return genInlinedAbsLong(cUnit, mir);
3649 return genInlinedMinMaxInt(cUnit, mir, true);
3651 return genInlinedMinMaxInt(cUnit, mir, false);
3653 return genInlinedStringCharAt(cUnit, mir);
3655 return genInlineSqrt(cUnit, mir);
3657 return genInlinedAbsFloat(cUnit, mir);
3659 return genInlinedAbsDouble(cUnit, mir);
3661 return genInlinedCompareTo(cUnit, mir);
3663 return genInlinedFastIndexOf(cUnit, mir);
3666 return genInlinedIntFloatConversion(cUnit, mir);
3669 return genInlinedLongDoubleConversion(cUnit, mir);
3680 return handleExecuteInlineC(cUnit, mir);
3682 dvmCompilerAbort(cUnit);
3686 static bool handleFmt51l(CompilationUnit *cUnit, MIR *mir)
3689 RegLocation rlDest = dvmCompilerGetDestWide(cUnit, mir, 0, 1);
3690 RegLocation rlResult = dvmCompilerEvalLoc(cUnit, rlDest, kCoreReg, true);
3691 loadConstantNoClobber(cUnit, rlResult.lowReg,
3693 loadConstantNoClobber(cUnit, rlResult.highReg,
3695 storeValueWide(cUnit, rlDest, rlResult);
3717 static void insertChainingSwitch(CompilationUnit *cUnit)
3719 ArmLIR *branch = newLIR0(cUnit, kThumbBUncond);
3720 newLIR2(cUnit, kThumbOrr, r0, r0);
3721 ArmLIR *target = newLIR0(cUnit, kArmPseudoTargetLabel);
3727 static void handleNormalChainingCell(CompilationUnit *cUnit,
3734 insertChainingSwitch(cUnit);
3735 newLIR3(cUnit, kThumbLdrRRI5, r0, r6SELF,
3738 newLIR1(cUnit, kThumbBlxR, r0);
3739 addWordData(cUnit, NULL, (int) (cUnit->method->insns + offset));
3746 static void handleHotChainingCell(CompilationUnit *cUnit,
3753 insertChainingSwitch(cUnit);
3754 newLIR3(cUnit, kThumbLdrRRI5, r0, r6SELF,
3757 newLIR1(cUnit, kThumbBlxR, r0);
3758 addWordData(cUnit, NULL, (int) (cUnit->method->insns + offset));
3762 static void handleBackwardBranchChainingCell(CompilationUnit *cUnit,
3769 insertChainingSwitch(cUnit);
3771 newLIR3(cUnit, kThumbLdrRRI5, r0, r6SELF,
3775 newLIR3(cUnit, kThumbLdrRRI5, r0, r6SELF,
3778 newLIR1(cUnit, kThumbBlxR, r0);
3779 addWordData(cUnit, NULL, (int) (cUnit->method->insns + offset));
3783 static void handleInvokeSingletonChainingCell(CompilationUnit *cUnit,
3790 insertChainingSwitch(cUnit);
3791 newLIR3(cUnit, kThumbLdrRRI5, r0, r6SELF,
3794 newLIR1(cUnit, kThumbBlxR, r0);
3795 addWordData(cUnit, NULL, (int) (callee->insns));
3799 static void handleInvokePredictedChainingCell(CompilationUnit *cUnit)
3803 addWordData(cUnit, NULL, PREDICTED_CHAIN_BX_PAIR_INIT);
3805 addWordData(cUnit, NULL, PREDICTED_CHAIN_CLAZZ_INIT);
3807 addWordData(cUnit, NULL, PREDICTED_CHAIN_METHOD_INIT);
3812 addWordData(cUnit, NULL, PREDICTED_CHAIN_COUNTER_INIT);
3816 static void handlePCReconstruction(CompilationUnit *cUnit,
3820 (ArmLIR **) cUnit->pcReconstructionList.elemList;
3821 int numElems = cUnit->pcReconstructionList.numUsed;
3829 newLIR0(cUnit, kThumbUndefined);
3833 dvmCompilerAppendLIR(cUnit, (LIR *) pcrLabel[i]);
3835 loadConstant(cUnit, r0, pcrLabel[i]->operands[0]);
3836 genUnconditionalBranch(cUnit, targetLabel);
3857 static void genHoistedChecksForCountUpLoop(CompilationUnit *cUnit, MIR *mir)
3869 RegLocation rlArray = cUnit->regLocation[mir->dalvikInsn.vA];
3870 RegLocation rlIdxEnd = cUnit->regLocation[mir->dalvikInsn.vC];
3873 rlArray = loadValue(cUnit, rlArray, kCoreReg);
3874 rlIdxEnd = loadValue(cUnit, rlIdxEnd, kCoreReg);
3875 genRegImmCheck(cUnit, kArmCondEq, rlArray.lowReg, 0, 0,
3876 (ArmLIR *) cUnit->loopAnalysis->branchToPCR);
3879 regLength = dvmCompilerAllocTemp(cUnit);
3880 loadWordDisp(cUnit, rlArray.lowReg, lenOffset, regLength);
3892 int tReg = dvmCompilerAllocTemp(cUnit);
3893 opRegRegImm(cUnit, kOpAdd, tReg, rlIdxEnd.lowReg, delta);
3895 dvmCompilerFreeTemp(cUnit, tReg);
3898 genRegRegCheck(cUnit, kArmCondGe, rlIdxEnd.lowReg, regLength, 0,
3899 (ArmLIR *) cUnit->loopAnalysis->branchToPCR);
3910 static void genHoistedChecksForCountDownLoop(CompilationUnit *cUnit, MIR *mir)
3914 const int regLength = dvmCompilerAllocTemp(cUnit);
3916 RegLocation rlArray = cUnit->regLocation[mir->dalvikInsn.vA];
3917 RegLocation rlIdxInit = cUnit->regLocation[mir->dalvikInsn.vB];
3920 rlArray = loadValue(cUnit, rlArray, kCoreReg);
3921 rlIdxInit = loadValue(cUnit, rlIdxInit, kCoreReg);
3922 genRegImmCheck(cUnit, kArmCondEq, rlArray.lowReg, 0, 0,
3923 (ArmLIR *) cUnit->loopAnalysis->branchToPCR);
3926 loadWordDisp(cUnit, rlArray.lowReg, lenOffset, regLength);
3929 int tReg = dvmCompilerAllocTemp(cUnit);
3930 opRegRegImm(cUnit, kOpAdd, tReg, rlIdxInit.lowReg, maxC);
3932 dvmCompilerFreeTemp(cUnit, tReg);
3936 genRegRegCheck(cUnit, kArmCondGe, rlIdxInit.lowReg, regLength, 0,
3937 (ArmLIR *) cUnit->loopAnalysis->branchToPCR);
3944 static void genHoistedLowerBoundCheck(CompilationUnit *cUnit, MIR *mir)
3948 RegLocation rlIdx = cUnit->regLocation[mir->dalvikInsn.vA];
3951 rlIdx = loadValue(cUnit, rlIdx, kCoreReg);
3954 genRegImmCheck(cUnit, kArmCondLt, rlIdx.lowReg, -minC, 0,
3955 (ArmLIR *) cUnit->loopAnalysis->branchToPCR);
4042 static void genValidationForPredictedInline(CompilationUnit *cUnit, MIR *mir)
4045 RegLocation rlThis = cUnit->regLocation[mir->dalvikInsn.vC];
4047 rlThis = loadValue(cUnit, rlThis, kCoreReg);
4048 int regPredictedClass = dvmCompilerAllocTemp(cUnit);
4049 loadClassPointer(cUnit, regPredictedClass, (int) callsiteInfo);
4050 genNullCheck(cUnit, rlThis.sRegLow, rlThis.lowReg, mir->offset,
4052 int regActualClass = dvmCompilerAllocTemp(cUnit);
4053 loadWordDisp(cUnit, rlThis.lowReg, offsetof(Object, clazz), regActualClass);
4054 opRegReg(cUnit, kOpCmp, regPredictedClass, regActualClass);
4059 callsiteInfo->misPredBranchOver = (LIR *) opCondBranch(cUnit, kArmCondNe);
4063 static void handleExtendedMIR(CompilationUnit *cUnit, MIR *mir)
4069 newLIR1(cUnit, kArmPseudoExtended, (int) msg);
4073 char *ssaString = dvmCompilerGetSSAString(cUnit, mir->ssaRep);
4074 newLIR1(cUnit, kArmPseudoSSARep, (int) ssaString);
4078 genHoistedChecksForCountUpLoop(cUnit, mir);
4082 genHoistedChecksForCountDownLoop(cUnit, mir);
4086 genHoistedLowerBoundCheck(cUnit, mir);
4090 genUnconditionalBranch(cUnit,
4091 (ArmLIR *) cUnit->loopAnalysis->branchToPCR);
4095 genValidationForPredictedInline(cUnit, mir);
4110 static void setupLoopEntryBlock(CompilationUnit *cUnit, BasicBlock *entry,
4117 (int) (cUnit->method->insns + entry->startOffset);
4120 dvmInsertGrowableList(&cUnit->pcReconstructionList, (intptr_t) pcrLabel);
4130 cUnit->loopAnalysis->branchToBody = (LIR *) branchToBody;
4136 cUnit->loopAnalysis->branchToPCR = (LIR *) branchToPCR;
4166 void dvmCompilerMIR2LIR(CompilationUnit *cUnit)
4170 (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR) * cUnit->numBlocks, true);
4183 dvmCompilerDataFlowAnalysisDispatcher(cUnit, dvmCompilerClearVisitedFlag,
4187 dvmGrowableListIteratorInit(&cUnit->blockList, &iterator);
4190 cUnit->profileCodeSize = genTraceProfileEntry(cUnit);
4204 newLIR0(cUnit, kArmPseudoPseudoAlign4);
4210 dvmCompilerAppendLIR(cUnit, (LIR *) &labelList[i]);
4218 setupLoopEntryBlock(cUnit, bb,
4228 dvmCompilerResetRegPool(cUnit);
4229 dvmCompilerClobberAllRegs(cUnit);
4230 dvmCompilerResetNullCheck(cUnit);
4273 handlePCReconstruction(cUnit,
4274 &labelList[cUnit->puntBlock->id]);
4278 if (cUnit->pcReconstructionList.numUsed) {
4279 loadWordDisp(cUnit, r6SELF, offsetof(Thread,
4282 opReg(cUnit, kOpBlx, r1);
4304 for (BasicBlock *nextBB = bb; nextBB != NULL; nextBB = cUnit->nextCodegenBlock) {
4307 cUnit->nextCodegenBlock = NULL;
4311 dvmCompilerResetRegPool(cUnit);
4313 dvmCompilerClobberAllRegs(cUnit);
4317 dvmCompilerResetDefTracking(cUnit);
4321 handleExtendedMIR(cUnit, mir);
4345 if (headLIR == NULL || cUnit->printMe == true) {
4347 newLIR2(cUnit, kArmPseudoDalvikByteCodeBoundary,
4362 if (cUnit->printMe && mir->ssaRep) {
4363 char *ssaString = dvmCompilerGetSSAString(cUnit,
4365 newLIR1(cUnit, kArmPseudoSSARep, (int) ssaString);
4379 if (singleStepMe || cUnit->allSingleStep) {
4381 genInterpSingleStep(cUnit, mir);
4388 notHandled = handleFmt10t_Fmt20t_Fmt30t(cUnit,
4392 notHandled = handleFmt10x(cUnit, mir);
4396 notHandled = handleFmt11n_Fmt31i(cUnit, mir);
4399 notHandled = handleFmt11x(cUnit, mir);
4402 notHandled = handleFmt12x(cUnit, mir);
4405 notHandled = handleFmt20bc(cUnit, mir);
4409 notHandled = handleFmt21c_Fmt31c(cUnit, mir);
4412 notHandled = handleFmt21h(cUnit, mir);
4415 notHandled = handleFmt21s(cUnit, mir);
4418 notHandled = handleFmt21t(cUnit, mir, bb,
4423 notHandled = handleFmt22b_Fmt22s(cUnit, mir);
4426 notHandled = handleFmt22c(cUnit, mir);
4429 notHandled = handleFmt22cs(cUnit, mir);
4432 notHandled = handleFmt22t(cUnit, mir, bb,
4437 notHandled = handleFmt22x_Fmt32x(cUnit, mir);
4440 notHandled = handleFmt23x(cUnit, mir);
4443 notHandled = handleFmt31t(cUnit, mir);
4447 notHandled = handleFmt35c_3rc(cUnit, mir, bb,
4452 notHandled = handleFmt35ms_3rms(cUnit, mir, bb,
4457 notHandled = handleExecuteInline(cUnit, mir);
4460 notHandled = handleFmt51l(cUnit, mir);
4472 dvmCompilerAbort(cUnit);
4479 dvmCompilerAppendLIR(cUnit,
4480 (LIR *) cUnit->loopAnalysis->branchToBody);
4481 dvmCompilerAppendLIR(cUnit,
4482 (LIR *) cUnit->loopAnalysis->branchToPCR);
4490 dvmCompilerApplyLocalOptimizations(cUnit, (LIR *) headLIR,
4491 cUnit->lastLIRInsn);
4502 genUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
4511 cUnit->numChainingCells[i] = chainingListByType[i].numUsed;
4514 if (cUnit->numChainingCells[i] == 0)
4518 cUnit->firstChainingLIR[i] = (LIR *) &labelList[blockIdList[0]];
4523 (BasicBlock *) dvmGrowableListGetElement(&cUnit->blockList,
4527 newLIR0(cUnit, kArmPseudoPseudoAlign4);
4530 dvmCompilerAppendLIR(cUnit, (LIR *) &labelList[blockId]);
4535 handleNormalChainingCell(cUnit, chainingBlock->startOffset);
4538 handleInvokeSingletonChainingCell(cUnit,
4542 handleInvokePredictedChainingCell(cUnit);
4545 handleHotChainingCell(cUnit, chainingBlock->startOffset);
4548 handleBackwardBranchChainingCell(cUnit,
4553 dvmCompilerAbort(cUnit);
4559 cUnit->chainingCellBottom = (LIR *) newLIR0(cUnit, kArmChainingCellBottom);
4565 if (cUnit->switchOverflowPad) {
4566 loadConstant(cUnit, r0, (int) cUnit->switchOverflowPad);
4567 loadWordDisp(cUnit, r6SELF, offsetof(Thread,
4569 opRegReg(cUnit, kOpAdd, r1, r1);
4570 opRegRegReg(cUnit, kOpAdd, r4PC, r0, r1);
4572 loadConstant(cUnit, r0, kSwitchOverflow);
4574 opReg(cUnit, kOpBlx, r2);
4577 dvmCompilerApplyGlobalOptimizations(cUnit);
4580 selfVerificationBranchInsertPass(cUnit);
4711 ArmLIR* dvmCompilerRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc)
4713 return genRegCopyNoInsert(cUnit, rDest, rSrc);
4717 ArmLIR* dvmCompilerRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
4719 return genRegCopy(cUnit, rDest, rSrc);
4723 void dvmCompilerRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi,
4726 genRegCopyWide(cUnit, destLo, destHi, srcLo, srcHi);
4729 void dvmCompilerFlushRegImpl(CompilationUnit *cUnit, int rBase,
4732 storeBaseDisp(cUnit, rBase, displacement, rSrc, size);
4735 void dvmCompilerFlushRegWideImpl(CompilationUnit *cUnit, int rBase,
4738 storeBaseDispWide(cUnit, rBase, displacement, rSrcLo, rSrcHi);