1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17/* 18 * This file contains register alloction support and is intended to be 19 * included by: 20 * 21 * Codegen-$(TARGET_ARCH_VARIANT).c 22 * 23 */ 24 25#include "compiler/CompilerUtility.h" 26#include "compiler/CompilerIR.h" 27#include "compiler/Dataflow.h" 28#include "compiler/codegen/arm/ArmLIR.h" 29 30/* 31 * Return most flexible allowed register class based on size. 32 * Bug: 2813841 33 * Must use a core register for data types narrower than word (due 34 * to possible unaligned load/store. 35 */ 36static inline RegisterClass dvmCompilerRegClassBySize(OpSize size) 37{ 38 return (size == kUnsignedHalf || 39 size == kSignedHalf || 40 size == kUnsignedByte || 41 size == kSignedByte ) ? kCoreReg : kAnyReg; 42} 43 44static inline int dvmCompilerS2VReg(CompilationUnit *cUnit, int sReg) 45{ 46 assert(sReg != INVALID_SREG); 47 return DECODE_REG(dvmConvertSSARegToDalvik(cUnit, sReg)); 48} 49 50/* Reset the tracker to unknown state */ 51static inline void dvmCompilerResetNullCheck(CompilationUnit *cUnit) 52{ 53 dvmClearAllBits(cUnit->regPool->nullCheckedRegs); 54} 55 56/* 57 * Get the "real" sreg number associated with an sReg slot. In general, 58 * sReg values passed through codegen are the SSA names created by 59 * dataflow analysis and refer to slot numbers in the cUnit->regLocation 60 * array. However, renaming is accomplished by simply replacing RegLocation 61 * entries in the cUnit->reglocation[] array. Therefore, when location 62 * records for operands are first created, we need to ask the locRecord 63 * identified by the dataflow pass what it's new name is. 64 */ 65 66static inline int dvmCompilerSRegHi(int lowSreg) { 67 return (lowSreg == INVALID_SREG) ? INVALID_SREG : lowSreg + 1; 68} 69 70 71static inline bool dvmCompilerLiveOut(CompilationUnit *cUnit, int sReg) 72{ 73 //TODO: fully implement 74 return true; 75} 76 77static inline int dvmCompilerSSASrc(MIR *mir, int num) 78{ 79 assert(mir->ssaRep->numUses > num); 80 return mir->ssaRep->uses[num]; 81} 82 83extern RegLocation dvmCompilerEvalLoc(CompilationUnit *cUnit, RegLocation loc, 84 int regClass, bool update); 85/* Mark a temp register as dead. Does not affect allocation state. */ 86extern void dvmCompilerClobber(CompilationUnit *cUnit, int reg); 87 88extern RegLocation dvmCompilerUpdateLoc(CompilationUnit *cUnit, 89 RegLocation loc); 90 91/* see comments for updateLoc */ 92extern RegLocation dvmCompilerUpdateLocWide(CompilationUnit *cUnit, 93 RegLocation loc); 94 95/* Clobber all of the temps that might be used by a handler. */ 96extern void dvmCompilerClobberHandlerRegs(CompilationUnit *cUnit); 97 98extern void dvmCompilerMarkLive(CompilationUnit *cUnit, int reg, int sReg); 99 100extern void dvmCompilerMarkDirty(CompilationUnit *cUnit, int reg); 101 102extern void dvmCompilerMarkPair(CompilationUnit *cUnit, int lowReg, 103 int highReg); 104 105extern void dvmCompilerMarkClean(CompilationUnit *cUnit, int reg); 106 107extern void dvmCompilerResetDef(CompilationUnit *cUnit, int reg); 108 109extern void dvmCompilerResetDefLoc(CompilationUnit *cUnit, RegLocation rl); 110 111/* Set up temp & preserved register pools specialized by target */ 112extern void dvmCompilerInitPool(RegisterInfo *regs, int *regNums, int num); 113 114/* 115 * Mark the beginning and end LIR of a def sequence. Note that 116 * on entry start points to the LIR prior to the beginning of the 117 * sequence. 118 */ 119extern void dvmCompilerMarkDef(CompilationUnit *cUnit, RegLocation rl, 120 LIR *start, LIR *finish); 121/* 122 * Mark the beginning and end LIR of a def sequence. Note that 123 * on entry start points to the LIR prior to the beginning of the 124 * sequence. 125 */ 126extern void dvmCompilerMarkDefWide(CompilationUnit *cUnit, RegLocation rl, 127 LIR *start, LIR *finish); 128 129extern RegLocation dvmCompilerGetSrcWide(CompilationUnit *cUnit, MIR *mir, 130 int low, int high); 131 132extern RegLocation dvmCompilerGetDestWide(CompilationUnit *cUnit, MIR *mir, 133 int low, int high); 134// Get the LocRecord associated with an SSA name use. 135extern RegLocation dvmCompilerGetSrc(CompilationUnit *cUnit, MIR *mir, int num); 136 137// Get the LocRecord associated with an SSA name def. 138extern RegLocation dvmCompilerGetDest(CompilationUnit *cUnit, MIR *mir, 139 int num); 140 141extern RegLocation dvmCompilerGetReturnWide(CompilationUnit *cUnit); 142 143/* Clobber all regs that might be used by an external C call */ 144extern void dvmCompilerClobberCallRegs(CompilationUnit *cUnit); 145 146extern RegisterInfo *dvmCompilerIsTemp(CompilationUnit *cUnit, int reg); 147 148extern void dvmCompilerMarkInUse(CompilationUnit *cUnit, int reg); 149 150extern int dvmCompilerAllocTemp(CompilationUnit *cUnit); 151 152extern int dvmCompilerAllocTempFloat(CompilationUnit *cUnit); 153 154//REDO: too many assumptions. 155extern int dvmCompilerAllocTempDouble(CompilationUnit *cUnit); 156 157extern void dvmCompilerFreeTemp(CompilationUnit *cUnit, int reg); 158 159extern void dvmCompilerResetDefLocWide(CompilationUnit *cUnit, RegLocation rl); 160 161extern void dvmCompilerResetDefTracking(CompilationUnit *cUnit); 162 163/* Kill the corresponding bit in the null-checked register list */ 164extern void dvmCompilerKillNullCheckedLoc(CompilationUnit *cUnit, 165 RegLocation loc); 166 167//FIXME - this needs to also check the preserved pool. 168extern RegisterInfo *dvmCompilerIsLive(CompilationUnit *cUnit, int reg); 169 170/* To be used when explicitly managing register use */ 171extern void dvmCompilerLockAllTemps(CompilationUnit *cUnit); 172 173extern void dvmCompilerFlushAllRegs(CompilationUnit *cUnit); 174 175extern RegLocation dvmCompilerGetReturnWideAlt(CompilationUnit *cUnit); 176 177extern RegLocation dvmCompilerGetReturn(CompilationUnit *cUnit); 178 179extern RegLocation dvmCompilerGetReturnAlt(CompilationUnit *cUnit); 180 181/* Clobber any temp associated with an sReg. Could be in either class */ 182extern void dvmCompilerClobberSReg(CompilationUnit *cUnit, int sReg); 183 184/* Return a temp if one is available, -1 otherwise */ 185extern int dvmCompilerAllocFreeTemp(CompilationUnit *cUnit); 186 187/* 188 * Similar to dvmCompilerAllocTemp(), but forces the allocation of a specific 189 * register. No check is made to see if the register was previously 190 * allocated. Use with caution. 191 */ 192extern void dvmCompilerLockTemp(CompilationUnit *cUnit, int reg); 193 194extern RegLocation dvmCompilerWideToNarrow(CompilationUnit *cUnit, 195 RegLocation rl); 196 197/* 198 * Free all allocated temps in the temp pools. Note that this does 199 * not affect the "liveness" of a temp register, which will stay 200 * live until it is either explicitly killed or reallocated. 201 */ 202extern void dvmCompilerResetRegPool(CompilationUnit *cUnit); 203 204extern void dvmCompilerClobberAllRegs(CompilationUnit *cUnit); 205 206extern void dvmCompilerResetDefTracking(CompilationUnit *cUnit); 207