blob: 7fd062d5a5b75b053257b58a1c6b4922998dd842 [file] [log] [blame]
buzbee67bf8852011-08-17 17:51:35 -07001/*
2 * Copyright (C) 2011 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 "../CompilerUtility.h"
26#include "../CompilerIR.h"
27#include "../Dataflow.h"
28#include "Ralloc.h"
29
30#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
41/*
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 */
46extern void oatResetRegPool(CompilationUnit* cUnit)
47{
48 int i;
49 for (i=0; i < cUnit->regPool->numCoreRegs; i++) {
50 if (cUnit->regPool->coreRegs[i].isTemp)
51 cUnit->regPool->coreRegs[i].inUse = false;
52 }
53 for (i=0; i < cUnit->regPool->numFPRegs; i++) {
54 if (cUnit->regPool->FPRegs[i].isTemp)
55 cUnit->regPool->FPRegs[i].inUse = false;
56 }
57}
58
59 /* Set up temp & preserved register pools specialized by target */
60extern void oatInitPool(RegisterInfo* regs, int* regNums, int num)
61{
62 int i;
63 for (i=0; i < num; i++) {
64 regs[i].reg = regNums[i];
65 regs[i].inUse = false;
66 regs[i].isTemp = false;
67 regs[i].pair = false;
68 regs[i].live = false;
69 regs[i].dirty = false;
70 regs[i].sReg = INVALID_SREG;
71 }
72}
73
buzbeeed3e9302011-09-23 17:34:19 -070074STATIC void dumpRegPool(RegisterInfo* p, int numRegs)
buzbee67bf8852011-08-17 17:51:35 -070075{
76 int i;
77 LOG(INFO) << "================================================";
78 for (i=0; i < numRegs; i++ ){
79 char buf[100];
80 snprintf(buf, 100,
81 "R[%d]: T:%d, U:%d, P:%d, p:%d, LV:%d, D:%d, SR:%d, ST:%x, EN:%x",
82 p[i].reg, p[i].isTemp, p[i].inUse, p[i].pair, p[i].partner,
83 p[i].live, p[i].dirty, p[i].sReg,(int)p[i].defStart,
84 (int)p[i].defEnd);
85 LOG(INFO) << buf;
86 }
87 LOG(INFO) << "================================================";
88}
89
buzbee6181f792011-09-29 11:14:04 -070090void oatDumpCoreRegPool(CompilationUnit* cUnit)
91{
92 dumpRegPool(cUnit->regPool->coreRegs, cUnit->regPool->numCoreRegs);
93}
94
95void oatDumpFpRegPool(CompilationUnit* cUnit)
96{
97 dumpRegPool(cUnit->regPool->FPRegs, cUnit->regPool->numFPRegs);
98}
99
buzbee67bf8852011-08-17 17:51:35 -0700100void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2)
101{
buzbee68253262011-10-07 14:02:25 -0700102 RegisterInfo* info1 = oatGetRegInfo(cUnit, reg1);
103 RegisterInfo* info2 = oatGetRegInfo(cUnit, reg2);
buzbeeed3e9302011-09-23 17:34:19 -0700104 DCHECK(info1 && info2 && info1->pair && info2->pair &&
buzbee67bf8852011-08-17 17:51:35 -0700105 (info1->partner == info2->reg) &&
106 (info2->partner == info1->reg));
107 if ((info1->live && info1->dirty) || (info2->live && info2->dirty)) {
108 if (!(info1->isTemp && info2->isTemp)) {
109 /* Should not happen. If it does, there's a problem in evalLoc */
110 LOG(FATAL) << "Long half-temp, half-promoted";
111 }
112
113 info1->dirty = false;
114 info2->dirty = false;
115 if (oatS2VReg(cUnit, info2->sReg) <
116 oatS2VReg(cUnit, info1->sReg))
117 info1 = info2;
118 int vReg = oatS2VReg(cUnit, info1->sReg);
119 oatFlushRegWideImpl(cUnit, rSP,
120 oatVRegOffset(cUnit, vReg),
121 info1->reg, info1->partner);
122 }
123}
124
125void oatFlushReg(CompilationUnit* cUnit, int reg)
126{
buzbee68253262011-10-07 14:02:25 -0700127 RegisterInfo* info = oatGetRegInfo(cUnit, reg);
buzbee67bf8852011-08-17 17:51:35 -0700128 if (info->live && info->dirty) {
129 info->dirty = false;
130 int vReg = oatS2VReg(cUnit, info->sReg);
131 oatFlushRegImpl(cUnit, rSP,
132 oatVRegOffset(cUnit, vReg),
133 reg, kWord);
134 }
135}
136
buzbee67bf8852011-08-17 17:51:35 -0700137/* Mark a temp register as dead. Does not affect allocation state. */
138void oatClobber(CompilationUnit* cUnit, int reg)
139{
buzbee68253262011-10-07 14:02:25 -0700140 RegisterInfo* p = oatGetRegInfo(cUnit, reg);
141 if (p->isTemp) {
142 DCHECK(!(p->live && p->dirty)) << "Live & dirty temp in clobber";
143 p->live = false;
144 p->sReg = INVALID_SREG;
145 p->defStart = NULL;
146 p->defEnd = NULL;
147 if (p->pair) {
148 p->pair = false;
149 oatClobber(cUnit, p->partner);
150 }
buzbee67bf8852011-08-17 17:51:35 -0700151 }
152}
153
buzbeeed3e9302011-09-23 17:34:19 -0700154STATIC void clobberSRegBody(RegisterInfo* p, int numRegs, int sReg)
buzbee67bf8852011-08-17 17:51:35 -0700155{
156 int i;
157 for (i=0; i< numRegs; i++) {
158 if (p[i].sReg == sReg) {
159 if (p[i].isTemp) {
160 p[i].live = false;
161 }
162 p[i].defStart = NULL;
163 p[i].defEnd = NULL;
164 }
165 }
166}
167
168/* Clobber any temp associated with an sReg. Could be in either class */
169extern void oatClobberSReg(CompilationUnit* cUnit, int sReg)
170{
171 clobberSRegBody(cUnit->regPool->coreRegs, cUnit->regPool->numCoreRegs,
172 sReg);
173 clobberSRegBody(cUnit->regPool->FPRegs, cUnit->regPool->numFPRegs,
174 sReg);
175}
176
177/* Reserve a callee-save register. Return -1 if none available */
178extern int oatAllocPreservedCoreReg(CompilationUnit* cUnit, int sReg)
179{
180 int res = -1;
181 RegisterInfo* coreRegs = cUnit->regPool->coreRegs;
182 for (int i = 0; i < cUnit->regPool->numCoreRegs; i++) {
183 if (!coreRegs[i].isTemp && !coreRegs[i].inUse) {
184 res = coreRegs[i].reg;
185 coreRegs[i].inUse = true;
186 cUnit->coreSpillMask |= (1 << res);
buzbeec41e5b52011-09-23 12:46:19 -0700187 cUnit->coreVmapTable.push_back(sReg);
buzbeebbaf8942011-10-02 13:08:29 -0700188 cUnit->numCoreSpills++;
buzbee67bf8852011-08-17 17:51:35 -0700189 cUnit->regLocation[sReg].location = kLocPhysReg;
190 cUnit->regLocation[sReg].lowReg = res;
191 cUnit->regLocation[sReg].home = true;
192 break;
193 }
194 }
195 return res;
196}
197
198/*
buzbeebbaf8942011-10-02 13:08:29 -0700199 * Mark a callee-save fp register as promoted. Note that
200 * vpush/vpop uses contiguous register lists so we must
201 * include any holes in the mask. Associate holes with
buzbee3ddc0d12011-10-05 10:36:21 -0700202 * Dalvik register INVALID_VREG (0xFFFFU).
buzbeebbaf8942011-10-02 13:08:29 -0700203 */
204STATIC void markPreservedSingle(CompilationUnit* cUnit, int sReg, int reg)
205{
206 DCHECK_GE(reg, FP_REG_MASK + FP_CALLEE_SAVE_BASE);
207 reg = (reg & FP_REG_MASK) - FP_CALLEE_SAVE_BASE;
208 // Ensure fpVmapTable is large enough
209 int tableSize = cUnit->fpVmapTable.size();
210 for (int i = tableSize; i < (reg + 1); i++) {
buzbee3ddc0d12011-10-05 10:36:21 -0700211 cUnit->fpVmapTable.push_back(INVALID_VREG);
buzbeebbaf8942011-10-02 13:08:29 -0700212 }
213 // Add the current mapping
214 cUnit->fpVmapTable[reg] = sReg;
215 // Size of fpVmapTable is high-water mark, use to set mask
216 cUnit->numFPSpills = cUnit->fpVmapTable.size();
217 cUnit->fpSpillMask = ((1 << cUnit->numFPSpills) - 1) << FP_CALLEE_SAVE_BASE;
218}
219
220/*
buzbee67bf8852011-08-17 17:51:35 -0700221 * Reserve a callee-save fp single register. Try to fullfill request for
222 * even/odd allocation, but go ahead and allocate anything if not
223 * available. If nothing's available, return -1.
224 */
buzbeeed3e9302011-09-23 17:34:19 -0700225STATIC int allocPreservedSingle(CompilationUnit* cUnit, int sReg, bool even)
buzbee67bf8852011-08-17 17:51:35 -0700226{
227 int res = -1;
228 RegisterInfo* FPRegs = cUnit->regPool->FPRegs;
229 for (int i = 0; i < cUnit->regPool->numFPRegs; i++) {
230 if (!FPRegs[i].isTemp && !FPRegs[i].inUse &&
231 ((FPRegs[i].reg & 0x1) == 0) == even) {
232 res = FPRegs[i].reg;
233 FPRegs[i].inUse = true;
buzbeebbaf8942011-10-02 13:08:29 -0700234 markPreservedSingle(cUnit, sReg, res);
buzbee67bf8852011-08-17 17:51:35 -0700235 cUnit->regLocation[sReg].fpLocation = kLocPhysReg;
236 cUnit->regLocation[sReg].fpLowReg = res;
237 cUnit->regLocation[sReg].home = true;
238 break;
239 }
240 }
241 return res;
242}
243
244/*
245 * Somewhat messy code here. We want to allocate a pair of contiguous
246 * physical single-precision floating point registers starting with
247 * an even numbered reg. It is possible that the paired sReg (sReg+1)
248 * has already been allocated - try to fit if possible. Fail to
249 * allocate if we can't meet the requirements for the pair of
250 * sReg<=sX[even] & (sReg+1)<= sX+1.
251 */
buzbeeed3e9302011-09-23 17:34:19 -0700252STATIC int allocPreservedDouble(CompilationUnit* cUnit, int sReg)
buzbee67bf8852011-08-17 17:51:35 -0700253{
254 int res = -1; // Assume failure
255 if (cUnit->regLocation[sReg+1].fpLocation == kLocPhysReg) {
256 // Upper reg is already allocated. Can we fit?
257 int highReg = cUnit->regLocation[sReg+1].fpLowReg;
258 if ((highReg & 1) == 0) {
259 // High reg is even - fail.
260 return res;
261 }
262 // Is the low reg of the pair free?
buzbee68253262011-10-07 14:02:25 -0700263 RegisterInfo* p = oatGetRegInfo(cUnit, highReg-1);
buzbee67bf8852011-08-17 17:51:35 -0700264 if (p->inUse || p->isTemp) {
265 // Already allocated or not preserved - fail.
266 return res;
267 }
268 // OK - good to go.
269 res = p->reg;
270 p->inUse = true;
buzbeeed3e9302011-09-23 17:34:19 -0700271 DCHECK_EQ((res & 1), 0);
buzbeebbaf8942011-10-02 13:08:29 -0700272 markPreservedSingle(cUnit, sReg, res);
buzbee67bf8852011-08-17 17:51:35 -0700273 } else {
274 RegisterInfo* FPRegs = cUnit->regPool->FPRegs;
275 for (int i = 0; i < cUnit->regPool->numFPRegs; i++) {
276 if (!FPRegs[i].isTemp && !FPRegs[i].inUse &&
277 ((FPRegs[i].reg & 0x1) == 0x0) &&
278 !FPRegs[i+1].isTemp && !FPRegs[i+1].inUse &&
279 ((FPRegs[i+1].reg & 0x1) == 0x1) &&
280 (FPRegs[i].reg + 1) == FPRegs[i+1].reg) {
281 res = FPRegs[i].reg;
282 FPRegs[i].inUse = true;
buzbeebbaf8942011-10-02 13:08:29 -0700283 markPreservedSingle(cUnit, sReg, res);
buzbee67bf8852011-08-17 17:51:35 -0700284 FPRegs[i+1].inUse = true;
buzbeebbaf8942011-10-02 13:08:29 -0700285 DCHECK_EQ(res + 1, FPRegs[i+1].reg);
286 markPreservedSingle(cUnit, sReg+1, res+1);
buzbee67bf8852011-08-17 17:51:35 -0700287 break;
288 }
289 }
290 }
291 if (res != -1) {
292 cUnit->regLocation[sReg].fpLocation = kLocPhysReg;
293 cUnit->regLocation[sReg].fpLowReg = res;
294 cUnit->regLocation[sReg].home = true;
295 cUnit->regLocation[sReg+1].fpLocation = kLocPhysReg;
296 cUnit->regLocation[sReg+1].fpLowReg = res + 1;
297 cUnit->regLocation[sReg+1].home = true;
298 }
299 return res;
300}
301
302
303/*
304 * Reserve a callee-save fp register. If this register can be used
305 * as the first of a double, attempt to allocate an even pair of fp
306 * single regs (but if can't still attempt to allocate a single, preferring
307 * first to allocate an odd register.
308 */
309extern int oatAllocPreservedFPReg(CompilationUnit* cUnit, int sReg,
310 bool doubleStart)
311{
312 int res = -1;
313 if (doubleStart) {
314 res = allocPreservedDouble(cUnit, sReg);
315 } else {
316 }
317 if (res == -1) {
318 res = allocPreservedSingle(cUnit, sReg, false /* try odd # */);
319 }
320 if (res == -1)
321 res = allocPreservedSingle(cUnit, sReg, true /* try even # */);
322 return res;
323}
324
buzbeeed3e9302011-09-23 17:34:19 -0700325STATIC int allocTempBody(CompilationUnit* cUnit, RegisterInfo* p, int numRegs,
buzbee67bf8852011-08-17 17:51:35 -0700326 int* nextTemp, bool required)
327{
328 int i;
329 int next = *nextTemp;
330 for (i=0; i< numRegs; i++) {
331 if (next >= numRegs)
332 next = 0;
333 if (p[next].isTemp && !p[next].inUse && !p[next].live) {
334 oatClobber(cUnit, p[next].reg);
335 p[next].inUse = true;
336 p[next].pair = false;
337 *nextTemp = next + 1;
338 return p[next].reg;
339 }
340 next++;
341 }
342 next = *nextTemp;
343 for (i=0; i< numRegs; i++) {
344 if (next >= numRegs)
345 next = 0;
346 if (p[next].isTemp && !p[next].inUse) {
347 oatClobber(cUnit, p[next].reg);
348 p[next].inUse = true;
349 p[next].pair = false;
350 *nextTemp = next + 1;
351 return p[next].reg;
352 }
353 next++;
354 }
355 if (required) {
buzbee6181f792011-09-29 11:14:04 -0700356 oatCodegenDump(cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700357 dumpRegPool(cUnit->regPool->coreRegs,
358 cUnit->regPool->numCoreRegs);
359 LOG(FATAL) << "No free temp registers";
360 }
361 return -1; // No register available
362}
363
364//REDO: too many assumptions.
365extern int oatAllocTempDouble(CompilationUnit* cUnit)
366{
367 RegisterInfo* p = cUnit->regPool->FPRegs;
368 int numRegs = cUnit->regPool->numFPRegs;
369 int next = cUnit->regPool->nextFPReg;
370 int i;
371
372 for (i=0; i < numRegs; i+=2) {
373 /* Cleanup - not all targets need aligned regs */
374 if (next & 1)
375 next++;
376 if (next >= numRegs)
377 next = 0;
378 if ((p[next].isTemp && !p[next].inUse && !p[next].live) &&
379 (p[next+1].isTemp && !p[next+1].inUse && !p[next+1].live)) {
380 oatClobber(cUnit, p[next].reg);
381 oatClobber(cUnit, p[next+1].reg);
382 p[next].inUse = true;
383 p[next+1].inUse = true;
buzbeeed3e9302011-09-23 17:34:19 -0700384 DCHECK_EQ((p[next].reg+1), p[next+1].reg);
385 DCHECK_EQ((p[next].reg & 0x1), 0);
buzbee67bf8852011-08-17 17:51:35 -0700386 cUnit->regPool->nextFPReg += 2;
387 return p[next].reg;
388 }
389 next += 2;
390 }
391 next = cUnit->regPool->nextFPReg;
392 for (i=0; i < numRegs; i+=2) {
393 if (next >= numRegs)
394 next = 0;
395 if (p[next].isTemp && !p[next].inUse && p[next+1].isTemp &&
396 !p[next+1].inUse) {
397 oatClobber(cUnit, p[next].reg);
398 oatClobber(cUnit, p[next+1].reg);
399 p[next].inUse = true;
400 p[next+1].inUse = true;
buzbeeed3e9302011-09-23 17:34:19 -0700401 DCHECK_EQ((p[next].reg+1), p[next+1].reg);
402 DCHECK_EQ((p[next].reg & 0x1), 0);
buzbee67bf8852011-08-17 17:51:35 -0700403 cUnit->regPool->nextFPReg += 2;
404 return p[next].reg;
405 }
406 next += 2;
407 }
buzbee6181f792011-09-29 11:14:04 -0700408 LOG(FATAL) << "No free temp registers (pair)";
buzbee67bf8852011-08-17 17:51:35 -0700409 return -1;
410}
411
412/* Return a temp if one is available, -1 otherwise */
413extern int oatAllocFreeTemp(CompilationUnit* cUnit)
414{
415 return allocTempBody(cUnit, cUnit->regPool->coreRegs,
416 cUnit->regPool->numCoreRegs,
417 &cUnit->regPool->nextCoreReg, true);
418}
419
420extern int oatAllocTemp(CompilationUnit* cUnit)
421{
422 return allocTempBody(cUnit, cUnit->regPool->coreRegs,
423 cUnit->regPool->numCoreRegs,
424 &cUnit->regPool->nextCoreReg, true);
425}
426
427extern int oatAllocTempFloat(CompilationUnit* cUnit)
428{
429 return allocTempBody(cUnit, cUnit->regPool->FPRegs,
430 cUnit->regPool->numFPRegs,
431 &cUnit->regPool->nextFPReg, true);
432}
433
buzbeeed3e9302011-09-23 17:34:19 -0700434STATIC RegisterInfo* allocLiveBody(RegisterInfo* p, int numRegs, int sReg)
buzbee67bf8852011-08-17 17:51:35 -0700435{
436 int i;
437 if (sReg == -1)
438 return NULL;
439 for (i=0; i < numRegs; i++) {
440 if (p[i].live && (p[i].sReg == sReg)) {
441 if (p[i].isTemp)
442 p[i].inUse = true;
443 return &p[i];
444 }
445 }
446 return NULL;
447}
448
buzbeeed3e9302011-09-23 17:34:19 -0700449STATIC RegisterInfo* allocLive(CompilationUnit* cUnit, int sReg,
buzbee67bf8852011-08-17 17:51:35 -0700450 int regClass)
451{
452 RegisterInfo* res = NULL;
453 switch(regClass) {
454 case kAnyReg:
455 res = allocLiveBody(cUnit->regPool->FPRegs,
456 cUnit->regPool->numFPRegs, sReg);
457 if (res)
458 break;
459 /* Intentional fallthrough */
460 case kCoreReg:
461 res = allocLiveBody(cUnit->regPool->coreRegs,
462 cUnit->regPool->numCoreRegs, sReg);
463 break;
464 case kFPReg:
465 res = allocLiveBody(cUnit->regPool->FPRegs,
466 cUnit->regPool->numFPRegs, sReg);
467 break;
468 default:
469 LOG(FATAL) << "Invalid register type";
470 }
471 return res;
472}
473
474extern void oatFreeTemp(CompilationUnit* cUnit, int reg)
475{
476 RegisterInfo* p = cUnit->regPool->coreRegs;
477 int numRegs = cUnit->regPool->numCoreRegs;
478 int i;
479 for (i=0; i< numRegs; i++) {
480 if (p[i].reg == reg) {
481 if (p[i].isTemp) {
482 p[i].inUse = false;
483 }
484 p[i].pair = false;
485 return;
486 }
487 }
488 p = cUnit->regPool->FPRegs;
489 numRegs = cUnit->regPool->numFPRegs;
490 for (i=0; i< numRegs; i++) {
491 if (p[i].reg == reg) {
492 if (p[i].isTemp) {
493 p[i].inUse = false;
494 }
495 p[i].pair = false;
496 return;
497 }
498 }
499 LOG(FATAL) << "Tried to free a non-existant temp: r" << reg;
500}
501
502extern RegisterInfo* oatIsLive(CompilationUnit* cUnit, int reg)
503{
504 RegisterInfo* p = cUnit->regPool->coreRegs;
505 int numRegs = cUnit->regPool->numCoreRegs;
506 int i;
507 for (i=0; i< numRegs; i++) {
508 if (p[i].reg == reg) {
509 return p[i].live ? &p[i] : NULL;
510 }
511 }
512 p = cUnit->regPool->FPRegs;
513 numRegs = cUnit->regPool->numFPRegs;
514 for (i=0; i< numRegs; i++) {
515 if (p[i].reg == reg) {
516 return p[i].live ? &p[i] : NULL;
517 }
518 }
519 return NULL;
520}
521
522extern RegisterInfo* oatIsTemp(CompilationUnit* cUnit, int reg)
523{
buzbee68253262011-10-07 14:02:25 -0700524 RegisterInfo* p = oatGetRegInfo(cUnit, reg);
buzbee67bf8852011-08-17 17:51:35 -0700525 return (p->isTemp) ? p : NULL;
526}
527
buzbeeb29e4d12011-09-26 15:05:48 -0700528extern RegisterInfo* oatIsPromoted(CompilationUnit* cUnit, int reg)
529{
buzbee68253262011-10-07 14:02:25 -0700530 RegisterInfo* p = oatGetRegInfo(cUnit, reg);
buzbeeb29e4d12011-09-26 15:05:48 -0700531 return (p->isTemp) ? NULL : p;
532}
533
buzbee67bf8852011-08-17 17:51:35 -0700534extern bool oatIsDirty(CompilationUnit* cUnit, int reg)
535{
buzbee68253262011-10-07 14:02:25 -0700536 RegisterInfo* p = oatGetRegInfo(cUnit, reg);
buzbee67bf8852011-08-17 17:51:35 -0700537 return p->dirty;
538}
539
540/*
541 * Similar to oatAllocTemp(), but forces the allocation of a specific
542 * register. No check is made to see if the register was previously
543 * allocated. Use with caution.
544 */
545extern void oatLockTemp(CompilationUnit* cUnit, int reg)
546{
547 RegisterInfo* p = cUnit->regPool->coreRegs;
548 int numRegs = cUnit->regPool->numCoreRegs;
549 int i;
550 for (i=0; i< numRegs; i++) {
551 if (p[i].reg == reg) {
buzbeeed3e9302011-09-23 17:34:19 -0700552 DCHECK(p[i].isTemp);
buzbee67bf8852011-08-17 17:51:35 -0700553 p[i].inUse = true;
554 p[i].live = false;
555 return;
556 }
557 }
558 p = cUnit->regPool->FPRegs;
559 numRegs = cUnit->regPool->numFPRegs;
560 for (i=0; i< numRegs; i++) {
561 if (p[i].reg == reg) {
buzbeeed3e9302011-09-23 17:34:19 -0700562 DCHECK(p[i].isTemp);
buzbee67bf8852011-08-17 17:51:35 -0700563 p[i].inUse = true;
564 p[i].live = false;
565 return;
566 }
567 }
568 LOG(FATAL) << "Tried to lock a non-existant temp: r" << reg;
569}
570
571extern void oatResetDef(CompilationUnit* cUnit, int reg)
572{
buzbee68253262011-10-07 14:02:25 -0700573 RegisterInfo* p = oatGetRegInfo(cUnit, reg);
buzbee67bf8852011-08-17 17:51:35 -0700574 p->defStart = NULL;
575 p->defEnd = NULL;
576}
577
buzbeeed3e9302011-09-23 17:34:19 -0700578STATIC void nullifyRange(CompilationUnit* cUnit, LIR *start, LIR *finish,
buzbee67bf8852011-08-17 17:51:35 -0700579 int sReg1, int sReg2)
580{
581 if (start && finish) {
582 LIR *p;
buzbeeed3e9302011-09-23 17:34:19 -0700583 DCHECK_EQ(sReg1, sReg2);
buzbee67bf8852011-08-17 17:51:35 -0700584 for (p = start; ;p = p->next) {
585 ((ArmLIR *)p)->flags.isNop = true;
buzbee6181f792011-09-29 11:14:04 -0700586 ((ArmLIR *)p)->flags.squashed = true;
buzbee67bf8852011-08-17 17:51:35 -0700587 if (p == finish)
588 break;
589 }
590 }
591}
592
593/*
594 * Mark the beginning and end LIR of a def sequence. Note that
595 * on entry start points to the LIR prior to the beginning of the
596 * sequence.
597 */
598extern void oatMarkDef(CompilationUnit* cUnit, RegLocation rl,
599 LIR *start, LIR *finish)
600{
buzbeeed3e9302011-09-23 17:34:19 -0700601 DCHECK(!rl.wide);
602 DCHECK(start && start->next);
603 DCHECK(finish);
buzbee68253262011-10-07 14:02:25 -0700604 RegisterInfo* p = oatGetRegInfo(cUnit, rl.lowReg);
buzbee67bf8852011-08-17 17:51:35 -0700605 p->defStart = start->next;
606 p->defEnd = finish;
607}
608
609/*
610 * Mark the beginning and end LIR of a def sequence. Note that
611 * on entry start points to the LIR prior to the beginning of the
612 * sequence.
613 */
614extern void oatMarkDefWide(CompilationUnit* cUnit, RegLocation rl,
615 LIR *start, LIR *finish)
616{
buzbeeed3e9302011-09-23 17:34:19 -0700617 DCHECK(rl.wide);
618 DCHECK(start && start->next);
619 DCHECK(finish);
buzbee68253262011-10-07 14:02:25 -0700620 RegisterInfo* p = oatGetRegInfo(cUnit, rl.lowReg);
buzbee67bf8852011-08-17 17:51:35 -0700621 oatResetDef(cUnit, rl.highReg); // Only track low of pair
622 p->defStart = start->next;
623 p->defEnd = finish;
624}
625
626extern RegLocation oatWideToNarrow(CompilationUnit* cUnit,
627 RegLocation rl)
628{
buzbeeed3e9302011-09-23 17:34:19 -0700629 DCHECK(rl.wide);
buzbee67bf8852011-08-17 17:51:35 -0700630 if (rl.location == kLocPhysReg) {
buzbee68253262011-10-07 14:02:25 -0700631 RegisterInfo* infoLo = oatGetRegInfo(cUnit, rl.lowReg);
632 RegisterInfo* infoHi = oatGetRegInfo(cUnit, rl.highReg);
buzbee0c7f26d2011-09-07 12:28:51 -0700633 if (infoLo->isTemp) {
634 infoLo->pair = false;
635 infoLo->defStart = NULL;
636 infoLo->defEnd = NULL;
buzbee67bf8852011-08-17 17:51:35 -0700637 }
buzbee0c7f26d2011-09-07 12:28:51 -0700638 if (infoHi->isTemp) {
639 infoHi->pair = false;
640 infoHi->defStart = NULL;
641 infoHi->defEnd = NULL;
buzbee67bf8852011-08-17 17:51:35 -0700642 }
buzbee67bf8852011-08-17 17:51:35 -0700643 }
644 rl.wide = false;
645 return rl;
646}
647
648extern void oatResetDefLoc(CompilationUnit* cUnit, RegLocation rl)
649{
buzbeeed3e9302011-09-23 17:34:19 -0700650 DCHECK(!rl.wide);
buzbee6181f792011-09-29 11:14:04 -0700651 RegisterInfo* p = oatIsTemp(cUnit, rl.lowReg);
652 if (p && !(cUnit->disableOpt & (1 << kSuppressLoads))) {
buzbeeed3e9302011-09-23 17:34:19 -0700653 DCHECK(!p->pair);
buzbee67bf8852011-08-17 17:51:35 -0700654 nullifyRange(cUnit, p->defStart, p->defEnd,
655 p->sReg, rl.sRegLow);
656 }
657 oatResetDef(cUnit, rl.lowReg);
658}
659
660extern void oatResetDefLocWide(CompilationUnit* cUnit, RegLocation rl)
661{
buzbeeed3e9302011-09-23 17:34:19 -0700662 DCHECK(rl.wide);
buzbee6181f792011-09-29 11:14:04 -0700663 RegisterInfo* pLow = oatIsTemp(cUnit, rl.lowReg);
664 RegisterInfo* pHigh = oatIsTemp(cUnit, rl.highReg);
665 if (pLow && !(cUnit->disableOpt & (1 << kSuppressLoads))) {
666 DCHECK(pLow->pair);
667 nullifyRange(cUnit, pLow->defStart, pLow->defEnd,
668 pLow->sReg, rl.sRegLow);
669 }
670 if (pHigh && !(cUnit->disableOpt & (1 << kSuppressLoads))) {
671 DCHECK(pHigh->pair);
buzbee67bf8852011-08-17 17:51:35 -0700672 }
673 oatResetDef(cUnit, rl.lowReg);
674 oatResetDef(cUnit, rl.highReg);
675}
676
677extern void oatResetDefTracking(CompilationUnit* cUnit)
678{
679 int i;
680 for (i=0; i< cUnit->regPool->numCoreRegs; i++) {
681 oatResetDef(cUnit, cUnit->regPool->coreRegs[i].reg);
682 }
683 for (i=0; i< cUnit->regPool->numFPRegs; i++) {
684 oatResetDef(cUnit, cUnit->regPool->FPRegs[i].reg);
685 }
686}
687
688extern void oatClobberAllRegs(CompilationUnit* cUnit)
689{
690 int i;
691 for (i=0; i< cUnit->regPool->numCoreRegs; i++) {
692 oatClobber(cUnit, cUnit->regPool->coreRegs[i].reg);
693 }
694 for (i=0; i< cUnit->regPool->numFPRegs; i++) {
695 oatClobber(cUnit, cUnit->regPool->FPRegs[i].reg);
696 }
697}
698
699/* To be used when explicitly managing register use */
buzbee2e748f32011-08-29 21:02:19 -0700700extern void oatLockCallTemps(CompilationUnit* cUnit)
buzbee67bf8852011-08-17 17:51:35 -0700701{
buzbee2e748f32011-08-29 21:02:19 -0700702 //TODO: Arm specific - move to target dependent code
703 oatLockTemp(cUnit, r0);
704 oatLockTemp(cUnit, r1);
705 oatLockTemp(cUnit, r2);
706 oatLockTemp(cUnit, r3);
buzbee67bf8852011-08-17 17:51:35 -0700707}
708
buzbee0d966cf2011-09-08 17:34:58 -0700709/* To be used when explicitly managing register use */
710extern void oatFreeCallTemps(CompilationUnit* cUnit)
711{
712 //TODO: Arm specific - move to target dependent code
713 oatFreeTemp(cUnit, r0);
714 oatFreeTemp(cUnit, r1);
715 oatFreeTemp(cUnit, r2);
716 oatFreeTemp(cUnit, r3);
717}
718
buzbee67bf8852011-08-17 17:51:35 -0700719// Make sure nothing is live and dirty
buzbeeed3e9302011-09-23 17:34:19 -0700720STATIC void flushAllRegsBody(CompilationUnit* cUnit, RegisterInfo* info,
buzbee67bf8852011-08-17 17:51:35 -0700721 int numRegs)
722{
723 int i;
724 for (i=0; i < numRegs; i++) {
725 if (info[i].live && info[i].dirty) {
726 if (info[i].pair) {
727 oatFlushRegWide(cUnit, info[i].reg, info[i].partner);
728 } else {
729 oatFlushReg(cUnit, info[i].reg);
730 }
731 }
732 }
733}
734
735extern void oatFlushAllRegs(CompilationUnit* cUnit)
736{
737 flushAllRegsBody(cUnit, cUnit->regPool->coreRegs,
738 cUnit->regPool->numCoreRegs);
739 flushAllRegsBody(cUnit, cUnit->regPool->FPRegs,
740 cUnit->regPool->numFPRegs);
741 oatClobberAllRegs(cUnit);
742}
743
744
745//TUNING: rewrite all of this reg stuff. Probably use an attribute table
buzbeeed3e9302011-09-23 17:34:19 -0700746STATIC bool regClassMatches(int regClass, int reg)
buzbee67bf8852011-08-17 17:51:35 -0700747{
748 if (regClass == kAnyReg) {
749 return true;
750 } else if (regClass == kCoreReg) {
751 return !FPREG(reg);
752 } else {
753 return FPREG(reg);
754 }
755}
756
757extern void oatMarkLive(CompilationUnit* cUnit, int reg, int sReg)
758{
buzbee68253262011-10-07 14:02:25 -0700759 RegisterInfo* info = oatGetRegInfo(cUnit, reg);
buzbee67bf8852011-08-17 17:51:35 -0700760 if ((info->reg == reg) && (info->sReg == sReg) && info->live) {
761 return; /* already live */
762 } else if (sReg != INVALID_SREG) {
763 oatClobberSReg(cUnit, sReg);
764 if (info->isTemp) {
765 info->live = true;
766 }
767 } else {
768 /* Can't be live if no associated sReg */
buzbeeed3e9302011-09-23 17:34:19 -0700769 DCHECK(info->isTemp);
buzbee67bf8852011-08-17 17:51:35 -0700770 info->live = false;
771 }
772 info->sReg = sReg;
773}
774
775extern void oatMarkTemp(CompilationUnit* cUnit, int reg)
776{
buzbee68253262011-10-07 14:02:25 -0700777 RegisterInfo* info = oatGetRegInfo(cUnit, reg);
buzbee67bf8852011-08-17 17:51:35 -0700778 info->isTemp = true;
779}
780
buzbee9e0f9b02011-08-24 15:32:46 -0700781extern void oatUnmarkTemp(CompilationUnit* cUnit, int reg)
782{
buzbee68253262011-10-07 14:02:25 -0700783 RegisterInfo* info = oatGetRegInfo(cUnit, reg);
buzbee9e0f9b02011-08-24 15:32:46 -0700784 info->isTemp = false;
785}
786
buzbee67bf8852011-08-17 17:51:35 -0700787extern void oatMarkPair(CompilationUnit* cUnit, int lowReg, int highReg)
788{
buzbee68253262011-10-07 14:02:25 -0700789 RegisterInfo* infoLo = oatGetRegInfo(cUnit, lowReg);
790 RegisterInfo* infoHi = oatGetRegInfo(cUnit, highReg);
buzbee67bf8852011-08-17 17:51:35 -0700791 infoLo->pair = infoHi->pair = true;
792 infoLo->partner = highReg;
793 infoHi->partner = lowReg;
794}
795
796extern void oatMarkClean(CompilationUnit* cUnit, RegLocation loc)
797{
buzbee68253262011-10-07 14:02:25 -0700798 RegisterInfo* info = oatGetRegInfo(cUnit, loc.lowReg);
buzbee67bf8852011-08-17 17:51:35 -0700799 info->dirty = false;
800 if (loc.wide) {
buzbee68253262011-10-07 14:02:25 -0700801 info = oatGetRegInfo(cUnit, loc.highReg);
buzbee67bf8852011-08-17 17:51:35 -0700802 info->dirty = false;
803 }
804}
805
806extern void oatMarkDirty(CompilationUnit* cUnit, RegLocation loc)
807{
808 if (loc.home) {
809 // If already home, can't be dirty
810 return;
811 }
buzbee68253262011-10-07 14:02:25 -0700812 RegisterInfo* info = oatGetRegInfo(cUnit, loc.lowReg);
buzbee67bf8852011-08-17 17:51:35 -0700813 info->dirty = true;
814 if (loc.wide) {
buzbee68253262011-10-07 14:02:25 -0700815 info = oatGetRegInfo(cUnit, loc.highReg);
buzbee67bf8852011-08-17 17:51:35 -0700816 info->dirty = true;
817 }
818}
819
820extern void oatMarkInUse(CompilationUnit* cUnit, int reg)
821{
buzbee68253262011-10-07 14:02:25 -0700822 RegisterInfo* info = oatGetRegInfo(cUnit, reg);
buzbee67bf8852011-08-17 17:51:35 -0700823 info->inUse = true;
824}
825
buzbeeed3e9302011-09-23 17:34:19 -0700826STATIC void copyRegInfo(CompilationUnit* cUnit, int newReg, int oldReg)
buzbee67bf8852011-08-17 17:51:35 -0700827{
buzbee68253262011-10-07 14:02:25 -0700828 RegisterInfo* newInfo = oatGetRegInfo(cUnit, newReg);
829 RegisterInfo* oldInfo = oatGetRegInfo(cUnit, oldReg);
buzbeeec5adf32011-09-11 15:25:43 -0700830 // Target temp status must not change
831 bool isTemp = newInfo->isTemp;
buzbee67bf8852011-08-17 17:51:35 -0700832 *newInfo = *oldInfo;
buzbeeec5adf32011-09-11 15:25:43 -0700833 // Restore target's temp status
834 newInfo->isTemp = isTemp;
buzbee67bf8852011-08-17 17:51:35 -0700835 newInfo->reg = newReg;
836}
837
838/*
839 * Return an updated location record with current in-register status.
840 * If the value lives in live temps, reflect that fact. No code
buzbeeb29e4d12011-09-26 15:05:48 -0700841 * is generated. If the live value is part of an older pair,
buzbee67bf8852011-08-17 17:51:35 -0700842 * clobber both low and high.
843 * TUNING: clobbering both is a bit heavy-handed, but the alternative
844 * is a bit complex when dealing with FP regs. Examine code to see
845 * if it's worthwhile trying to be more clever here.
846 */
847
848extern RegLocation oatUpdateLoc(CompilationUnit* cUnit, RegLocation loc)
849{
buzbeeed3e9302011-09-23 17:34:19 -0700850 DCHECK(!loc.wide);
buzbee6181f792011-09-29 11:14:04 -0700851 DCHECK(oatCheckCorePoolSanity(cUnit));
buzbee67bf8852011-08-17 17:51:35 -0700852 if (loc.location == kLocDalvikFrame) {
853 RegisterInfo* infoLo = allocLive(cUnit, loc.sRegLow, kAnyReg);
854 if (infoLo) {
855 if (infoLo->pair) {
856 oatClobber(cUnit, infoLo->reg);
857 oatClobber(cUnit, infoLo->partner);
buzbee58f92742011-10-01 11:22:17 -0700858 oatFreeTemp(cUnit, infoLo->reg);
buzbee67bf8852011-08-17 17:51:35 -0700859 } else {
860 loc.lowReg = infoLo->reg;
861 loc.location = kLocPhysReg;
862 }
863 }
864 }
865
866 return loc;
867}
868
buzbee6181f792011-09-29 11:14:04 -0700869bool oatCheckCorePoolSanity(CompilationUnit* cUnit)
870{
871 for (static int i = 0; i < cUnit->regPool->numCoreRegs; i++) {
872 if (cUnit->regPool->coreRegs[i].pair) {
873 static int myReg = cUnit->regPool->coreRegs[i].reg;
874 static int mySreg = cUnit->regPool->coreRegs[i].sReg;
875 static int partnerReg = cUnit->regPool->coreRegs[i].partner;
buzbee68253262011-10-07 14:02:25 -0700876 static RegisterInfo* partner = oatGetRegInfo(cUnit, partnerReg);
buzbee6181f792011-09-29 11:14:04 -0700877 DCHECK(partner != NULL);
878 DCHECK(partner->pair);
879 DCHECK_EQ(myReg, partner->partner);
880 static int partnerSreg = partner->sReg;
881 if (mySreg == INVALID_SREG) {
882 DCHECK_EQ(partnerSreg, INVALID_SREG);
883 } else {
884 int diff = mySreg - partnerSreg;
885 DCHECK((diff == -1) || (diff == 1));
886 }
887 }
888 if (!cUnit->regPool->coreRegs[i].live) {
889 DCHECK(cUnit->regPool->coreRegs[i].defStart == NULL);
890 DCHECK(cUnit->regPool->coreRegs[i].defEnd == NULL);
891 }
892 }
893 return true;
894}
895
buzbee67bf8852011-08-17 17:51:35 -0700896/* see comments for updateLoc */
897extern RegLocation oatUpdateLocWide(CompilationUnit* cUnit,
898 RegLocation loc)
899{
buzbeeed3e9302011-09-23 17:34:19 -0700900 DCHECK(loc.wide);
buzbee6181f792011-09-29 11:14:04 -0700901 DCHECK(oatCheckCorePoolSanity(cUnit));
buzbee67bf8852011-08-17 17:51:35 -0700902 if (loc.location == kLocDalvikFrame) {
903 // Are the dalvik regs already live in physical registers?
904 RegisterInfo* infoLo = allocLive(cUnit, loc.sRegLow, kAnyReg);
905 RegisterInfo* infoHi = allocLive(cUnit,
906 oatSRegHi(loc.sRegLow), kAnyReg);
907 bool match = true;
908 match = match && (infoLo != NULL);
909 match = match && (infoHi != NULL);
910 // Are they both core or both FP?
911 match = match && (FPREG(infoLo->reg) == FPREG(infoHi->reg));
912 // If a pair of floating point singles, are they properly aligned?
913 if (match && FPREG(infoLo->reg)) {
914 match &= ((infoLo->reg & 0x1) == 0);
915 match &= ((infoHi->reg - infoLo->reg) == 1);
916 }
917 // If previously used as a pair, it is the same pair?
918 if (match && (infoLo->pair || infoHi->pair)) {
919 match = (infoLo->pair == infoHi->pair);
920 match &= ((infoLo->reg == infoHi->partner) &&
921 (infoHi->reg == infoLo->partner));
922 }
923 if (match) {
924 // Can reuse - update the register usage info
925 loc.lowReg = infoLo->reg;
926 loc.highReg = infoHi->reg;
927 loc.location = kLocPhysReg;
928 oatMarkPair(cUnit, loc.lowReg, loc.highReg);
buzbeeed3e9302011-09-23 17:34:19 -0700929 DCHECK(!FPREG(loc.lowReg) || ((loc.lowReg & 0x1) == 0));
buzbee67bf8852011-08-17 17:51:35 -0700930 return loc;
931 }
buzbee58f92742011-10-01 11:22:17 -0700932 // Can't easily reuse - clobber and free any overlaps
buzbee67bf8852011-08-17 17:51:35 -0700933 if (infoLo) {
934 oatClobber(cUnit, infoLo->reg);
buzbee58f92742011-10-01 11:22:17 -0700935 oatFreeTemp(cUnit, infoLo->reg);
buzbee67bf8852011-08-17 17:51:35 -0700936 if (infoLo->pair)
937 oatClobber(cUnit, infoLo->partner);
938 }
939 if (infoHi) {
940 oatClobber(cUnit, infoHi->reg);
buzbee58f92742011-10-01 11:22:17 -0700941 oatFreeTemp(cUnit, infoHi->reg);
buzbee67bf8852011-08-17 17:51:35 -0700942 if (infoHi->pair)
943 oatClobber(cUnit, infoHi->partner);
944 }
945 }
946 return loc;
947}
948
buzbeeed3e9302011-09-23 17:34:19 -0700949
950/* For use in cases we don't know (or care) width */
951extern RegLocation oatUpdateRawLoc(CompilationUnit* cUnit,
952 RegLocation loc)
953{
954 if (loc.wide)
955 return oatUpdateLocWide(cUnit, loc);
956 else
957 return oatUpdateLoc(cUnit, loc);
958}
959
960STATIC RegLocation evalLocWide(CompilationUnit* cUnit, RegLocation loc,
buzbee67bf8852011-08-17 17:51:35 -0700961 int regClass, bool update)
962{
buzbeeed3e9302011-09-23 17:34:19 -0700963 DCHECK(loc.wide);
buzbee67bf8852011-08-17 17:51:35 -0700964 int newRegs;
965 int lowReg;
966 int highReg;
967
968 loc = oatUpdateLocWide(cUnit, loc);
969
970 /* If already in registers, we can assume proper form. Right reg class? */
971 if (loc.location == kLocPhysReg) {
buzbeeed3e9302011-09-23 17:34:19 -0700972 DCHECK_EQ(FPREG(loc.lowReg), FPREG(loc.highReg));
973 DCHECK(!FPREG(loc.lowReg) || ((loc.lowReg & 0x1) == 0));
buzbee67bf8852011-08-17 17:51:35 -0700974 if (!regClassMatches(regClass, loc.lowReg)) {
975 /* Wrong register class. Reallocate and copy */
976 newRegs = oatAllocTypedTempPair(cUnit, loc.fp, regClass);
977 lowReg = newRegs & 0xff;
978 highReg = (newRegs >> 8) & 0xff;
979 oatRegCopyWide(cUnit, lowReg, highReg, loc.lowReg,
980 loc.highReg);
981 copyRegInfo(cUnit, lowReg, loc.lowReg);
982 copyRegInfo(cUnit, highReg, loc.highReg);
983 oatClobber(cUnit, loc.lowReg);
984 oatClobber(cUnit, loc.highReg);
985 loc.lowReg = lowReg;
986 loc.highReg = highReg;
987 oatMarkPair(cUnit, loc.lowReg, loc.highReg);
buzbeeed3e9302011-09-23 17:34:19 -0700988 DCHECK(!FPREG(loc.lowReg) || ((loc.lowReg & 0x1) == 0));
buzbee67bf8852011-08-17 17:51:35 -0700989 }
990 return loc;
991 }
992
buzbeeed3e9302011-09-23 17:34:19 -0700993 DCHECK_NE(loc.sRegLow, INVALID_SREG);
994 DCHECK_NE(oatSRegHi(loc.sRegLow), INVALID_SREG);
buzbee67bf8852011-08-17 17:51:35 -0700995
996 newRegs = oatAllocTypedTempPair(cUnit, loc.fp, regClass);
997 loc.lowReg = newRegs & 0xff;
998 loc.highReg = (newRegs >> 8) & 0xff;
999
1000 oatMarkPair(cUnit, loc.lowReg, loc.highReg);
1001 if (update) {
1002 loc.location = kLocPhysReg;
1003 oatMarkLive(cUnit, loc.lowReg, loc.sRegLow);
1004 oatMarkLive(cUnit, loc.highReg, oatSRegHi(loc.sRegLow));
1005 }
buzbeeed3e9302011-09-23 17:34:19 -07001006 DCHECK(!FPREG(loc.lowReg) || ((loc.lowReg & 0x1) == 0));
buzbee67bf8852011-08-17 17:51:35 -07001007 return loc;
1008}
1009
1010extern RegLocation oatEvalLoc(CompilationUnit* cUnit, RegLocation loc,
1011 int regClass, bool update)
1012{
1013 int newReg;
1014
1015 if (loc.wide)
1016 return evalLocWide(cUnit, loc, regClass, update);
1017
1018 loc = oatUpdateLoc(cUnit, loc);
1019
1020 if (loc.location == kLocPhysReg) {
1021 if (!regClassMatches(regClass, loc.lowReg)) {
1022 /* Wrong register class. Realloc, copy and transfer ownership */
1023 newReg = oatAllocTypedTemp(cUnit, loc.fp, regClass);
1024 oatRegCopy(cUnit, newReg, loc.lowReg);
1025 copyRegInfo(cUnit, newReg, loc.lowReg);
1026 oatClobber(cUnit, loc.lowReg);
1027 loc.lowReg = newReg;
1028 }
1029 return loc;
1030 }
1031
buzbeeed3e9302011-09-23 17:34:19 -07001032 DCHECK_NE(loc.sRegLow, INVALID_SREG);
buzbee67bf8852011-08-17 17:51:35 -07001033
1034 newReg = oatAllocTypedTemp(cUnit, loc.fp, regClass);
1035 loc.lowReg = newReg;
1036
1037 if (update) {
1038 loc.location = kLocPhysReg;
1039 oatMarkLive(cUnit, loc.lowReg, loc.sRegLow);
1040 }
1041 return loc;
1042}
1043
1044extern RegLocation oatGetDest(CompilationUnit* cUnit, MIR* mir, int num)
1045{
buzbeee9a72f62011-09-04 17:59:07 -07001046 RegLocation res = cUnit->regLocation[mir->ssaRep->defs[num]];
buzbeeed3e9302011-09-23 17:34:19 -07001047 DCHECK(!res.wide);
buzbeee9a72f62011-09-04 17:59:07 -07001048 return res;
buzbee67bf8852011-08-17 17:51:35 -07001049}
1050extern RegLocation oatGetSrc(CompilationUnit* cUnit, MIR* mir, int num)
1051{
buzbeee9a72f62011-09-04 17:59:07 -07001052 RegLocation res = cUnit->regLocation[mir->ssaRep->uses[num]];
buzbeeed3e9302011-09-23 17:34:19 -07001053 DCHECK(!res.wide);
buzbeee9a72f62011-09-04 17:59:07 -07001054 return res;
1055}
1056extern RegLocation oatGetRawSrc(CompilationUnit* cUnit, MIR* mir, int num)
1057{
1058 RegLocation res = cUnit->regLocation[mir->ssaRep->uses[num]];
1059 return res;
buzbee67bf8852011-08-17 17:51:35 -07001060}
1061extern RegLocation oatGetDestWide(CompilationUnit* cUnit, MIR* mir,
1062 int low, int high)
1063{
buzbeee9a72f62011-09-04 17:59:07 -07001064 RegLocation res = cUnit->regLocation[mir->ssaRep->defs[low]];
buzbeeed3e9302011-09-23 17:34:19 -07001065 DCHECK(res.wide);
buzbeee9a72f62011-09-04 17:59:07 -07001066 return res;
buzbee67bf8852011-08-17 17:51:35 -07001067}
1068
1069extern RegLocation oatGetSrcWide(CompilationUnit* cUnit, MIR* mir,
1070 int low, int high)
1071{
buzbeee9a72f62011-09-04 17:59:07 -07001072 RegLocation res = cUnit->regLocation[mir->ssaRep->uses[low]];
buzbeeed3e9302011-09-23 17:34:19 -07001073 DCHECK(res.wide);
buzbeee9a72f62011-09-04 17:59:07 -07001074 return res;
buzbee67bf8852011-08-17 17:51:35 -07001075}