blob: 2296fbceee0db18da2ee0e0f9387324b29bd2c9d [file] [log] [blame]
Ben Cheng5d90c202009-11-22 23:31:11 -08001/*
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/*
buzbeef6789272010-09-24 15:37:12 -070018 * This file contains target independent register alloction support.
Ben Cheng5d90c202009-11-22 23:31:11 -080019 */
20
21#include "compiler/CompilerUtility.h"
22#include "compiler/CompilerIR.h"
23#include "compiler/Dataflow.h"
24#include "compiler/codegen/arm/ArmLIR.h"
25
Bill Buzbee749e8162010-07-07 06:55:56 -070026/*
27 * Return most flexible allowed register class based on size.
28 * Bug: 2813841
29 * Must use a core register for data types narrower than word (due
30 * to possible unaligned load/store.
31 */
32static inline RegisterClass dvmCompilerRegClassBySize(OpSize size)
33{
34 return (size == kUnsignedHalf ||
35 size == kSignedHalf ||
36 size == kUnsignedByte ||
37 size == kSignedByte ) ? kCoreReg : kAnyReg;
38}
39
Bill Buzbeec6f10662010-02-09 11:16:15 -080040static inline int dvmCompilerS2VReg(CompilationUnit *cUnit, int sReg)
Ben Cheng5d90c202009-11-22 23:31:11 -080041{
42 assert(sReg != INVALID_SREG);
43 return DECODE_REG(dvmConvertSSARegToDalvik(cUnit, sReg));
44}
45
46/* Reset the tracker to unknown state */
Bill Buzbeec6f10662010-02-09 11:16:15 -080047static inline void dvmCompilerResetNullCheck(CompilationUnit *cUnit)
Ben Cheng5d90c202009-11-22 23:31:11 -080048{
49 dvmClearAllBits(cUnit->regPool->nullCheckedRegs);
50}
51
52/*
53 * Get the "real" sreg number associated with an sReg slot. In general,
54 * sReg values passed through codegen are the SSA names created by
55 * dataflow analysis and refer to slot numbers in the cUnit->regLocation
56 * array. However, renaming is accomplished by simply replacing RegLocation
57 * entries in the cUnit->reglocation[] array. Therefore, when location
58 * records for operands are first created, we need to ask the locRecord
59 * identified by the dataflow pass what it's new name is.
60 */
61
Bill Buzbeec6f10662010-02-09 11:16:15 -080062static inline int dvmCompilerSRegHi(int lowSreg) {
Ben Cheng5d90c202009-11-22 23:31:11 -080063 return (lowSreg == INVALID_SREG) ? INVALID_SREG : lowSreg + 1;
64}
65
66
Bill Buzbeec6f10662010-02-09 11:16:15 -080067static inline bool dvmCompilerLiveOut(CompilationUnit *cUnit, int sReg)
Ben Cheng5d90c202009-11-22 23:31:11 -080068{
69 //TODO: fully implement
70 return true;
71}
72
Bill Buzbeec6f10662010-02-09 11:16:15 -080073static inline int dvmCompilerSSASrc(MIR *mir, int num)
Ben Cheng5d90c202009-11-22 23:31:11 -080074{
75 assert(mir->ssaRep->numUses > num);
76 return mir->ssaRep->uses[num];
77}
78
Bill Buzbeec6f10662010-02-09 11:16:15 -080079extern RegLocation dvmCompilerEvalLoc(CompilationUnit *cUnit, RegLocation loc,
80 int regClass, bool update);
Ben Cheng5d90c202009-11-22 23:31:11 -080081/* Mark a temp register as dead. Does not affect allocation state. */
Bill Buzbeec6f10662010-02-09 11:16:15 -080082extern void dvmCompilerClobber(CompilationUnit *cUnit, int reg);
Ben Cheng5d90c202009-11-22 23:31:11 -080083
Bill Buzbeec6f10662010-02-09 11:16:15 -080084extern RegLocation dvmCompilerUpdateLoc(CompilationUnit *cUnit,
85 RegLocation loc);
Ben Cheng5d90c202009-11-22 23:31:11 -080086
87/* see comments for updateLoc */
Bill Buzbeec6f10662010-02-09 11:16:15 -080088extern RegLocation dvmCompilerUpdateLocWide(CompilationUnit *cUnit,
89 RegLocation loc);
Ben Cheng5d90c202009-11-22 23:31:11 -080090
91/* Clobber all of the temps that might be used by a handler. */
Bill Buzbeec6f10662010-02-09 11:16:15 -080092extern void dvmCompilerClobberHandlerRegs(CompilationUnit *cUnit);
Ben Cheng5d90c202009-11-22 23:31:11 -080093
Bill Buzbeec6f10662010-02-09 11:16:15 -080094extern void dvmCompilerMarkLive(CompilationUnit *cUnit, int reg, int sReg);
Ben Cheng5d90c202009-11-22 23:31:11 -080095
Bill Buzbeec6f10662010-02-09 11:16:15 -080096extern void dvmCompilerMarkDirty(CompilationUnit *cUnit, int reg);
Ben Cheng5d90c202009-11-22 23:31:11 -080097
Bill Buzbeec6f10662010-02-09 11:16:15 -080098extern void dvmCompilerMarkPair(CompilationUnit *cUnit, int lowReg,
99 int highReg);
Ben Cheng5d90c202009-11-22 23:31:11 -0800100
Bill Buzbeec6f10662010-02-09 11:16:15 -0800101extern void dvmCompilerMarkClean(CompilationUnit *cUnit, int reg);
Ben Cheng5d90c202009-11-22 23:31:11 -0800102
Bill Buzbeec6f10662010-02-09 11:16:15 -0800103extern void dvmCompilerResetDef(CompilationUnit *cUnit, int reg);
Ben Cheng5d90c202009-11-22 23:31:11 -0800104
Bill Buzbeec6f10662010-02-09 11:16:15 -0800105extern void dvmCompilerResetDefLoc(CompilationUnit *cUnit, RegLocation rl);
Ben Cheng5d90c202009-11-22 23:31:11 -0800106
107/* Set up temp & preserved register pools specialized by target */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800108extern void dvmCompilerInitPool(RegisterInfo *regs, int *regNums, int num);
Ben Cheng5d90c202009-11-22 23:31:11 -0800109
110/*
111 * Mark the beginning and end LIR of a def sequence. Note that
112 * on entry start points to the LIR prior to the beginning of the
113 * sequence.
114 */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800115extern void dvmCompilerMarkDef(CompilationUnit *cUnit, RegLocation rl,
116 LIR *start, LIR *finish);
Ben Cheng5d90c202009-11-22 23:31:11 -0800117/*
118 * Mark the beginning and end LIR of a def sequence. Note that
119 * on entry start points to the LIR prior to the beginning of the
120 * sequence.
121 */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800122extern void dvmCompilerMarkDefWide(CompilationUnit *cUnit, RegLocation rl,
123 LIR *start, LIR *finish);
Ben Cheng5d90c202009-11-22 23:31:11 -0800124
Bill Buzbeec6f10662010-02-09 11:16:15 -0800125extern RegLocation dvmCompilerGetSrcWide(CompilationUnit *cUnit, MIR *mir,
Ben Cheng5d90c202009-11-22 23:31:11 -0800126 int low, int high);
127
Bill Buzbeec6f10662010-02-09 11:16:15 -0800128extern RegLocation dvmCompilerGetDestWide(CompilationUnit *cUnit, MIR *mir,
129 int low, int high);
Ben Cheng5d90c202009-11-22 23:31:11 -0800130// Get the LocRecord associated with an SSA name use.
Bill Buzbeec6f10662010-02-09 11:16:15 -0800131extern RegLocation dvmCompilerGetSrc(CompilationUnit *cUnit, MIR *mir, int num);
Ben Cheng5d90c202009-11-22 23:31:11 -0800132
133// Get the LocRecord associated with an SSA name def.
Bill Buzbeec6f10662010-02-09 11:16:15 -0800134extern RegLocation dvmCompilerGetDest(CompilationUnit *cUnit, MIR *mir,
135 int num);
Ben Cheng5d90c202009-11-22 23:31:11 -0800136
Bill Buzbeec6f10662010-02-09 11:16:15 -0800137extern RegLocation dvmCompilerGetReturnWide(CompilationUnit *cUnit);
Ben Cheng5d90c202009-11-22 23:31:11 -0800138
139/* Clobber all regs that might be used by an external C call */
Elliott Hughes6a555132010-02-25 15:41:42 -0800140extern void dvmCompilerClobberCallRegs(CompilationUnit *cUnit);
Ben Cheng5d90c202009-11-22 23:31:11 -0800141
Bill Buzbeec6f10662010-02-09 11:16:15 -0800142extern RegisterInfo *dvmCompilerIsTemp(CompilationUnit *cUnit, int reg);
Ben Cheng5d90c202009-11-22 23:31:11 -0800143
Elliott Hughes6a555132010-02-25 15:41:42 -0800144extern void dvmCompilerMarkInUse(CompilationUnit *cUnit, int reg);
Ben Cheng5d90c202009-11-22 23:31:11 -0800145
Bill Buzbeec6f10662010-02-09 11:16:15 -0800146extern int dvmCompilerAllocTemp(CompilationUnit *cUnit);
Ben Cheng5d90c202009-11-22 23:31:11 -0800147
Bill Buzbeec6f10662010-02-09 11:16:15 -0800148extern int dvmCompilerAllocTempFloat(CompilationUnit *cUnit);
Ben Cheng5d90c202009-11-22 23:31:11 -0800149
150//REDO: too many assumptions.
Bill Buzbeec6f10662010-02-09 11:16:15 -0800151extern int dvmCompilerAllocTempDouble(CompilationUnit *cUnit);
Ben Cheng5d90c202009-11-22 23:31:11 -0800152
Bill Buzbeec6f10662010-02-09 11:16:15 -0800153extern void dvmCompilerFreeTemp(CompilationUnit *cUnit, int reg);
Ben Cheng5d90c202009-11-22 23:31:11 -0800154
Bill Buzbeec6f10662010-02-09 11:16:15 -0800155extern void dvmCompilerResetDefLocWide(CompilationUnit *cUnit, RegLocation rl);
Ben Cheng5d90c202009-11-22 23:31:11 -0800156
Bill Buzbeec6f10662010-02-09 11:16:15 -0800157extern void dvmCompilerResetDefTracking(CompilationUnit *cUnit);
Ben Cheng5d90c202009-11-22 23:31:11 -0800158
159/* Kill the corresponding bit in the null-checked register list */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800160extern void dvmCompilerKillNullCheckedLoc(CompilationUnit *cUnit,
161 RegLocation loc);
Ben Cheng5d90c202009-11-22 23:31:11 -0800162
163//FIXME - this needs to also check the preserved pool.
Bill Buzbeec6f10662010-02-09 11:16:15 -0800164extern RegisterInfo *dvmCompilerIsLive(CompilationUnit *cUnit, int reg);
Ben Cheng5d90c202009-11-22 23:31:11 -0800165
166/* To be used when explicitly managing register use */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800167extern void dvmCompilerLockAllTemps(CompilationUnit *cUnit);
Ben Cheng5d90c202009-11-22 23:31:11 -0800168
Bill Buzbeec6f10662010-02-09 11:16:15 -0800169extern void dvmCompilerFlushAllRegs(CompilationUnit *cUnit);
Ben Cheng5d90c202009-11-22 23:31:11 -0800170
Bill Buzbeec6f10662010-02-09 11:16:15 -0800171extern RegLocation dvmCompilerGetReturnWideAlt(CompilationUnit *cUnit);
Ben Cheng5d90c202009-11-22 23:31:11 -0800172
Bill Buzbeec6f10662010-02-09 11:16:15 -0800173extern RegLocation dvmCompilerGetReturn(CompilationUnit *cUnit);
Ben Cheng5d90c202009-11-22 23:31:11 -0800174
Bill Buzbeec6f10662010-02-09 11:16:15 -0800175extern RegLocation dvmCompilerGetReturnAlt(CompilationUnit *cUnit);
Ben Cheng5d90c202009-11-22 23:31:11 -0800176
177/* Clobber any temp associated with an sReg. Could be in either class */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800178extern void dvmCompilerClobberSReg(CompilationUnit *cUnit, int sReg);
Ben Cheng5d90c202009-11-22 23:31:11 -0800179
180/* Return a temp if one is available, -1 otherwise */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800181extern int dvmCompilerAllocFreeTemp(CompilationUnit *cUnit);
Ben Cheng5d90c202009-11-22 23:31:11 -0800182
183/*
Bill Buzbeec6f10662010-02-09 11:16:15 -0800184 * Similar to dvmCompilerAllocTemp(), but forces the allocation of a specific
Ben Cheng5d90c202009-11-22 23:31:11 -0800185 * register. No check is made to see if the register was previously
186 * allocated. Use with caution.
187 */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800188extern void dvmCompilerLockTemp(CompilationUnit *cUnit, int reg);
Ben Cheng5d90c202009-11-22 23:31:11 -0800189
Bill Buzbeec6f10662010-02-09 11:16:15 -0800190extern RegLocation dvmCompilerWideToNarrow(CompilationUnit *cUnit,
191 RegLocation rl);
Ben Cheng5d90c202009-11-22 23:31:11 -0800192
193/*
194 * Free all allocated temps in the temp pools. Note that this does
195 * not affect the "liveness" of a temp register, which will stay
196 * live until it is either explicitly killed or reallocated.
197 */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800198extern void dvmCompilerResetRegPool(CompilationUnit *cUnit);
Ben Cheng5d90c202009-11-22 23:31:11 -0800199
Bill Buzbeec6f10662010-02-09 11:16:15 -0800200extern void dvmCompilerClobberAllRegs(CompilationUnit *cUnit);
Ben Cheng5d90c202009-11-22 23:31:11 -0800201
buzbeef6789272010-09-24 15:37:12 -0700202extern void dvmCompilerFlushRegWide(CompilationUnit *cUnit, int reg1, int reg2);
203
204extern void dvmCompilerFlushReg(CompilationUnit *cUnit, int reg);
205
206/*
207 * Architecture-dependent register allocation routines implemented in
208 * ${TARGET_ARCH}/${TARGET_ARCH_VARIANT}/Ralloc.c
209 */
210extern int dvmCompilerAllocTypedTempPair(CompilationUnit *cUnit,
211 bool fpHint, int regClass);
212
213extern int dvmCompilerAllocTypedTemp(CompilationUnit *cUnit, bool fpHint,
214 int regClass);
215
216extern ArmLIR* dvmCompilerRegCopy(CompilationUnit *cUnit, int rDest, int rSrc);
217
218extern void dvmCompilerRegCopyWide(CompilationUnit *cUnit, int destLo,
219 int destHi, int srcLo, int srcHi);
220
221extern void dvmCompilerFlushRegImpl(CompilationUnit *cUnit, int rBase,
222 int displacement, int rSrc, OpSize size);
223
224extern void dvmCompilerFlushRegWideImpl(CompilationUnit *cUnit, int rBase,
225 int displacement, int rSrcLo,
226 int rSrcHi);