blob: bd9f97eb6fdfbc0ac99f528accd6b7c012a0000f [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/*
buzbee31a4a6f2012-02-28 15:36:15 -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.
34 */
35
36void oatAdjustSpillMask(CompilationUnit* cUnit)
37{
Bill Buzbeea114add2012-05-03 15:00:40 -070038 cUnit->coreSpillMask |= (1 << r_RA);
39 cUnit->numCoreSpills++;
buzbee31a4a6f2012-02-28 15:36:15 -080040}
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).
47 */
buzbee31a4a6f2012-02-28 15:36:15 -080048void oatMarkPreservedSingle(CompilationUnit* cUnit, int sReg, int reg)
buzbeee3acd072012-02-25 17:03:10 -080049{
Bill Buzbeea114add2012-05-03 15:00:40 -070050 LOG(FATAL) << "No support yet for promoted FP regs";
buzbeee3acd072012-02-25 17:03:10 -080051}
52
53void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2)
54{
Bill Buzbeea114add2012-05-03 15:00:40 -070055 RegisterInfo* info1 = oatGetRegInfo(cUnit, reg1);
56 RegisterInfo* info2 = oatGetRegInfo(cUnit, reg2);
57 DCHECK(info1 && info2 && info1->pair && info2->pair &&
58 (info1->partner == info2->reg) &&
59 (info2->partner == info1->reg));
60 if ((info1->live && info1->dirty) || (info2->live && info2->dirty)) {
61 if (!(info1->isTemp && info2->isTemp)) {
62 /* Should not happen. If it does, there's a problem in evalLoc */
63 LOG(FATAL) << "Long half-temp, half-promoted";
buzbeee3acd072012-02-25 17:03:10 -080064 }
Bill Buzbeea114add2012-05-03 15:00:40 -070065
66 info1->dirty = false;
67 info2->dirty = false;
68 if (SRegToVReg(cUnit, info2->sReg) < SRegToVReg(cUnit, info1->sReg))
69 info1 = info2;
70 int vReg = SRegToVReg(cUnit, info1->sReg);
71 oatFlushRegWideImpl(cUnit, rSP, oatVRegOffset(cUnit, vReg), info1->reg,
72 info1->partner);
73 }
buzbeee3acd072012-02-25 17:03:10 -080074}
75
76void oatFlushReg(CompilationUnit* cUnit, int reg)
77{
Bill Buzbeea114add2012-05-03 15:00:40 -070078 RegisterInfo* info = oatGetRegInfo(cUnit, reg);
79 if (info->live && info->dirty) {
80 info->dirty = false;
81 int vReg = SRegToVReg(cUnit, info->sReg);
82 oatFlushRegImpl(cUnit, rSP, oatVRegOffset(cUnit, vReg), reg, kWord);
83 }
buzbeee3acd072012-02-25 17:03:10 -080084}
85
86/* Give access to the target-dependent FP register encoding to common code */
87bool oatIsFpReg(int reg) {
Bill Buzbeea114add2012-05-03 15:00:40 -070088 return FPREG(reg);
buzbeee3acd072012-02-25 17:03:10 -080089}
90
91uint32_t oatFpRegMask() {
Bill Buzbeea114add2012-05-03 15:00:40 -070092 return FP_REG_MASK;
buzbeee3acd072012-02-25 17:03:10 -080093}
94
95/* Clobber all regs that might be used by an external C call */
96extern void oatClobberCalleeSave(CompilationUnit *cUnit)
97{
Bill Buzbeea114add2012-05-03 15:00:40 -070098 oatClobber(cUnit, r_ZERO);
99 oatClobber(cUnit, r_AT);
100 oatClobber(cUnit, r_V0);
101 oatClobber(cUnit, r_V1);
102 oatClobber(cUnit, r_A0);
103 oatClobber(cUnit, r_A1);
104 oatClobber(cUnit, r_A2);
105 oatClobber(cUnit, r_A3);
106 oatClobber(cUnit, r_T0);
107 oatClobber(cUnit, r_T1);
108 oatClobber(cUnit, r_T2);
109 oatClobber(cUnit, r_T3);
110 oatClobber(cUnit, r_T4);
111 oatClobber(cUnit, r_T5);
112 oatClobber(cUnit, r_T6);
113 oatClobber(cUnit, r_T7);
114 oatClobber(cUnit, r_T8);
115 oatClobber(cUnit, r_T9);
116 oatClobber(cUnit, r_K0);
117 oatClobber(cUnit, r_K1);
118 oatClobber(cUnit, r_GP);
119 oatClobber(cUnit, r_FP);
120 oatClobber(cUnit, r_RA);
121 oatClobber(cUnit, r_F0);
122 oatClobber(cUnit, r_F1);
123 oatClobber(cUnit, r_F2);
124 oatClobber(cUnit, r_F3);
125 oatClobber(cUnit, r_F4);
126 oatClobber(cUnit, r_F5);
127 oatClobber(cUnit, r_F6);
128 oatClobber(cUnit, r_F7);
129 oatClobber(cUnit, r_F8);
130 oatClobber(cUnit, r_F9);
131 oatClobber(cUnit, r_F10);
132 oatClobber(cUnit, r_F11);
133 oatClobber(cUnit, r_F12);
134 oatClobber(cUnit, r_F13);
135 oatClobber(cUnit, r_F14);
136 oatClobber(cUnit, r_F15);
buzbeee3acd072012-02-25 17:03:10 -0800137}
138
buzbeee3acd072012-02-25 17:03:10 -0800139extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit)
140{
jeffhao4f8f04a2012-10-02 18:10:35 -0700141 UNIMPLEMENTED(FATAL) << "No oatGetReturnWideAlt for MIPS";
142 RegLocation res = LOC_C_RETURN_WIDE;
Bill Buzbeea114add2012-05-03 15:00:40 -0700143 return res;
buzbeee3acd072012-02-25 17:03:10 -0800144}
145
Elliott Hughese7825db2012-03-09 15:46:57 -0800146extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit)
147{
jeffhao4f8f04a2012-10-02 18:10:35 -0700148 UNIMPLEMENTED(FATAL) << "No oatGetReturnAlt for MIPS";
149 RegLocation res = LOC_C_RETURN;
Bill Buzbeea114add2012-05-03 15:00:40 -0700150 return res;
Elliott Hughese7825db2012-03-09 15:46:57 -0800151}
152
buzbeee3acd072012-02-25 17:03:10 -0800153extern RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg)
154{
Bill Buzbeea114add2012-05-03 15:00:40 -0700155 return FPREG(reg) ? &cUnit->regPool->FPRegs[reg & FP_REG_MASK]
156 : &cUnit->regPool->coreRegs[reg];
buzbeee3acd072012-02-25 17:03:10 -0800157}
158
159/* To be used when explicitly managing register use */
160extern void oatLockCallTemps(CompilationUnit* cUnit)
161{
Bill Buzbeea114add2012-05-03 15:00:40 -0700162 oatLockTemp(cUnit, rARG0);
163 oatLockTemp(cUnit, rARG1);
164 oatLockTemp(cUnit, rARG2);
165 oatLockTemp(cUnit, rARG3);
buzbeee3acd072012-02-25 17:03:10 -0800166}
167
168/* To be used when explicitly managing register use */
169extern void oatFreeCallTemps(CompilationUnit* cUnit)
170{
Bill Buzbeea114add2012-05-03 15:00:40 -0700171 oatFreeTemp(cUnit, rARG0);
172 oatFreeTemp(cUnit, rARG1);
173 oatFreeTemp(cUnit, rARG2);
174 oatFreeTemp(cUnit, rARG3);
buzbeee3acd072012-02-25 17:03:10 -0800175}
176
buzbee31a4a6f2012-02-28 15:36:15 -0800177/* Convert an instruction to a NOP */
buzbee5de34942012-03-01 14:51:57 -0800178void oatNopLIR( LIR* lir)
buzbee31a4a6f2012-02-28 15:36:15 -0800179{
Bill Buzbeea114add2012-05-03 15:00:40 -0700180 ((LIR*)lir)->flags.isNop = true;
buzbee31a4a6f2012-02-28 15:36:15 -0800181}
182
buzbeee3acd072012-02-25 17:03:10 -0800183} // namespace art