blob: 05fe7faa5e2078fc8786a5b1848113892cdb2f1d [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/*
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080018 * This file contains Arm-specific register allocation support.
buzbee67bf8852011-08-17 17:51:35 -070019 */
20
21#include "../../CompilerUtility.h"
22#include "../../CompilerIR.h"
23#include "../..//Dataflow.h"
24#include "ArmLIR.h"
25#include "Codegen.h"
26#include "../Ralloc.h"
27
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080028namespace art {
29
buzbee67bf8852011-08-17 17:51:35 -070030/*
buzbeee3acd072012-02-25 17:03:10 -080031 * TUNING: is leaf? Can't just use "hasInvoke" to determine as some
32 * instructions might call out to C/assembly helper functions. Until
33 * machinery is in place, always spill lr.
buzbee67bf8852011-08-17 17:51:35 -070034 */
35
buzbeee3acd072012-02-25 17:03:10 -080036void oatAdjustSpillMask(CompilationUnit* cUnit)
buzbee67bf8852011-08-17 17:51:35 -070037{
buzbeef0504cd2012-11-13 16:31:10 -080038 cUnit->coreSpillMask |= (1 << rARM_LR);
Bill Buzbeea114add2012-05-03 15:00:40 -070039 cUnit->numCoreSpills++;
buzbee67bf8852011-08-17 17:51:35 -070040}
41
42/*
buzbeee3acd072012-02-25 17:03:10 -080043 * Mark a callee-save fp register as promoted. Note that
44 * vpush/vpop uses contiguous register lists so we must
45 * include any holes in the mask. Associate holes with
46 * Dalvik register INVALID_VREG (0xFFFFU).
buzbee67bf8852011-08-17 17:51:35 -070047 */
buzbee9c044ce2012-03-18 13:24:07 -070048void oatMarkPreservedSingle(CompilationUnit* cUnit, int vReg, int reg)
buzbee67bf8852011-08-17 17:51:35 -070049{
buzbeef0504cd2012-11-13 16:31:10 -080050 DCHECK_GE(reg, ARM_FP_REG_MASK + ARM_FP_CALLEE_SAVE_BASE);
51 reg = (reg & ARM_FP_REG_MASK) - ARM_FP_CALLEE_SAVE_BASE;
Bill Buzbeea114add2012-05-03 15:00:40 -070052 // Ensure fpVmapTable is large enough
53 int tableSize = cUnit->fpVmapTable.size();
54 for (int i = tableSize; i < (reg + 1); i++) {
55 cUnit->fpVmapTable.push_back(INVALID_VREG);
56 }
57 // Add the current mapping
58 cUnit->fpVmapTable[reg] = vReg;
59 // Size of fpVmapTable is high-water mark, use to set mask
60 cUnit->numFPSpills = cUnit->fpVmapTable.size();
buzbeef0504cd2012-11-13 16:31:10 -080061 cUnit->fpSpillMask = ((1 << cUnit->numFPSpills) - 1) << ARM_FP_CALLEE_SAVE_BASE;
buzbeee3acd072012-02-25 17:03:10 -080062}
buzbee67bf8852011-08-17 17:51:35 -070063
buzbeee3acd072012-02-25 17:03:10 -080064void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2)
65{
Bill Buzbeea114add2012-05-03 15:00:40 -070066 RegisterInfo* info1 = oatGetRegInfo(cUnit, reg1);
67 RegisterInfo* info2 = oatGetRegInfo(cUnit, reg2);
68 DCHECK(info1 && info2 && info1->pair && info2->pair &&
69 (info1->partner == info2->reg) &&
70 (info2->partner == info1->reg));
71 if ((info1->live && info1->dirty) || (info2->live && info2->dirty)) {
72 if (!(info1->isTemp && info2->isTemp)) {
73 /* Should not happen. If it does, there's a problem in evalLoc */
74 LOG(FATAL) << "Long half-temp, half-promoted";
buzbee67bf8852011-08-17 17:51:35 -070075 }
Bill Buzbeea114add2012-05-03 15:00:40 -070076
77 info1->dirty = false;
78 info2->dirty = false;
79 if (SRegToVReg(cUnit, info2->sReg) <
80 SRegToVReg(cUnit, info1->sReg))
81 info1 = info2;
82 int vReg = SRegToVReg(cUnit, info1->sReg);
buzbeef0504cd2012-11-13 16:31:10 -080083 oatFlushRegWideImpl(cUnit, rARM_SP, oatVRegOffset(cUnit, vReg),
Bill Buzbeea114add2012-05-03 15:00:40 -070084 info1->reg, info1->partner);
85 }
buzbee67bf8852011-08-17 17:51:35 -070086}
87
buzbeee3acd072012-02-25 17:03:10 -080088void oatFlushReg(CompilationUnit* cUnit, int reg)
buzbee67bf8852011-08-17 17:51:35 -070089{
Bill Buzbeea114add2012-05-03 15:00:40 -070090 RegisterInfo* info = oatGetRegInfo(cUnit, reg);
91 if (info->live && info->dirty) {
92 info->dirty = false;
93 int vReg = SRegToVReg(cUnit, info->sReg);
buzbeef0504cd2012-11-13 16:31:10 -080094 oatFlushRegImpl(cUnit, rARM_SP, oatVRegOffset(cUnit, vReg), reg, kWord);
Bill Buzbeea114add2012-05-03 15:00:40 -070095 }
buzbee67bf8852011-08-17 17:51:35 -070096}
97
buzbeee3acd072012-02-25 17:03:10 -080098/* Give access to the target-dependent FP register encoding to common code */
99bool oatIsFpReg(int reg) {
buzbeef0504cd2012-11-13 16:31:10 -0800100 return ARM_FPREG(reg);
buzbee67bc2362011-10-11 18:08:40 -0700101}
102
buzbeee3acd072012-02-25 17:03:10 -0800103uint32_t oatFpRegMask() {
buzbeef0504cd2012-11-13 16:31:10 -0800104 return ARM_FP_REG_MASK;
buzbeec41e5b52011-09-23 12:46:19 -0700105}
buzbee67bf8852011-08-17 17:51:35 -0700106
107/* Clobber all regs that might be used by an external C call */
buzbeee3acd072012-02-25 17:03:10 -0800108void oatClobberCalleeSave(CompilationUnit *cUnit)
buzbee67bf8852011-08-17 17:51:35 -0700109{
Bill Buzbeea114add2012-05-03 15:00:40 -0700110 oatClobber(cUnit, r0);
111 oatClobber(cUnit, r1);
112 oatClobber(cUnit, r2);
113 oatClobber(cUnit, r3);
114 oatClobber(cUnit, r12);
115 oatClobber(cUnit, r14lr);
116 oatClobber(cUnit, fr0);
117 oatClobber(cUnit, fr1);
118 oatClobber(cUnit, fr2);
119 oatClobber(cUnit, fr3);
120 oatClobber(cUnit, fr4);
121 oatClobber(cUnit, fr5);
122 oatClobber(cUnit, fr6);
123 oatClobber(cUnit, fr7);
124 oatClobber(cUnit, fr8);
125 oatClobber(cUnit, fr9);
126 oatClobber(cUnit, fr10);
127 oatClobber(cUnit, fr11);
128 oatClobber(cUnit, fr12);
129 oatClobber(cUnit, fr13);
130 oatClobber(cUnit, fr14);
131 oatClobber(cUnit, fr15);
buzbee67bf8852011-08-17 17:51:35 -0700132}
133
buzbee67bf8852011-08-17 17:51:35 -0700134extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit)
135{
buzbeef0504cd2012-11-13 16:31:10 -0800136 RegLocation res = locCReturnWide();
Bill Buzbeea114add2012-05-03 15:00:40 -0700137 res.lowReg = r2;
138 res.highReg = r3;
139 oatClobber(cUnit, r2);
140 oatClobber(cUnit, r3);
141 oatMarkInUse(cUnit, r2);
142 oatMarkInUse(cUnit, r3);
143 oatMarkPair(cUnit, res.lowReg, res.highReg);
144 return res;
buzbee67bf8852011-08-17 17:51:35 -0700145}
146
buzbee67bf8852011-08-17 17:51:35 -0700147extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit)
148{
buzbeef0504cd2012-11-13 16:31:10 -0800149 RegLocation res = locCReturn();
Bill Buzbeea114add2012-05-03 15:00:40 -0700150 res.lowReg = r1;
151 oatClobber(cUnit, r1);
152 oatMarkInUse(cUnit, r1);
153 return res;
buzbee67bf8852011-08-17 17:51:35 -0700154}
buzbee68253262011-10-07 14:02:25 -0700155
156extern RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg)
157{
buzbeef0504cd2012-11-13 16:31:10 -0800158 return ARM_FPREG(reg) ? &cUnit->regPool->FPRegs[reg & ARM_FP_REG_MASK]
Bill Buzbeea114add2012-05-03 15:00:40 -0700159 : &cUnit->regPool->coreRegs[reg];
buzbee68253262011-10-07 14:02:25 -0700160}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800161
buzbeee3acd072012-02-25 17:03:10 -0800162/* To be used when explicitly managing register use */
163extern void oatLockCallTemps(CompilationUnit* cUnit)
164{
Bill Buzbeea114add2012-05-03 15:00:40 -0700165 oatLockTemp(cUnit, r0);
166 oatLockTemp(cUnit, r1);
167 oatLockTemp(cUnit, r2);
168 oatLockTemp(cUnit, r3);
buzbeee3acd072012-02-25 17:03:10 -0800169}
170
171/* To be used when explicitly managing register use */
172extern void oatFreeCallTemps(CompilationUnit* cUnit)
173{
Bill Buzbeea114add2012-05-03 15:00:40 -0700174 oatFreeTemp(cUnit, r0);
175 oatFreeTemp(cUnit, r1);
176 oatFreeTemp(cUnit, r2);
177 oatFreeTemp(cUnit, r3);
buzbeee3acd072012-02-25 17:03:10 -0800178}
179
180/* Convert an instruction to a NOP */
buzbee31a4a6f2012-02-28 15:36:15 -0800181void oatNopLIR( LIR* lir)
buzbeee3acd072012-02-25 17:03:10 -0800182{
Bill Buzbeea114add2012-05-03 15:00:40 -0700183 ((LIR*)lir)->flags.isNop = true;
buzbeee3acd072012-02-25 17:03:10 -0800184}
185
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800186} // namespace art