blob: 32977eb2407e890787857e7a969123875654c75a [file] [log] [blame]
Bill Buzbee1465db52009-09-23 17:17:35 -07001/*
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
Ben Cheng5d90c202009-11-22 23:31:11 -080025#include "compiler/CompilerUtility.h"
26#include "compiler/CompilerIR.h"
27#include "compiler/Dataflow.h"
Ben Cheng5d90c202009-11-22 23:31:11 -080028#include "Ralloc.h"
29
Bill Buzbee1465db52009-09-23 17:17:35 -070030#define SREG(c, s) ((c)->regLocation[(s)].sRegLow)
31/*
32 * Get the "real" sreg number associated with an sReg slot. In general,
33 * sReg values passed through codegen are the SSA names created by
34 * dataflow analysis and refer to slot numbers in the cUnit->regLocation
35 * array. However, renaming is accomplished by simply replacing RegLocation
36 * entries in the cUnit->reglocation[] array. Therefore, when location
37 * records for operands are first created, we need to ask the locRecord
38 * identified by the dataflow pass what it's new name is.
39 */
40
Bill Buzbee1465db52009-09-23 17:17:35 -070041/*
42 * Free all allocated temps in the temp pools. Note that this does
43 * not affect the "liveness" of a temp register, which will stay
44 * live until it is either explicitly killed or reallocated.
45 */
Bill Buzbeec6f10662010-02-09 11:16:15 -080046extern void dvmCompilerResetRegPool(CompilationUnit *cUnit)
Bill Buzbee1465db52009-09-23 17:17:35 -070047{
48 int i;
49 for (i=0; i < cUnit->regPool->numCoreTemps; i++) {
50 cUnit->regPool->coreTemps[i].inUse = false;
51 }
52 for (i=0; i < cUnit->regPool->numFPTemps; i++) {
53 cUnit->regPool->FPTemps[i].inUse = false;
54 }
55}
56
57 /* Set up temp & preserved register pools specialized by target */
Bill Buzbeec6f10662010-02-09 11:16:15 -080058extern void dvmCompilerInitPool(RegisterInfo *regs, int *regNums, int num)
Bill Buzbee1465db52009-09-23 17:17:35 -070059{
60 int i;
61 for (i=0; i < num; i++) {
62 regs[i].reg = regNums[i];
63 regs[i].inUse = false;
64 regs[i].pair = false;
65 regs[i].live = false;
66 regs[i].dirty = false;
67 regs[i].sReg = INVALID_SREG;
68 }
69}
70
71static void dumpRegPool(RegisterInfo *p, int numRegs)
72{
73 int i;
74 LOGE("================================================");
75 for (i=0; i < numRegs; i++ ){
76 LOGE("R[%d]: U:%d, P:%d, part:%d, LV:%d, D:%d, SR:%d, ST:%x, EN:%x",
77 p[i].reg, p[i].inUse, p[i].pair, p[i].partner, p[i].live,
78 p[i].dirty, p[i].sReg,(int)p[i].defStart, (int)p[i].defEnd);
79 }
80 LOGE("================================================");
81}
82
Ben Cheng5d90c202009-11-22 23:31:11 -080083static RegisterInfo *getRegInfo(CompilationUnit *cUnit, int reg)
84{
85 int numTemps = cUnit->regPool->numCoreTemps;
86 RegisterInfo *p = cUnit->regPool->coreTemps;
87 int i;
88 for (i=0; i< numTemps; i++) {
89 if (p[i].reg == reg) {
90 return &p[i];
91 }
92 }
93 p = cUnit->regPool->FPTemps;
94 numTemps = cUnit->regPool->numFPTemps;
95 for (i=0; i< numTemps; i++) {
96 if (p[i].reg == reg) {
97 return &p[i];
98 }
99 }
100 LOGE("Tried to get info on a non-existant temp: r%d",reg);
Bill Buzbeefc519dc2010-03-06 23:30:57 -0800101 dvmCompilerAbort(cUnit);
Ben Cheng5d90c202009-11-22 23:31:11 -0800102 return NULL;
103}
104
buzbeef6789272010-09-24 15:37:12 -0700105void dvmCompilerFlushRegWide(CompilationUnit *cUnit, int reg1, int reg2)
Ben Cheng5d90c202009-11-22 23:31:11 -0800106{
107 RegisterInfo *info1 = getRegInfo(cUnit, reg1);
108 RegisterInfo *info2 = getRegInfo(cUnit, reg2);
109 assert(info1 && info2 && info1->pair && info2->pair &&
110 (info1->partner == info2->reg) &&
111 (info2->partner == info1->reg));
112 if ((info1->live && info1->dirty) || (info2->live && info2->dirty)) {
113 info1->dirty = false;
114 info2->dirty = false;
Bill Buzbeec6f10662010-02-09 11:16:15 -0800115 if (dvmCompilerS2VReg(cUnit, info2->sReg) <
116 dvmCompilerS2VReg(cUnit, info1->sReg))
Ben Cheng5d90c202009-11-22 23:31:11 -0800117 info1 = info2;
118 dvmCompilerFlushRegWideImpl(cUnit, rFP,
Bill Buzbeec6f10662010-02-09 11:16:15 -0800119 dvmCompilerS2VReg(cUnit, info1->sReg) << 2,
Ben Cheng5d90c202009-11-22 23:31:11 -0800120 info1->reg, info1->partner);
121 }
122}
123
buzbeef6789272010-09-24 15:37:12 -0700124void dvmCompilerFlushReg(CompilationUnit *cUnit, int reg)
Ben Cheng5d90c202009-11-22 23:31:11 -0800125{
126 RegisterInfo *info = getRegInfo(cUnit, reg);
127 if (info->live && info->dirty) {
128 info->dirty = false;
Bill Buzbeec6f10662010-02-09 11:16:15 -0800129 dvmCompilerFlushRegImpl(cUnit, rFP,
130 dvmCompilerS2VReg(cUnit, info->sReg) << 2,
Ben Cheng5d90c202009-11-22 23:31:11 -0800131 reg, kWord);
132 }
133}
134
135/* return true if found reg to clobber */
136static bool clobberRegBody(CompilationUnit *cUnit, RegisterInfo *p,
137 int numTemps, int reg)
138{
139 int i;
140 for (i=0; i< numTemps; i++) {
141 if (p[i].reg == reg) {
142 if (p[i].live && p[i].dirty) {
143 if (p[i].pair) {
buzbeef6789272010-09-24 15:37:12 -0700144 dvmCompilerFlushRegWide(cUnit, p[i].reg, p[i].partner);
Ben Cheng5d90c202009-11-22 23:31:11 -0800145 } else {
buzbeef6789272010-09-24 15:37:12 -0700146 dvmCompilerFlushReg(cUnit, p[i].reg);
Ben Cheng5d90c202009-11-22 23:31:11 -0800147 }
148 }
149 p[i].live = false;
150 p[i].sReg = INVALID_SREG;
151 p[i].defStart = NULL;
152 p[i].defEnd = NULL;
153 if (p[i].pair) {
154 p[i].pair = false;
155 /* partners should be in same pool */
156 clobberRegBody(cUnit, p, numTemps, p[i].partner);
157 }
158 return true;
159 }
160 }
161 return false;
162}
163
164/* Mark a temp register as dead. Does not affect allocation state. */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800165void dvmCompilerClobber(CompilationUnit *cUnit, int reg)
Ben Cheng5d90c202009-11-22 23:31:11 -0800166{
167 if (!clobberRegBody(cUnit, cUnit->regPool->coreTemps,
168 cUnit->regPool->numCoreTemps, reg)) {
169 clobberRegBody(cUnit, cUnit->regPool->FPTemps,
170 cUnit->regPool->numFPTemps, reg);
171 }
172}
173
174static void clobberSRegBody(RegisterInfo *p, int numTemps, int sReg)
175{
176 int i;
177 for (i=0; i< numTemps; i++) {
178 if (p[i].sReg == sReg) {
179 p[i].live = false;
180 p[i].defStart = NULL;
181 p[i].defEnd = NULL;
182 }
183 }
184}
185
186/* Clobber any temp associated with an sReg. Could be in either class */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800187extern void dvmCompilerClobberSReg(CompilationUnit *cUnit, int sReg)
Ben Cheng5d90c202009-11-22 23:31:11 -0800188{
189 clobberSRegBody(cUnit->regPool->coreTemps, cUnit->regPool->numCoreTemps,
190 sReg);
191 clobberSRegBody(cUnit->regPool->FPTemps, cUnit->regPool->numFPTemps,
192 sReg);
193}
194
Bill Buzbee1465db52009-09-23 17:17:35 -0700195static int allocTempBody(CompilationUnit *cUnit, RegisterInfo *p, int numTemps,
Bill Buzbee1f748632010-03-02 16:14:41 -0800196 int *nextTemp, bool required)
Bill Buzbee1465db52009-09-23 17:17:35 -0700197{
198 int i;
Bill Buzbee1f748632010-03-02 16:14:41 -0800199 int next = *nextTemp;
Bill Buzbee1465db52009-09-23 17:17:35 -0700200 for (i=0; i< numTemps; i++) {
Bill Buzbee1f748632010-03-02 16:14:41 -0800201 if (next >= numTemps)
202 next = 0;
203 if (!p[next].inUse && !p[next].live) {
204 dvmCompilerClobber(cUnit, p[next].reg);
205 p[next].inUse = true;
206 p[next].pair = false;
207 *nextTemp = next + 1;
208 return p[next].reg;
Bill Buzbee1465db52009-09-23 17:17:35 -0700209 }
Bill Buzbee1f748632010-03-02 16:14:41 -0800210 next++;
Bill Buzbee1465db52009-09-23 17:17:35 -0700211 }
Bill Buzbee1f748632010-03-02 16:14:41 -0800212 next = *nextTemp;
Bill Buzbee1465db52009-09-23 17:17:35 -0700213 for (i=0; i< numTemps; i++) {
Bill Buzbee1f748632010-03-02 16:14:41 -0800214 if (next >= numTemps)
215 next = 0;
216 if (!p[next].inUse) {
217 dvmCompilerClobber(cUnit, p[next].reg);
218 p[next].inUse = true;
219 p[next].pair = false;
220 *nextTemp = next + 1;
221 return p[next].reg;
Bill Buzbee1465db52009-09-23 17:17:35 -0700222 }
Bill Buzbee1f748632010-03-02 16:14:41 -0800223 next++;
Bill Buzbee1465db52009-09-23 17:17:35 -0700224 }
225 if (required) {
226 LOGE("No free temp registers");
Bill Buzbeefc519dc2010-03-06 23:30:57 -0800227 dvmCompilerAbort(cUnit);
Bill Buzbee1465db52009-09-23 17:17:35 -0700228 }
229 return -1; // No register available
230}
231
232//REDO: too many assumptions.
Bill Buzbeec6f10662010-02-09 11:16:15 -0800233extern int dvmCompilerAllocTempDouble(CompilationUnit *cUnit)
Bill Buzbee1465db52009-09-23 17:17:35 -0700234{
235 RegisterInfo *p = cUnit->regPool->FPTemps;
236 int numTemps = cUnit->regPool->numFPTemps;
Bill Buzbee1f748632010-03-02 16:14:41 -0800237 int next = cUnit->regPool->nextFPTemp;
Bill Buzbee1465db52009-09-23 17:17:35 -0700238 int i;
239
240 for (i=0; i < numTemps; i+=2) {
Bill Buzbee1f748632010-03-02 16:14:41 -0800241 /* Cleanup - not all targets need aligned regs */
242 if (next & 1)
243 next++;
244 if (next >= numTemps)
245 next = 0;
246 if ((!p[next].inUse && !p[next].live) &&
247 (!p[next+1].inUse && !p[next+1].live)) {
248 dvmCompilerClobber(cUnit, p[next].reg);
249 dvmCompilerClobber(cUnit, p[next+1].reg);
250 p[next].inUse = true;
251 p[next+1].inUse = true;
252 assert((p[next].reg+1) == p[next+1].reg);
253 assert((p[next].reg & 0x1) == 0);
254 cUnit->regPool->nextFPTemp += 2;
255 return p[next].reg;
Bill Buzbee1465db52009-09-23 17:17:35 -0700256 }
Bill Buzbee1f748632010-03-02 16:14:41 -0800257 next += 2;
Bill Buzbee1465db52009-09-23 17:17:35 -0700258 }
Bill Buzbee1f748632010-03-02 16:14:41 -0800259 next = cUnit->regPool->nextFPTemp;
Bill Buzbee1465db52009-09-23 17:17:35 -0700260 for (i=0; i < numTemps; i+=2) {
Bill Buzbee1f748632010-03-02 16:14:41 -0800261 if (next >= numTemps)
262 next = 0;
263 if (!p[next].inUse && !p[next+1].inUse) {
264 dvmCompilerClobber(cUnit, p[next].reg);
265 dvmCompilerClobber(cUnit, p[next+1].reg);
266 p[next].inUse = true;
267 p[next+1].inUse = true;
268 assert((p[next].reg+1) == p[next+1].reg);
269 assert((p[next].reg & 0x1) == 0);
270 cUnit->regPool->nextFPTemp += 2;
271 return p[next].reg;
Bill Buzbee1465db52009-09-23 17:17:35 -0700272 }
Bill Buzbee1f748632010-03-02 16:14:41 -0800273 next += 2;
Bill Buzbee1465db52009-09-23 17:17:35 -0700274 }
275 LOGE("No free temp registers");
Bill Buzbeefc519dc2010-03-06 23:30:57 -0800276 dvmCompilerAbort(cUnit);
Bill Buzbee1465db52009-09-23 17:17:35 -0700277 return -1;
278}
279
280/* Return a temp if one is available, -1 otherwise */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800281extern int dvmCompilerAllocFreeTemp(CompilationUnit *cUnit)
Bill Buzbee1465db52009-09-23 17:17:35 -0700282{
283 return allocTempBody(cUnit, cUnit->regPool->coreTemps,
Bill Buzbee1f748632010-03-02 16:14:41 -0800284 cUnit->regPool->numCoreTemps,
285 &cUnit->regPool->nextCoreTemp, true);
Bill Buzbee1465db52009-09-23 17:17:35 -0700286}
287
Bill Buzbeec6f10662010-02-09 11:16:15 -0800288extern int dvmCompilerAllocTemp(CompilationUnit *cUnit)
Bill Buzbee1465db52009-09-23 17:17:35 -0700289{
290 return allocTempBody(cUnit, cUnit->regPool->coreTemps,
Bill Buzbee1f748632010-03-02 16:14:41 -0800291 cUnit->regPool->numCoreTemps,
292 &cUnit->regPool->nextCoreTemp, true);
Bill Buzbee1465db52009-09-23 17:17:35 -0700293}
294
Bill Buzbeec6f10662010-02-09 11:16:15 -0800295extern int dvmCompilerAllocTempFloat(CompilationUnit *cUnit)
Bill Buzbee1465db52009-09-23 17:17:35 -0700296{
297 return allocTempBody(cUnit, cUnit->regPool->FPTemps,
Bill Buzbee1f748632010-03-02 16:14:41 -0800298 cUnit->regPool->numFPTemps,
299 &cUnit->regPool->nextFPTemp, true);
Bill Buzbee1465db52009-09-23 17:17:35 -0700300}
301
302static RegisterInfo *allocLiveBody(RegisterInfo *p, int numTemps, int sReg)
303{
304 int i;
305 if (sReg == -1)
306 return NULL;
307 for (i=0; i < numTemps; i++) {
308 if (p[i].live && (p[i].sReg == sReg)) {
309 p[i].inUse = true;
310 return &p[i];
311 }
312 }
313 return NULL;
314}
315
316static RegisterInfo *allocLive(CompilationUnit *cUnit, int sReg,
317 int regClass)
318{
319 RegisterInfo *res = NULL;
320 switch(regClass) {
321 case kAnyReg:
322 res = allocLiveBody(cUnit->regPool->FPTemps,
323 cUnit->regPool->numFPTemps, sReg);
324 if (res)
325 break;
326 /* Intentional fallthrough */
327 case kCoreReg:
328 res = allocLiveBody(cUnit->regPool->coreTemps,
329 cUnit->regPool->numCoreTemps, sReg);
330 break;
331 case kFPReg:
332 res = allocLiveBody(cUnit->regPool->FPTemps,
333 cUnit->regPool->numFPTemps, sReg);
334 break;
335 default:
336 LOGE("Invalid register type");
Bill Buzbeefc519dc2010-03-06 23:30:57 -0800337 dvmCompilerAbort(cUnit);
Bill Buzbee1465db52009-09-23 17:17:35 -0700338 }
339 return res;
340}
341
Bill Buzbeec6f10662010-02-09 11:16:15 -0800342extern void dvmCompilerFreeTemp(CompilationUnit *cUnit, int reg)
Bill Buzbee1465db52009-09-23 17:17:35 -0700343{
344 RegisterInfo *p = cUnit->regPool->coreTemps;
345 int numTemps = cUnit->regPool->numCoreTemps;
346 int i;
347 for (i=0; i< numTemps; i++) {
348 if (p[i].reg == reg) {
349 p[i].inUse = false;
350 p[i].pair = false;
351 return;
352 }
353 }
354 p = cUnit->regPool->FPTemps;
355 numTemps = cUnit->regPool->numFPTemps;
356 for (i=0; i< numTemps; i++) {
357 if (p[i].reg == reg) {
358 p[i].inUse = false;
359 p[i].pair = false;
360 return;
361 }
362 }
363 LOGE("Tried to free a non-existant temp: r%d",reg);
Bill Buzbeefc519dc2010-03-06 23:30:57 -0800364 dvmCompilerAbort(cUnit);
Bill Buzbee1465db52009-09-23 17:17:35 -0700365}
366
Bill Buzbee1f748632010-03-02 16:14:41 -0800367/*
368 * FIXME - this needs to also check the preserved pool once we start
369 * start using preserved registers.
370 */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800371extern RegisterInfo *dvmCompilerIsLive(CompilationUnit *cUnit, int reg)
Bill Buzbee1465db52009-09-23 17:17:35 -0700372{
373 RegisterInfo *p = cUnit->regPool->coreTemps;
374 int numTemps = cUnit->regPool->numCoreTemps;
375 int i;
376 for (i=0; i< numTemps; i++) {
377 if (p[i].reg == reg) {
378 return p[i].live ? &p[i] : NULL;
379 }
380 }
381 p = cUnit->regPool->FPTemps;
382 numTemps = cUnit->regPool->numFPTemps;
383 for (i=0; i< numTemps; i++) {
384 if (p[i].reg == reg) {
385 return p[i].live ? &p[i] : NULL;
386 }
387 }
388 return NULL;
389}
390
Bill Buzbeec6f10662010-02-09 11:16:15 -0800391extern RegisterInfo *dvmCompilerIsTemp(CompilationUnit *cUnit, int reg)
Bill Buzbee1465db52009-09-23 17:17:35 -0700392{
393 RegisterInfo *p = cUnit->regPool->coreTemps;
394 int numTemps = cUnit->regPool->numCoreTemps;
395 int i;
396 for (i=0; i< numTemps; i++) {
397 if (p[i].reg == reg) {
398 return &p[i];
399 }
400 }
401 p = cUnit->regPool->FPTemps;
402 numTemps = cUnit->regPool->numFPTemps;
403 for (i=0; i< numTemps; i++) {
404 if (p[i].reg == reg) {
405 return &p[i];
406 }
407 }
408 return NULL;
409}
410
Bill Buzbee1465db52009-09-23 17:17:35 -0700411/*
Bill Buzbeec6f10662010-02-09 11:16:15 -0800412 * Similar to dvmCompilerAllocTemp(), but forces the allocation of a specific
Bill Buzbee1465db52009-09-23 17:17:35 -0700413 * register. No check is made to see if the register was previously
414 * allocated. Use with caution.
415 */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800416extern void dvmCompilerLockTemp(CompilationUnit *cUnit, int reg)
Bill Buzbee1465db52009-09-23 17:17:35 -0700417{
418 RegisterInfo *p = cUnit->regPool->coreTemps;
419 int numTemps = cUnit->regPool->numCoreTemps;
420 int i;
421 for (i=0; i< numTemps; i++) {
422 if (p[i].reg == reg) {
423 p[i].inUse = true;
424 p[i].live = false;
425 return;
426 }
427 }
428 p = cUnit->regPool->FPTemps;
429 numTemps = cUnit->regPool->numFPTemps;
430 for (i=0; i< numTemps; i++) {
431 if (p[i].reg == reg) {
432 p[i].inUse = true;
433 p[i].live = false;
434 return;
435 }
436 }
437 LOGE("Tried to lock a non-existant temp: r%d",reg);
Bill Buzbeefc519dc2010-03-06 23:30:57 -0800438 dvmCompilerAbort(cUnit);
Bill Buzbee1465db52009-09-23 17:17:35 -0700439}
440
Bill Buzbeec6f10662010-02-09 11:16:15 -0800441extern void dvmCompilerResetDef(CompilationUnit *cUnit, int reg)
Bill Buzbee1465db52009-09-23 17:17:35 -0700442{
443 RegisterInfo *p = getRegInfo(cUnit, reg);
444 p->defStart = NULL;
445 p->defEnd = NULL;
446}
447
448static void nullifyRange(CompilationUnit *cUnit, LIR *start, LIR *finish,
449 int sReg1, int sReg2)
450{
451 if (start && finish) {
452 LIR *p;
453 assert(sReg1 == sReg2);
454 for (p = start; ;p = p->next) {
455 ((ArmLIR *)p)->isNop = true;
456 if (p == finish)
457 break;
458 }
459 }
460}
461
462/*
463 * Mark the beginning and end LIR of a def sequence. Note that
464 * on entry start points to the LIR prior to the beginning of the
465 * sequence.
466 */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800467extern void dvmCompilerMarkDef(CompilationUnit *cUnit, RegLocation rl,
Bill Buzbee1465db52009-09-23 17:17:35 -0700468 LIR *start, LIR *finish)
469{
470 assert(!rl.wide);
471 assert(start && start->next);
472 assert(finish);
473 RegisterInfo *p = getRegInfo(cUnit, rl.lowReg);
474 p->defStart = start->next;
475 p->defEnd = finish;
476}
477
478/*
479 * Mark the beginning and end LIR of a def sequence. Note that
480 * on entry start points to the LIR prior to the beginning of the
481 * sequence.
482 */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800483extern void dvmCompilerMarkDefWide(CompilationUnit *cUnit, RegLocation rl,
Bill Buzbee1465db52009-09-23 17:17:35 -0700484 LIR *start, LIR *finish)
485{
486 assert(rl.wide);
487 assert(start && start->next);
488 assert(finish);
489 RegisterInfo *p = getRegInfo(cUnit, rl.lowReg);
Bill Buzbeec6f10662010-02-09 11:16:15 -0800490 dvmCompilerResetDef(cUnit, rl.highReg); // Only track low of pair
Bill Buzbee1465db52009-09-23 17:17:35 -0700491 p->defStart = start->next;
492 p->defEnd = finish;
493}
494
Bill Buzbeec6f10662010-02-09 11:16:15 -0800495extern RegLocation dvmCompilerWideToNarrow(CompilationUnit *cUnit,
496 RegLocation rl)
Bill Buzbee1465db52009-09-23 17:17:35 -0700497{
498 assert(rl.wide);
499 if (rl.location == kLocPhysReg) {
500 RegisterInfo *infoLo = getRegInfo(cUnit, rl.lowReg);
501 RegisterInfo *infoHi = getRegInfo(cUnit, rl.highReg);
502 if (!infoLo->pair) {
Ben Cheng5d90c202009-11-22 23:31:11 -0800503 dumpRegPool(cUnit->regPool->coreTemps,
504 cUnit->regPool->numCoreTemps);
Bill Buzbee1465db52009-09-23 17:17:35 -0700505 assert(infoLo->pair);
506 }
507 if (!infoHi->pair) {
Ben Cheng5d90c202009-11-22 23:31:11 -0800508 dumpRegPool(cUnit->regPool->coreTemps,
509 cUnit->regPool->numCoreTemps);
Bill Buzbee1465db52009-09-23 17:17:35 -0700510 assert(infoHi->pair);
511 }
512 assert(infoLo->pair);
513 assert(infoHi->pair);
514 assert(infoLo->partner == infoHi->reg);
515 assert(infoHi->partner == infoLo->reg);
516 infoLo->pair = false;
517 infoHi->pair = false;
518 infoLo->defStart = NULL;
519 infoLo->defEnd = NULL;
520 infoHi->defStart = NULL;
521 infoHi->defEnd = NULL;
522 }
523 rl.wide = false;
524 return rl;
525}
526
Bill Buzbeec6f10662010-02-09 11:16:15 -0800527extern void dvmCompilerResetDefLoc(CompilationUnit *cUnit, RegLocation rl)
Bill Buzbee1465db52009-09-23 17:17:35 -0700528{
529 assert(!rl.wide);
530 if (!(gDvmJit.disableOpt & (1 << kSuppressLoads))) {
531 RegisterInfo *p = getRegInfo(cUnit, rl.lowReg);
532 assert(!p->pair);
533 nullifyRange(cUnit, p->defStart, p->defEnd,
534 p->sReg, rl.sRegLow);
535 }
Bill Buzbeec6f10662010-02-09 11:16:15 -0800536 dvmCompilerResetDef(cUnit, rl.lowReg);
Bill Buzbee1465db52009-09-23 17:17:35 -0700537}
538
Bill Buzbeec6f10662010-02-09 11:16:15 -0800539extern void dvmCompilerResetDefLocWide(CompilationUnit *cUnit, RegLocation rl)
Bill Buzbee1465db52009-09-23 17:17:35 -0700540{
541 assert(rl.wide);
542 if (!(gDvmJit.disableOpt & (1 << kSuppressLoads))) {
543 RegisterInfo *p = getRegInfo(cUnit, rl.lowReg);
544 assert(p->pair);
545 nullifyRange(cUnit, p->defStart, p->defEnd,
546 p->sReg, rl.sRegLow);
547 }
Bill Buzbeec6f10662010-02-09 11:16:15 -0800548 dvmCompilerResetDef(cUnit, rl.lowReg);
549 dvmCompilerResetDef(cUnit, rl.highReg);
Bill Buzbee1465db52009-09-23 17:17:35 -0700550}
551
Bill Buzbeec6f10662010-02-09 11:16:15 -0800552extern void dvmCompilerResetDefTracking(CompilationUnit *cUnit)
Bill Buzbee1465db52009-09-23 17:17:35 -0700553{
554 int i;
555 for (i=0; i< cUnit->regPool->numCoreTemps; i++) {
Bill Buzbeec6f10662010-02-09 11:16:15 -0800556 dvmCompilerResetDef(cUnit, cUnit->regPool->coreTemps[i].reg);
Bill Buzbee1465db52009-09-23 17:17:35 -0700557 }
558 for (i=0; i< cUnit->regPool->numFPTemps; i++) {
Bill Buzbeec6f10662010-02-09 11:16:15 -0800559 dvmCompilerResetDef(cUnit, cUnit->regPool->FPTemps[i].reg);
Bill Buzbee1465db52009-09-23 17:17:35 -0700560 }
561}
562
Bill Buzbeec6f10662010-02-09 11:16:15 -0800563extern void dvmCompilerClobberAllRegs(CompilationUnit *cUnit)
Bill Buzbee1465db52009-09-23 17:17:35 -0700564{
565 int i;
566 for (i=0; i< cUnit->regPool->numCoreTemps; i++) {
Bill Buzbeec6f10662010-02-09 11:16:15 -0800567 dvmCompilerClobber(cUnit, cUnit->regPool->coreTemps[i].reg);
Bill Buzbee1465db52009-09-23 17:17:35 -0700568 }
569 for (i=0; i< cUnit->regPool->numFPTemps; i++) {
Bill Buzbeec6f10662010-02-09 11:16:15 -0800570 dvmCompilerClobber(cUnit, cUnit->regPool->FPTemps[i].reg);
Bill Buzbee1465db52009-09-23 17:17:35 -0700571 }
572}
573
574/* To be used when explicitly managing register use */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800575extern void dvmCompilerLockAllTemps(CompilationUnit *cUnit)
Bill Buzbee1465db52009-09-23 17:17:35 -0700576{
577 int i;
578 for (i=0; i< cUnit->regPool->numCoreTemps; i++) {
Bill Buzbeec6f10662010-02-09 11:16:15 -0800579 dvmCompilerLockTemp(cUnit, cUnit->regPool->coreTemps[i].reg);
Bill Buzbee1465db52009-09-23 17:17:35 -0700580 }
581}
582
583// Make sure nothing is live and dirty
584static void flushAllRegsBody(CompilationUnit *cUnit, RegisterInfo *info,
585 int numRegs)
586{
587 int i;
588 for (i=0; i < numRegs; i++) {
589 if (info[i].live && info[i].dirty) {
590 if (info[i].pair) {
buzbeef6789272010-09-24 15:37:12 -0700591 dvmCompilerFlushRegWide(cUnit, info[i].reg, info[i].partner);
Bill Buzbee1465db52009-09-23 17:17:35 -0700592 } else {
buzbeef6789272010-09-24 15:37:12 -0700593 dvmCompilerFlushReg(cUnit, info[i].reg);
Bill Buzbee1465db52009-09-23 17:17:35 -0700594 }
595 }
596 }
597}
598
Bill Buzbeec6f10662010-02-09 11:16:15 -0800599extern void dvmCompilerFlushAllRegs(CompilationUnit *cUnit)
Bill Buzbee1465db52009-09-23 17:17:35 -0700600{
601 flushAllRegsBody(cUnit, cUnit->regPool->coreTemps,
602 cUnit->regPool->numCoreTemps);
603 flushAllRegsBody(cUnit, cUnit->regPool->FPTemps,
604 cUnit->regPool->numFPTemps);
Bill Buzbeec6f10662010-02-09 11:16:15 -0800605 dvmCompilerClobberAllRegs(cUnit);
Bill Buzbee1465db52009-09-23 17:17:35 -0700606}
607
608
609//TUNING: rewrite all of this reg stuff. Probably use an attribute table
610static bool regClassMatches(int regClass, int reg)
611{
612 if (regClass == kAnyReg) {
613 return true;
614 } else if (regClass == kCoreReg) {
615 return !FPREG(reg);
616 } else {
617 return FPREG(reg);
618 }
619}
620
Bill Buzbeec6f10662010-02-09 11:16:15 -0800621extern void dvmCompilerMarkLive(CompilationUnit *cUnit, int reg, int sReg)
Bill Buzbee1465db52009-09-23 17:17:35 -0700622{
623 RegisterInfo *info = getRegInfo(cUnit, reg);
624 if ((info->reg == reg) && (info->sReg == sReg) && info->live) {
625 return; /* already live */
626 } else if (sReg != INVALID_SREG) {
Bill Buzbeec6f10662010-02-09 11:16:15 -0800627 dvmCompilerClobberSReg(cUnit, sReg);
Bill Buzbee1465db52009-09-23 17:17:35 -0700628 info->live = true;
629 } else {
630 /* Can't be live if no associated sReg */
631 info->live = false;
632 }
633 info->sReg = sReg;
634}
635
Bill Buzbeec6f10662010-02-09 11:16:15 -0800636extern void dvmCompilerMarkPair(CompilationUnit *cUnit, int lowReg, int highReg)
Bill Buzbee1465db52009-09-23 17:17:35 -0700637{
638 RegisterInfo *infoLo = getRegInfo(cUnit, lowReg);
639 RegisterInfo *infoHi = getRegInfo(cUnit, highReg);
640 infoLo->pair = infoHi->pair = true;
641 infoLo->partner = highReg;
642 infoHi->partner = lowReg;
643}
644
Bill Buzbeec6f10662010-02-09 11:16:15 -0800645extern void dvmCompilerMarkClean(CompilationUnit *cUnit, int reg)
Bill Buzbee1465db52009-09-23 17:17:35 -0700646{
647 RegisterInfo *info = getRegInfo(cUnit, reg);
648 info->dirty = false;
649}
650
Bill Buzbeec6f10662010-02-09 11:16:15 -0800651extern void dvmCompilerMarkDirty(CompilationUnit *cUnit, int reg)
Bill Buzbee1465db52009-09-23 17:17:35 -0700652{
653 RegisterInfo *info = getRegInfo(cUnit, reg);
654 info->dirty = true;
655}
656
Elliott Hughes6a555132010-02-25 15:41:42 -0800657extern void dvmCompilerMarkInUse(CompilationUnit *cUnit, int reg)
Bill Buzbee1465db52009-09-23 17:17:35 -0700658{
Ben Cheng5d90c202009-11-22 23:31:11 -0800659 RegisterInfo *info = getRegInfo(cUnit, reg);
660 info->inUse = true;
Bill Buzbee1465db52009-09-23 17:17:35 -0700661}
662
Andy McFadden953a0ed2010-09-17 15:48:38 -0700663static void copyRegInfo(CompilationUnit *cUnit, int newReg, int oldReg)
Bill Buzbee1465db52009-09-23 17:17:35 -0700664{
665 RegisterInfo *newInfo = getRegInfo(cUnit, newReg);
666 RegisterInfo *oldInfo = getRegInfo(cUnit, oldReg);
667 *newInfo = *oldInfo;
668 newInfo->reg = newReg;
669}
670
671/*
672 * Return an updated location record with current in-register status.
673 * If the value lives in live temps, reflect that fact. No code
674 * is generated. The the live value is part of an older pair,
675 * clobber both low and high.
676 * TUNING: clobbering both is a bit heavy-handed, but the alternative
677 * is a bit complex when dealing with FP regs. Examine code to see
678 * if it's worthwhile trying to be more clever here.
679 */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800680extern RegLocation dvmCompilerUpdateLoc(CompilationUnit *cUnit, RegLocation loc)
Bill Buzbee1465db52009-09-23 17:17:35 -0700681{
682 assert(!loc.wide);
683 if (loc.location == kLocDalvikFrame) {
684 RegisterInfo *infoLo = allocLive(cUnit, loc.sRegLow, kAnyReg);
685 if (infoLo) {
686 if (infoLo->pair) {
Bill Buzbeec6f10662010-02-09 11:16:15 -0800687 dvmCompilerClobber(cUnit, infoLo->reg);
688 dvmCompilerClobber(cUnit, infoLo->partner);
Bill Buzbee1465db52009-09-23 17:17:35 -0700689 } else {
690 loc.lowReg = infoLo->reg;
691 loc.location = kLocPhysReg;
692 }
693 }
694 }
695
696 return loc;
697}
698
699/* see comments for updateLoc */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800700extern RegLocation dvmCompilerUpdateLocWide(CompilationUnit *cUnit,
701 RegLocation loc)
Bill Buzbee1465db52009-09-23 17:17:35 -0700702{
703 assert(loc.wide);
704 if (loc.location == kLocDalvikFrame) {
Bill Buzbee80cef862010-03-25 10:38:34 -0700705 // Are the dalvik regs already live in physical registers?
Bill Buzbee1465db52009-09-23 17:17:35 -0700706 RegisterInfo *infoLo = allocLive(cUnit, loc.sRegLow, kAnyReg);
Bill Buzbeec6f10662010-02-09 11:16:15 -0800707 RegisterInfo *infoHi = allocLive(cUnit,
708 dvmCompilerSRegHi(loc.sRegLow), kAnyReg);
Bill Buzbee1465db52009-09-23 17:17:35 -0700709 bool match = true;
710 match = match && (infoLo != NULL);
711 match = match && (infoHi != NULL);
Bill Buzbee80cef862010-03-25 10:38:34 -0700712 // Are they both core or both FP?
Bill Buzbee1465db52009-09-23 17:17:35 -0700713 match = match && (FPREG(infoLo->reg) == FPREG(infoHi->reg));
Bill Buzbee80cef862010-03-25 10:38:34 -0700714 // If a pair of floating point singles, are they properly aligned?
Bill Buzbee1465db52009-09-23 17:17:35 -0700715 if (match && FPREG(infoLo->reg)) {
716 match &= ((infoLo->reg & 0x1) == 0);
717 match &= ((infoHi->reg - infoLo->reg) == 1);
718 }
Bill Buzbee80cef862010-03-25 10:38:34 -0700719 // If previously used as a pair, it is the same pair?
720 if (match && (infoLo->pair || infoHi->pair)) {
721 match = (infoLo->pair == infoHi->pair);
722 match &= ((infoLo->reg == infoHi->partner) &&
723 (infoHi->reg == infoLo->partner));
724 }
Bill Buzbee1465db52009-09-23 17:17:35 -0700725 if (match) {
Bill Buzbee80cef862010-03-25 10:38:34 -0700726 // Can reuse - update the register usage info
Bill Buzbee1465db52009-09-23 17:17:35 -0700727 loc.lowReg = infoLo->reg;
728 loc.highReg = infoHi->reg;
729 loc.location = kLocPhysReg;
Bill Buzbeec6f10662010-02-09 11:16:15 -0800730 dvmCompilerMarkPair(cUnit, loc.lowReg, loc.highReg);
Bill Buzbee1465db52009-09-23 17:17:35 -0700731 assert(!FPREG(loc.lowReg) || ((loc.lowReg & 0x1) == 0));
732 return loc;
733 }
Bill Buzbee80cef862010-03-25 10:38:34 -0700734 // Can't easily reuse - clobber any overlaps
Bill Buzbee1465db52009-09-23 17:17:35 -0700735 if (infoLo) {
Bill Buzbeec6f10662010-02-09 11:16:15 -0800736 dvmCompilerClobber(cUnit, infoLo->reg);
Bill Buzbee1465db52009-09-23 17:17:35 -0700737 if (infoLo->pair)
Bill Buzbeec6f10662010-02-09 11:16:15 -0800738 dvmCompilerClobber(cUnit, infoLo->partner);
Bill Buzbee1465db52009-09-23 17:17:35 -0700739 }
740 if (infoHi) {
Bill Buzbeec6f10662010-02-09 11:16:15 -0800741 dvmCompilerClobber(cUnit, infoHi->reg);
Bill Buzbee1465db52009-09-23 17:17:35 -0700742 if (infoHi->pair)
Bill Buzbeec6f10662010-02-09 11:16:15 -0800743 dvmCompilerClobber(cUnit, infoHi->partner);
Bill Buzbee1465db52009-09-23 17:17:35 -0700744 }
745 }
746
747 return loc;
748}
749
750static RegLocation evalLocWide(CompilationUnit *cUnit, RegLocation loc,
751 int regClass, bool update)
752{
753 assert(loc.wide);
754 int newRegs;
755 int lowReg;
756 int highReg;
757
Bill Buzbeec6f10662010-02-09 11:16:15 -0800758 loc = dvmCompilerUpdateLocWide(cUnit, loc);
Bill Buzbee1465db52009-09-23 17:17:35 -0700759
760 /* If already in registers, we can assume proper form. Right reg class? */
761 if (loc.location == kLocPhysReg) {
762 assert(FPREG(loc.lowReg) == FPREG(loc.highReg));
763 assert(!FPREG(loc.lowReg) || ((loc.lowReg & 0x1) == 0));
764 if (!regClassMatches(regClass, loc.lowReg)) {
765 /* Wrong register class. Reallocate and copy */
Ben Cheng5d90c202009-11-22 23:31:11 -0800766 newRegs = dvmCompilerAllocTypedTempPair(cUnit, loc.fp, regClass);
Bill Buzbee1465db52009-09-23 17:17:35 -0700767 lowReg = newRegs & 0xff;
768 highReg = (newRegs >> 8) & 0xff;
Ben Cheng5d90c202009-11-22 23:31:11 -0800769 dvmCompilerRegCopyWide(cUnit, lowReg, highReg, loc.lowReg,
770 loc.highReg);
Bill Buzbee1465db52009-09-23 17:17:35 -0700771 copyRegInfo(cUnit, lowReg, loc.lowReg);
772 copyRegInfo(cUnit, highReg, loc.highReg);
Bill Buzbeec6f10662010-02-09 11:16:15 -0800773 dvmCompilerClobber(cUnit, loc.lowReg);
774 dvmCompilerClobber(cUnit, loc.highReg);
Bill Buzbee1465db52009-09-23 17:17:35 -0700775 loc.lowReg = lowReg;
776 loc.highReg = highReg;
Bill Buzbeec6f10662010-02-09 11:16:15 -0800777 dvmCompilerMarkPair(cUnit, loc.lowReg, loc.highReg);
Bill Buzbee1465db52009-09-23 17:17:35 -0700778 assert(!FPREG(loc.lowReg) || ((loc.lowReg & 0x1) == 0));
779 }
780 return loc;
781 }
782
783 assert((loc.location != kLocRetval) || (loc.sRegLow == INVALID_SREG));
Ben Cheng5d90c202009-11-22 23:31:11 -0800784 assert((loc.location != kLocRetval) ||
Bill Buzbeec6f10662010-02-09 11:16:15 -0800785 (dvmCompilerSRegHi(loc.sRegLow) == INVALID_SREG));
Bill Buzbee1465db52009-09-23 17:17:35 -0700786
Ben Cheng5d90c202009-11-22 23:31:11 -0800787 newRegs = dvmCompilerAllocTypedTempPair(cUnit, loc.fp, regClass);
Bill Buzbee1465db52009-09-23 17:17:35 -0700788 loc.lowReg = newRegs & 0xff;
789 loc.highReg = (newRegs >> 8) & 0xff;
790
Bill Buzbeec6f10662010-02-09 11:16:15 -0800791 dvmCompilerMarkPair(cUnit, loc.lowReg, loc.highReg);
Bill Buzbee1465db52009-09-23 17:17:35 -0700792 if (update) {
793 loc.location = kLocPhysReg;
Bill Buzbeec6f10662010-02-09 11:16:15 -0800794 dvmCompilerMarkLive(cUnit, loc.lowReg, loc.sRegLow);
795 dvmCompilerMarkLive(cUnit, loc.highReg, dvmCompilerSRegHi(loc.sRegLow));
Bill Buzbee1465db52009-09-23 17:17:35 -0700796 }
797 assert(!FPREG(loc.lowReg) || ((loc.lowReg & 0x1) == 0));
798 return loc;
799}
800
Bill Buzbeec6f10662010-02-09 11:16:15 -0800801extern RegLocation dvmCompilerEvalLoc(CompilationUnit *cUnit, RegLocation loc,
802 int regClass, bool update)
Bill Buzbee1465db52009-09-23 17:17:35 -0700803{
Bill Buzbee1465db52009-09-23 17:17:35 -0700804 int newReg;
805 if (loc.wide)
806 return evalLocWide(cUnit, loc, regClass, update);
Bill Buzbeec6f10662010-02-09 11:16:15 -0800807 loc = dvmCompilerUpdateLoc(cUnit, loc);
Bill Buzbee1465db52009-09-23 17:17:35 -0700808
809 if (loc.location == kLocPhysReg) {
810 if (!regClassMatches(regClass, loc.lowReg)) {
811 /* Wrong register class. Realloc, copy and transfer ownership */
Ben Cheng5d90c202009-11-22 23:31:11 -0800812 newReg = dvmCompilerAllocTypedTemp(cUnit, loc.fp, regClass);
813 dvmCompilerRegCopy(cUnit, newReg, loc.lowReg);
Bill Buzbee1465db52009-09-23 17:17:35 -0700814 copyRegInfo(cUnit, newReg, loc.lowReg);
Bill Buzbeec6f10662010-02-09 11:16:15 -0800815 dvmCompilerClobber(cUnit, loc.lowReg);
Bill Buzbee1465db52009-09-23 17:17:35 -0700816 loc.lowReg = newReg;
817 }
818 return loc;
819 }
820
821 assert((loc.location != kLocRetval) || (loc.sRegLow == INVALID_SREG));
822
Ben Cheng5d90c202009-11-22 23:31:11 -0800823 newReg = dvmCompilerAllocTypedTemp(cUnit, loc.fp, regClass);
Bill Buzbee1465db52009-09-23 17:17:35 -0700824 loc.lowReg = newReg;
825
826 if (update) {
827 loc.location = kLocPhysReg;
Bill Buzbeec6f10662010-02-09 11:16:15 -0800828 dvmCompilerMarkLive(cUnit, loc.lowReg, loc.sRegLow);
Bill Buzbee1465db52009-09-23 17:17:35 -0700829 }
830 return loc;
831}
832
Bill Buzbee1465db52009-09-23 17:17:35 -0700833static inline int getDestSSAName(MIR *mir, int num)
834{
835 assert(mir->ssaRep->numDefs > num);
836 return mir->ssaRep->defs[num];
837}
838
839// Get the LocRecord associated with an SSA name use.
Bill Buzbeec6f10662010-02-09 11:16:15 -0800840extern RegLocation dvmCompilerGetSrc(CompilationUnit *cUnit, MIR *mir, int num)
Bill Buzbee1465db52009-09-23 17:17:35 -0700841{
Bill Buzbeec6f10662010-02-09 11:16:15 -0800842 RegLocation loc = cUnit->regLocation[
843 SREG(cUnit, dvmCompilerSSASrc(mir, num))];
844 loc.fp = cUnit->regLocation[dvmCompilerSSASrc(mir, num)].fp;
Bill Buzbee1465db52009-09-23 17:17:35 -0700845 loc.wide = false;
846 return loc;
847}
848
849// Get the LocRecord associated with an SSA name def.
Bill Buzbeec6f10662010-02-09 11:16:15 -0800850extern RegLocation dvmCompilerGetDest(CompilationUnit *cUnit, MIR *mir,
851 int num)
Bill Buzbee1465db52009-09-23 17:17:35 -0700852{
853 RegLocation loc = cUnit->regLocation[SREG(cUnit, getDestSSAName(mir, num))];
854 loc.fp = cUnit->regLocation[getDestSSAName(mir, num)].fp;
855 loc.wide = false;
856 return loc;
857}
858
859static RegLocation getLocWide(CompilationUnit *cUnit, MIR *mir,
Bill Buzbeec6f10662010-02-09 11:16:15 -0800860 int low, int high, bool isSrc)
Bill Buzbee1465db52009-09-23 17:17:35 -0700861{
862 RegLocation lowLoc;
863 RegLocation highLoc;
864 /* Copy loc record for low word and patch in data from high word */
865 if (isSrc) {
Bill Buzbeec6f10662010-02-09 11:16:15 -0800866 lowLoc = dvmCompilerGetSrc(cUnit, mir, low);
867 highLoc = dvmCompilerGetSrc(cUnit, mir, high);
Bill Buzbee1465db52009-09-23 17:17:35 -0700868 } else {
Bill Buzbeec6f10662010-02-09 11:16:15 -0800869 lowLoc = dvmCompilerGetDest(cUnit, mir, low);
870 highLoc = dvmCompilerGetDest(cUnit, mir, high);
Bill Buzbee1465db52009-09-23 17:17:35 -0700871 }
872 /* Avoid this case by either promoting both or neither. */
873 assert(lowLoc.location == highLoc.location);
874 if (lowLoc.location == kLocPhysReg) {
875 /* This case shouldn't happen if we've named correctly */
876 assert(lowLoc.fp == highLoc.fp);
877 }
878 lowLoc.wide = true;
879 lowLoc.highReg = highLoc.lowReg;
880 return lowLoc;
881}
Ben Cheng5d90c202009-11-22 23:31:11 -0800882
Bill Buzbeec6f10662010-02-09 11:16:15 -0800883extern RegLocation dvmCompilerGetDestWide(CompilationUnit *cUnit, MIR *mir,
884 int low, int high)
Bill Buzbee1465db52009-09-23 17:17:35 -0700885{
886 return getLocWide(cUnit, mir, low, high, false);
887}
888
Bill Buzbeec6f10662010-02-09 11:16:15 -0800889extern RegLocation dvmCompilerGetSrcWide(CompilationUnit *cUnit, MIR *mir,
Bill Buzbee1465db52009-09-23 17:17:35 -0700890 int low, int high)
891{
892 return getLocWide(cUnit, mir, low, high, true);
893}
894
Bill Buzbee1465db52009-09-23 17:17:35 -0700895/* Kill the corresponding bit in the null-checked register list */
Bill Buzbeec6f10662010-02-09 11:16:15 -0800896extern void dvmCompilerKillNullCheckedLoc(CompilationUnit *cUnit,
897 RegLocation loc)
Bill Buzbee1465db52009-09-23 17:17:35 -0700898{
899 if (loc.location != kLocRetval) {
900 assert(loc.sRegLow != INVALID_SREG);
901 dvmClearBit(cUnit->regPool->nullCheckedRegs, loc.sRegLow);
902 if (loc.wide) {
Bill Buzbeec6f10662010-02-09 11:16:15 -0800903 assert(dvmCompilerSRegHi(loc.sRegLow) != INVALID_SREG);
904 dvmClearBit(cUnit->regPool->nullCheckedRegs,
905 dvmCompilerSRegHi(loc.sRegLow));
Bill Buzbee1465db52009-09-23 17:17:35 -0700906 }
907 }
908}