/* * Load a class pointer value into a fixed or temp register. Target * register is clobbered, and marked inUse. */ static ArmLIR *loadClassPointer(CompilationUnit *cUnit, int rDest, int value) { ArmLIR *res; cUnit->hasClassLiterals = true; if (dvmCompilerIsTemp(cUnit, rDest)) { dvmCompilerClobber(cUnit, rDest); dvmCompilerMarkInUse(cUnit, rDest); } ArmLIR *dataTarget = scanLiteralPool(cUnit->classPointerList, value, 0); if (dataTarget == NULL) { dataTarget = addWordData(cUnit, &cUnit->classPointerList, value); /* Counts the number of class pointers in this translation */ cUnit->numClassPointers++; } ArmLIR *loadPcRel = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); loadPcRel->opcode = kThumbLdrPcRel; loadPcRel->generic.target = (LIR *) dataTarget; loadPcRel->operands[0] = rDest; setupResourceMasks(loadPcRel); setMemRefType(loadPcRel, true, kLiteral); loadPcRel->aliasInfo = dataTarget->operands[0]; res = loadPcRel; dvmCompilerAppendLIR(cUnit, (LIR *) loadPcRel); return res; }
/* * Load a immediate using a shortcut if possible; otherwise * grab from the per-translation literal pool. If target is * a high register, build constant into a low register and copy. * * No additional register clobbering operation performed. Use this version when * 1) rDest is freshly returned from dvmCompilerAllocTemp or * 2) The codegen is under fixed register usage */ static ArmLIR *loadConstantNoClobber(CompilationUnit *cUnit, int rDest, int value) { ArmLIR *res; int tDest = LOWREG(rDest) ? rDest : dvmCompilerAllocTemp(cUnit); /* See if the value can be constructed cheaply */ if ((value >= 0) && (value <= 255)) { res = newLIR2(cUnit, kThumbMovImm, tDest, value); if (rDest != tDest) { opRegReg(cUnit, kOpMov, rDest, tDest); dvmCompilerFreeTemp(cUnit, tDest); } return res; } else if ((value & 0xFFFFFF00) == 0xFFFFFF00) { res = newLIR2(cUnit, kThumbMovImm, tDest, ~value); newLIR2(cUnit, kThumbMvn, tDest, tDest); if (rDest != tDest) { opRegReg(cUnit, kOpMov, rDest, tDest); dvmCompilerFreeTemp(cUnit, tDest); } return res; } /* No shortcut - go ahead and use literal pool */ ArmLIR *dataTarget = scanLiteralPool(cUnit->literalList, value, 255); if (dataTarget == NULL) { dataTarget = addWordData(cUnit, &cUnit->literalList, value); } ArmLIR *loadPcRel = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); loadPcRel->opcode = kThumbLdrPcRel; loadPcRel->generic.target = (LIR *) dataTarget; loadPcRel->operands[0] = tDest; setupResourceMasks(loadPcRel); setMemRefType(loadPcRel, true, kLiteral); loadPcRel->aliasInfo = dataTarget->operands[0]; res = loadPcRel; dvmCompilerAppendLIR(cUnit, (LIR *) loadPcRel); /* * To save space in the constant pool, we use the ADD_RRI8 instruction to * add up to 255 to an existing constant value. */ if (dataTarget->operands[0] != value) { newLIR2(cUnit, kThumbAddRI8, tDest, value - dataTarget->operands[0]); } if (rDest != tDest) { opRegReg(cUnit, kOpMov, rDest, tDest); dvmCompilerFreeTemp(cUnit, tDest); } return res; }
/* Add a 64-bit constant to the literal pool or mixed with code */ ArmLIR* addWideData(CompilationUnit* cUnit, LIR** constantListP, int valLo, int valHi) { addWordData(cUnit, constantListP, valHi); return addWordData(cUnit, constantListP, valLo); }