blob: a243415ed1c493bbb25aecbebb5d03678243903a [file] [log] [blame]
buzbeee3acd072012-02-25 17:03:10 -08001/*
2 * Copyright (C) 2012 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 Mips-specific register allocation support.
19 */
20
21#include "../../CompilerUtility.h"
22#include "../../CompilerIR.h"
23#include "../..//Dataflow.h"
24#include "MipsLIR.h"
25#include "Codegen.h"
26#include "../Ralloc.h"
27
28namespace art {
29
30/*
31 * Mark a callee-save fp register as promoted. Note that
32 * vpush/vpop uses contiguous register lists so we must
33 * include any holes in the mask. Associate holes with
34 * Dalvik register INVALID_VREG (0xFFFFU).
35 */
36STATIC void markPreservedSingle(CompilationUnit* cUnit, int sReg, int reg)
37{
38 UNIMPLEMENTED(FATAL) << "No support yet for promoted FP regs";
39#if 0
40 DCHECK_GE(reg, FP_REG_MASK + FP_CALLEE_SAVE_BASE);
41 reg = (reg & FP_REG_MASK) - FP_CALLEE_SAVE_BASE;
42 // Ensure fpVmapTable is large enough
43 int tableSize = cUnit->fpVmapTable.size();
44 for (int i = tableSize; i < (reg + 1); i++) {
45 cUnit->fpVmapTable.push_back(INVALID_VREG);
46 }
47 // Add the current mapping
48 cUnit->fpVmapTable[reg] = sReg;
49 // Size of fpVmapTable is high-water mark, use to set mask
50 cUnit->numFPSpills = cUnit->fpVmapTable.size();
51 cUnit->fpSpillMask = ((1 << cUnit->numFPSpills) - 1) << FP_CALLEE_SAVE_BASE;
52#endif
53}
54
55void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2)
56{
57 RegisterInfo* info1 = oatGetRegInfo(cUnit, reg1);
58 RegisterInfo* info2 = oatGetRegInfo(cUnit, reg2);
59 DCHECK(info1 && info2 && info1->pair && info2->pair &&
60 (info1->partner == info2->reg) &&
61 (info2->partner == info1->reg));
62 if ((info1->live && info1->dirty) || (info2->live && info2->dirty)) {
63 if (!(info1->isTemp && info2->isTemp)) {
64 /* Should not happen. If it does, there's a problem in evalLoc */
65 LOG(FATAL) << "Long half-temp, half-promoted";
66 }
67
68 info1->dirty = false;
69 info2->dirty = false;
70 if (oatS2VReg(cUnit, info2->sReg) <
71 oatS2VReg(cUnit, info1->sReg))
72 info1 = info2;
73 int vReg = oatS2VReg(cUnit, info1->sReg);
74 oatFlushRegWideImpl(cUnit, rSP,
75 oatVRegOffset(cUnit, vReg),
76 info1->reg, info1->partner);
77 }
78}
79
80void oatFlushReg(CompilationUnit* cUnit, int reg)
81{
82 RegisterInfo* info = oatGetRegInfo(cUnit, reg);
83 if (info->live && info->dirty) {
84 info->dirty = false;
85 int vReg = oatS2VReg(cUnit, info->sReg);
86 oatFlushRegImpl(cUnit, rSP,
87 oatVRegOffset(cUnit, vReg),
88 reg, kWord);
89 }
90}
91
92/* Give access to the target-dependent FP register encoding to common code */
93bool oatIsFpReg(int reg) {
94 return FPREG(reg);
95}
96
97uint32_t oatFpRegMask() {
98 return FP_REG_MASK;
99}
100
101/* Clobber all regs that might be used by an external C call */
102extern void oatClobberCalleeSave(CompilationUnit *cUnit)
103{
104 oatClobber(cUnit, r_ZERO);
105 oatClobber(cUnit, r_AT);
106 oatClobber(cUnit, r_V0);
107 oatClobber(cUnit, r_V1);
108 oatClobber(cUnit, r_A0);
109 oatClobber(cUnit, r_A1);
110 oatClobber(cUnit, r_A2);
111 oatClobber(cUnit, r_A3);
112 oatClobber(cUnit, r_T0);
113 oatClobber(cUnit, r_T1);
114 oatClobber(cUnit, r_T2);
115 oatClobber(cUnit, r_T3);
116 oatClobber(cUnit, r_T4);
117 oatClobber(cUnit, r_T5);
118 oatClobber(cUnit, r_T6);
119 oatClobber(cUnit, r_T7);
120 oatClobber(cUnit, r_T8);
121 oatClobber(cUnit, r_T9);
122 oatClobber(cUnit, r_K0);
123 oatClobber(cUnit, r_K1);
124 oatClobber(cUnit, r_GP);
125 oatClobber(cUnit, r_FP);
126 oatClobber(cUnit, r_RA);
127 oatClobber(cUnit, r_HI);
128 oatClobber(cUnit, r_LO);
129 oatClobber(cUnit, r_F0);
130 oatClobber(cUnit, r_F1);
131 oatClobber(cUnit, r_F2);
132 oatClobber(cUnit, r_F3);
133 oatClobber(cUnit, r_F4);
134 oatClobber(cUnit, r_F5);
135 oatClobber(cUnit, r_F6);
136 oatClobber(cUnit, r_F7);
137 oatClobber(cUnit, r_F8);
138 oatClobber(cUnit, r_F9);
139 oatClobber(cUnit, r_F10);
140 oatClobber(cUnit, r_F11);
141 oatClobber(cUnit, r_F12);
142 oatClobber(cUnit, r_F13);
143 oatClobber(cUnit, r_F14);
144 oatClobber(cUnit, r_F15);
145}
146
147extern RegLocation oatGetReturnWide(CompilationUnit* cUnit)
148{
149 RegLocation res = LOC_C_RETURN_WIDE;
150 oatClobber(cUnit, r_V0);
151 oatClobber(cUnit, r_V1);
152 oatMarkInUse(cUnit, r_V0);
153 oatMarkInUse(cUnit, r_V1);
154 oatMarkPair(cUnit, res.lowReg, res.highReg);
155 return res;
156}
157
158extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit)
159{
160 RegLocation res = LOC_C_RETURN_WIDE_ALT;
161 oatClobber(cUnit, r_F0);
162 oatClobber(cUnit, r_F1);
163 oatMarkInUse(cUnit, r_F0);
164 oatMarkInUse(cUnit, r_F1);
165 oatMarkPair(cUnit, res.lowReg, res.highReg);
166 return res;
167}
168
169extern RegLocation oatGetReturn(CompilationUnit* cUnit)
170{
171 RegLocation res = LOC_C_RETURN;
172 oatClobber(cUnit, r_V0);
173 oatMarkInUse(cUnit, r_V0);
174 return res;
175}
176
177extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit)
178{
179 RegLocation res = LOC_C_RETURN_ALT;
180 oatClobber(cUnit, r_F0);
181 oatMarkInUse(cUnit, r_F0);
182 return res;
183}
184
185extern RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg)
186{
187 return FPREG(reg) ? &cUnit->regPool->FPRegs[reg & FP_REG_MASK]
188 : &cUnit->regPool->coreRegs[reg];
189}
190
191/* To be used when explicitly managing register use */
192extern void oatLockCallTemps(CompilationUnit* cUnit)
193{
194 oatLockTemp(cUnit, r_A0);
195 oatLockTemp(cUnit, r_A1);
196 oatLockTemp(cUnit, r_A2);
197 oatLockTemp(cUnit, r_A3);
198}
199
200/* To be used when explicitly managing register use */
201extern void oatFreeCallTemps(CompilationUnit* cUnit)
202{
203 oatFreeTemp(cUnit, r_A0);
204 oatFreeTemp(cUnit, r_A1);
205 oatFreeTemp(cUnit, r_A2);
206 oatFreeTemp(cUnit, r_A3);
207}
208
209} // namespace art