Home | History | Annotate | Download | only in mips
      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/mips/MipsLIR.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  */
     36 static inline RegisterClass dvmCompilerRegClassBySize(OpSize size)
     37 {
     38     return (size == kUnsignedHalf ||
     39             size == kSignedHalf ||
     40             size == kUnsignedByte ||
     41             size == kSignedByte ) ? kCoreReg : kAnyReg;
     42 }
     43 
     44 static 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 */
     51 static 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 
     66 static inline int dvmCompilerSRegHi(int lowSreg) {
     67     return (lowSreg == INVALID_SREG) ? INVALID_SREG : lowSreg + 1;
     68 }
     69 
     70 
     71 static inline bool dvmCompilerLiveOut(CompilationUnit *cUnit, int sReg)
     72 {
     73     //TODO: fully implement
     74     return true;
     75 }
     76 
     77 static inline int dvmCompilerSSASrc(MIR *mir, int num)
     78 {
     79     assert(mir->ssaRep->numUses > num);
     80     return mir->ssaRep->uses[num];
     81 }
     82 
     83 extern RegLocation dvmCompilerEvalLoc(CompilationUnit *cUnit, RegLocation loc,
     84                                       int regClass, bool update);
     85 /* Mark a temp register as dead.  Does not affect allocation state. */
     86 extern void dvmCompilerClobber(CompilationUnit *cUnit, int reg);
     87 
     88 extern RegLocation dvmCompilerUpdateLoc(CompilationUnit *cUnit,
     89                                         RegLocation loc);
     90 
     91 /* see comments for updateLoc */
     92 extern RegLocation dvmCompilerUpdateLocWide(CompilationUnit *cUnit,
     93                                             RegLocation loc);
     94 
     95 /* Clobber all of the temps that might be used by a handler. */
     96 extern void dvmCompilerClobberHandlerRegs(CompilationUnit *cUnit);
     97 
     98 extern void dvmCompilerMarkLive(CompilationUnit *cUnit, int reg, int sReg);
     99 
    100 extern void dvmCompilerMarkDirty(CompilationUnit *cUnit, int reg);
    101 
    102 extern void dvmCompilerMarkPair(CompilationUnit *cUnit, int lowReg,
    103                                 int highReg);
    104 
    105 extern void dvmCompilerMarkClean(CompilationUnit *cUnit, int reg);
    106 
    107 extern void dvmCompilerResetDef(CompilationUnit *cUnit, int reg);
    108 
    109 extern void dvmCompilerResetDefLoc(CompilationUnit *cUnit, RegLocation rl);
    110 
    111 /* Set up temp & preserved register pools specialized by target */
    112 extern 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  */
    119 extern 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  */
    126 extern void dvmCompilerMarkDefWide(CompilationUnit *cUnit, RegLocation rl,
    127                                    LIR *start, LIR *finish);
    128 
    129 extern RegLocation dvmCompilerGetSrcWide(CompilationUnit *cUnit, MIR *mir,
    130                                          int low, int high);
    131 
    132 extern RegLocation dvmCompilerGetDestWide(CompilationUnit *cUnit, MIR *mir,
    133                                           int low, int high);
    134 // Get the LocRecord associated with an SSA name use.
    135 extern RegLocation dvmCompilerGetSrc(CompilationUnit *cUnit, MIR *mir, int num);
    136 
    137 // Get the LocRecord associated with an SSA name def.
    138 extern RegLocation dvmCompilerGetDest(CompilationUnit *cUnit, MIR *mir,
    139                                       int num);
    140 
    141 extern RegLocation dvmCompilerGetReturnWide(CompilationUnit *cUnit);
    142 
    143 /* Clobber all regs that might be used by an external C call */
    144 extern void dvmCompilerClobberCallRegs(CompilationUnit *cUnit);
    145 
    146 extern RegisterInfo *dvmCompilerIsTemp(CompilationUnit *cUnit, int reg);
    147 
    148 extern void dvmCompilerMarkInUse(CompilationUnit *cUnit, int reg);
    149 
    150 extern int dvmCompilerAllocTemp(CompilationUnit *cUnit);
    151 
    152 extern int dvmCompilerAllocTempFloat(CompilationUnit *cUnit);
    153 
    154 //REDO: too many assumptions.
    155 extern int dvmCompilerAllocTempDouble(CompilationUnit *cUnit);
    156 
    157 extern void dvmCompilerFreeTemp(CompilationUnit *cUnit, int reg);
    158 
    159 extern void dvmCompilerResetDefLocWide(CompilationUnit *cUnit, RegLocation rl);
    160 
    161 extern void dvmCompilerResetDefTracking(CompilationUnit *cUnit);
    162 
    163 /* Kill the corresponding bit in the null-checked register list */
    164 extern void dvmCompilerKillNullCheckedLoc(CompilationUnit *cUnit,
    165                                           RegLocation loc);
    166 
    167 //FIXME - this needs to also check the preserved pool.
    168 extern RegisterInfo *dvmCompilerIsLive(CompilationUnit *cUnit, int reg);
    169 
    170 /* To be used when explicitly managing register use */
    171 extern void dvmCompilerLockAllTemps(CompilationUnit *cUnit);
    172 
    173 extern void dvmCompilerFlushAllRegs(CompilationUnit *cUnit);
    174 
    175 extern RegLocation dvmCompilerGetReturnWideAlt(CompilationUnit *cUnit);
    176 
    177 extern RegLocation dvmCompilerGetReturn(CompilationUnit *cUnit);
    178 
    179 extern RegLocation dvmCompilerGetReturnAlt(CompilationUnit *cUnit);
    180 
    181 /* Clobber any temp associated with an sReg.  Could be in either class */
    182 extern void dvmCompilerClobberSReg(CompilationUnit *cUnit, int sReg);
    183 
    184 /* Return a temp if one is available, -1 otherwise */
    185 extern 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  */
    192 extern void dvmCompilerLockTemp(CompilationUnit *cUnit, int reg);
    193 
    194 extern 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  */
    202 extern void dvmCompilerResetRegPool(CompilationUnit *cUnit);
    203 
    204 extern void dvmCompilerClobberAllRegs(CompilationUnit *cUnit);
    205 
    206 extern void dvmCompilerResetDefTracking(CompilationUnit *cUnit);
    207