blob: 54e5742837424956f5d82d6170efa4dc374e9c6f [file] [log] [blame]
Brian Carlstrom7940e442013-07-12 13:46:57 -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
Andreas Gampe0b9203e2015-01-22 20:39:27 -080017#include "mir_to_lir-inl.h"
18
Brian Carlstrom7940e442013-07-12 13:46:57 -070019#include "dex/compiler_ir.h"
Andreas Gampe0b9203e2015-01-22 20:39:27 -080020#include "dex/mir_graph.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070021#include "invoke_type.h"
22
23namespace art {
24
25/* This file contains target-independent codegen and support. */
26
27/*
28 * Load an immediate value into a fixed or temp register. Target
29 * register is clobbered, and marked in_use.
30 */
buzbee2700f7e2014-03-07 09:46:20 -080031LIR* Mir2Lir::LoadConstant(RegStorage r_dest, int value) {
Brian Carlstrom7940e442013-07-12 13:46:57 -070032 if (IsTemp(r_dest)) {
33 Clobber(r_dest);
34 MarkInUse(r_dest);
35 }
36 return LoadConstantNoClobber(r_dest, value);
37}
38
39/*
Brian Carlstrom7940e442013-07-12 13:46:57 -070040 * Load a Dalvik register into a physical register. Take care when
41 * using this routine, as it doesn't perform any bookkeeping regarding
42 * register liveness. That is the responsibility of the caller.
43 */
buzbee2700f7e2014-03-07 09:46:20 -080044void Mir2Lir::LoadValueDirect(RegLocation rl_src, RegStorage r_dest) {
Brian Carlstrom7940e442013-07-12 13:46:57 -070045 rl_src = UpdateLoc(rl_src);
46 if (rl_src.location == kLocPhysReg) {
buzbee2700f7e2014-03-07 09:46:20 -080047 OpRegCopy(r_dest, rl_src.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -070048 } else if (IsInexpensiveConstant(rl_src)) {
buzbee695d13a2014-04-19 13:32:20 -070049 // On 64-bit targets, will sign extend. Make sure constant reference is always NULL.
50 DCHECK(!rl_src.ref || (mir_graph_->ConstantValue(rl_src) == 0));
Brian Carlstrom7940e442013-07-12 13:46:57 -070051 LoadConstantNoClobber(r_dest, mir_graph_->ConstantValue(rl_src));
52 } else {
53 DCHECK((rl_src.location == kLocDalvikFrame) ||
54 (rl_src.location == kLocCompilerTemp));
Vladimir Marko8dea81c2014-06-06 14:50:36 +010055 ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
buzbee695d13a2014-04-19 13:32:20 -070056 if (rl_src.ref) {
Chao-ying Fua77ee512014-07-01 17:43:41 -070057 LoadRefDisp(TargetPtrReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest, kNotVolatile);
buzbee695d13a2014-04-19 13:32:20 -070058 } else {
Chao-ying Fua77ee512014-07-01 17:43:41 -070059 Load32Disp(TargetPtrReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest);
buzbee695d13a2014-04-19 13:32:20 -070060 }
Brian Carlstrom7940e442013-07-12 13:46:57 -070061 }
62}
63
64/*
65 * Similar to LoadValueDirect, but clobbers and allocates the target
66 * register. Should be used when loading to a fixed register (for example,
67 * loading arguments to an out of line call.
68 */
buzbee2700f7e2014-03-07 09:46:20 -080069void Mir2Lir::LoadValueDirectFixed(RegLocation rl_src, RegStorage r_dest) {
Brian Carlstrom7940e442013-07-12 13:46:57 -070070 Clobber(r_dest);
71 MarkInUse(r_dest);
72 LoadValueDirect(rl_src, r_dest);
73}
74
75/*
76 * Load a Dalvik register pair into a physical register[s]. Take care when
77 * using this routine, as it doesn't perform any bookkeeping regarding
78 * register liveness. That is the responsibility of the caller.
79 */
buzbee2700f7e2014-03-07 09:46:20 -080080void Mir2Lir::LoadValueDirectWide(RegLocation rl_src, RegStorage r_dest) {
Brian Carlstrom7940e442013-07-12 13:46:57 -070081 rl_src = UpdateLocWide(rl_src);
82 if (rl_src.location == kLocPhysReg) {
buzbee2700f7e2014-03-07 09:46:20 -080083 OpRegCopyWide(r_dest, rl_src.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -070084 } else if (IsInexpensiveConstant(rl_src)) {
buzbee2700f7e2014-03-07 09:46:20 -080085 LoadConstantWide(r_dest, mir_graph_->ConstantValueWide(rl_src));
Brian Carlstrom7940e442013-07-12 13:46:57 -070086 } else {
87 DCHECK((rl_src.location == kLocDalvikFrame) ||
88 (rl_src.location == kLocCompilerTemp));
Vladimir Marko8dea81c2014-06-06 14:50:36 +010089 ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
Chao-ying Fua77ee512014-07-01 17:43:41 -070090 LoadBaseDisp(TargetPtrReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest, k64, kNotVolatile);
Brian Carlstrom7940e442013-07-12 13:46:57 -070091 }
92}
93
94/*
95 * Similar to LoadValueDirect, but clobbers and allocates the target
96 * registers. Should be used when loading to a fixed registers (for example,
97 * loading arguments to an out of line call.
98 */
buzbee2700f7e2014-03-07 09:46:20 -080099void Mir2Lir::LoadValueDirectWideFixed(RegLocation rl_src, RegStorage r_dest) {
100 Clobber(r_dest);
101 MarkInUse(r_dest);
102 LoadValueDirectWide(rl_src, r_dest);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700103}
104
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700105RegLocation Mir2Lir::LoadValue(RegLocation rl_src, RegisterClass op_kind) {
buzbeea0cd2d72014-06-01 09:33:49 -0700106 DCHECK(!rl_src.ref || op_kind == kRefReg);
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100107 rl_src = UpdateLoc(rl_src);
108 if (rl_src.location == kLocPhysReg) {
109 if (!RegClassMatches(op_kind, rl_src.reg)) {
110 // Wrong register class, realloc, copy and transfer ownership.
111 RegStorage new_reg = AllocTypedTemp(rl_src.fp, op_kind);
112 OpRegCopy(new_reg, rl_src.reg);
Serguei Katkov02c637e2014-10-29 13:48:02 +0600113 // Clobber the old regs and free it.
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100114 Clobber(rl_src.reg);
Serguei Katkov02c637e2014-10-29 13:48:02 +0600115 FreeTemp(rl_src.reg);
buzbee082833c2014-05-17 23:16:26 -0700116 // ...and mark the new one live.
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100117 rl_src.reg = new_reg;
buzbee082833c2014-05-17 23:16:26 -0700118 MarkLive(rl_src);
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100119 }
120 return rl_src;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700121 }
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100122
123 DCHECK_NE(rl_src.s_reg_low, INVALID_SREG);
124 rl_src.reg = AllocTypedTemp(rl_src.fp, op_kind);
125 LoadValueDirect(rl_src, rl_src.reg);
126 rl_src.location = kLocPhysReg;
127 MarkLive(rl_src);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700128 return rl_src;
129}
130
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700131void Mir2Lir::StoreValue(RegLocation rl_dest, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700132 /*
133 * Sanity checking - should never try to store to the same
134 * ssa name during the compilation of a single instruction
135 * without an intervening ClobberSReg().
136 */
137 if (kIsDebugBuild) {
138 DCHECK((live_sreg_ == INVALID_SREG) ||
139 (rl_dest.s_reg_low != live_sreg_));
140 live_sreg_ = rl_dest.s_reg_low;
141 }
142 LIR* def_start;
143 LIR* def_end;
144 DCHECK(!rl_dest.wide);
145 DCHECK(!rl_src.wide);
146 rl_src = UpdateLoc(rl_src);
147 rl_dest = UpdateLoc(rl_dest);
148 if (rl_src.location == kLocPhysReg) {
buzbee2700f7e2014-03-07 09:46:20 -0800149 if (IsLive(rl_src.reg) ||
150 IsPromoted(rl_src.reg) ||
Brian Carlstrom7940e442013-07-12 13:46:57 -0700151 (rl_dest.location == kLocPhysReg)) {
152 // Src is live/promoted or Dest has assigned reg.
Andreas Gampe4b537a82014-06-30 22:24:53 -0700153 rl_dest = EvalLoc(rl_dest, rl_dest.ref || rl_src.ref ? kRefReg : kAnyReg, false);
buzbee2700f7e2014-03-07 09:46:20 -0800154 OpRegCopy(rl_dest.reg, rl_src.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700155 } else {
156 // Just re-assign the registers. Dest gets Src's regs
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000157 rl_dest.reg = rl_src.reg;
buzbee2700f7e2014-03-07 09:46:20 -0800158 Clobber(rl_src.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700159 }
160 } else {
161 // Load Src either into promoted Dest or temps allocated for Dest
Andreas Gampe4b537a82014-06-30 22:24:53 -0700162 rl_dest = EvalLoc(rl_dest, rl_dest.ref ? kRefReg : kAnyReg, false);
buzbee2700f7e2014-03-07 09:46:20 -0800163 LoadValueDirect(rl_src, rl_dest.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700164 }
165
166 // Dest is now live and dirty (until/if we flush it to home location)
buzbee091cc402014-03-31 10:14:40 -0700167 MarkLive(rl_dest);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700168 MarkDirty(rl_dest);
169
170
171 ResetDefLoc(rl_dest);
buzbee091cc402014-03-31 10:14:40 -0700172 if (IsDirty(rl_dest.reg) && LiveOut(rl_dest.s_reg_low)) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700173 def_start = last_lir_insn_;
Ian Rogerse98297b2014-06-22 07:47:53 +0000174 ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
Andreas Gampe2073e752014-06-23 15:39:00 +0000175 if (rl_dest.ref) {
Chao-ying Fua77ee512014-07-01 17:43:41 -0700176 StoreRefDisp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg, kNotVolatile);
Andreas Gampe2073e752014-06-23 15:39:00 +0000177 } else {
Chao-ying Fua77ee512014-07-01 17:43:41 -0700178 Store32Disp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg);
Andreas Gampe2073e752014-06-23 15:39:00 +0000179 }
Brian Carlstrom7940e442013-07-12 13:46:57 -0700180 MarkClean(rl_dest);
181 def_end = last_lir_insn_;
182 if (!rl_dest.ref) {
183 // Exclude references from store elimination
184 MarkDef(rl_dest, def_start, def_end);
185 }
186 }
187}
188
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700189RegLocation Mir2Lir::LoadValueWide(RegLocation rl_src, RegisterClass op_kind) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700190 DCHECK(rl_src.wide);
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100191 rl_src = UpdateLocWide(rl_src);
192 if (rl_src.location == kLocPhysReg) {
193 if (!RegClassMatches(op_kind, rl_src.reg)) {
194 // Wrong register class, realloc, copy and transfer ownership.
195 RegStorage new_regs = AllocTypedTempWide(rl_src.fp, op_kind);
196 OpRegCopyWide(new_regs, rl_src.reg);
Serguei Katkov02c637e2014-10-29 13:48:02 +0600197 // Clobber the old regs and free it.
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100198 Clobber(rl_src.reg);
Serguei Katkov02c637e2014-10-29 13:48:02 +0600199 FreeTemp(rl_src.reg);
buzbee082833c2014-05-17 23:16:26 -0700200 // ...and mark the new ones live.
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100201 rl_src.reg = new_regs;
buzbee082833c2014-05-17 23:16:26 -0700202 MarkLive(rl_src);
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100203 }
204 return rl_src;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700205 }
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100206
207 DCHECK_NE(rl_src.s_reg_low, INVALID_SREG);
208 DCHECK_NE(GetSRegHi(rl_src.s_reg_low), INVALID_SREG);
209 rl_src.reg = AllocTypedTempWide(rl_src.fp, op_kind);
210 LoadValueDirectWide(rl_src, rl_src.reg);
211 rl_src.location = kLocPhysReg;
212 MarkLive(rl_src);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700213 return rl_src;
214}
215
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700216void Mir2Lir::StoreValueWide(RegLocation rl_dest, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700217 /*
218 * Sanity checking - should never try to store to the same
219 * ssa name during the compilation of a single instruction
220 * without an intervening ClobberSReg().
221 */
222 if (kIsDebugBuild) {
223 DCHECK((live_sreg_ == INVALID_SREG) ||
224 (rl_dest.s_reg_low != live_sreg_));
225 live_sreg_ = rl_dest.s_reg_low;
226 }
227 LIR* def_start;
228 LIR* def_end;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700229 DCHECK(rl_dest.wide);
230 DCHECK(rl_src.wide);
Alexei Zavjalovc17ebe82014-02-26 10:38:23 +0700231 rl_src = UpdateLocWide(rl_src);
232 rl_dest = UpdateLocWide(rl_dest);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700233 if (rl_src.location == kLocPhysReg) {
buzbee2700f7e2014-03-07 09:46:20 -0800234 if (IsLive(rl_src.reg) ||
235 IsPromoted(rl_src.reg) ||
Brian Carlstrom7940e442013-07-12 13:46:57 -0700236 (rl_dest.location == kLocPhysReg)) {
buzbee30adc732014-05-09 15:10:18 -0700237 /*
238 * If src reg[s] are tied to the original Dalvik vreg via liveness or promotion, we
239 * can't repurpose them. Similarly, if the dest reg[s] are tied to Dalvik vregs via
240 * promotion, we can't just re-assign. In these cases, we have to copy.
241 */
Brian Carlstrom7940e442013-07-12 13:46:57 -0700242 rl_dest = EvalLoc(rl_dest, kAnyReg, false);
buzbee2700f7e2014-03-07 09:46:20 -0800243 OpRegCopyWide(rl_dest.reg, rl_src.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700244 } else {
245 // Just re-assign the registers. Dest gets Src's regs
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000246 rl_dest.reg = rl_src.reg;
buzbee2700f7e2014-03-07 09:46:20 -0800247 Clobber(rl_src.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700248 }
249 } else {
250 // Load Src either into promoted Dest or temps allocated for Dest
251 rl_dest = EvalLoc(rl_dest, kAnyReg, false);
buzbee2700f7e2014-03-07 09:46:20 -0800252 LoadValueDirectWide(rl_src, rl_dest.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700253 }
254
255 // Dest is now live and dirty (until/if we flush it to home location)
buzbee091cc402014-03-31 10:14:40 -0700256 MarkLive(rl_dest);
257 MarkWide(rl_dest.reg);
258 MarkDirty(rl_dest);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700259
260 ResetDefLocWide(rl_dest);
buzbee091cc402014-03-31 10:14:40 -0700261 if (IsDirty(rl_dest.reg) && (LiveOut(rl_dest.s_reg_low) ||
262 LiveOut(GetSRegHi(rl_dest.s_reg_low)))) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700263 def_start = last_lir_insn_;
264 DCHECK_EQ((mir_graph_->SRegToVReg(rl_dest.s_reg_low)+1),
265 mir_graph_->SRegToVReg(GetSRegHi(rl_dest.s_reg_low)));
Vladimir Marko8dea81c2014-06-06 14:50:36 +0100266 ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
Chao-ying Fua77ee512014-07-01 17:43:41 -0700267 StoreBaseDisp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg, k64, kNotVolatile);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700268 MarkClean(rl_dest);
269 def_end = last_lir_insn_;
270 MarkDefWide(rl_dest, def_start, def_end);
271 }
272}
273
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800274void Mir2Lir::StoreFinalValue(RegLocation rl_dest, RegLocation rl_src) {
275 DCHECK_EQ(rl_src.location, kLocPhysReg);
276
277 if (rl_dest.location == kLocPhysReg) {
buzbee2700f7e2014-03-07 09:46:20 -0800278 OpRegCopy(rl_dest.reg, rl_src.reg);
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800279 } else {
280 // Just re-assign the register. Dest gets Src's reg.
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800281 rl_dest.location = kLocPhysReg;
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000282 rl_dest.reg = rl_src.reg;
buzbee2700f7e2014-03-07 09:46:20 -0800283 Clobber(rl_src.reg);
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800284 }
285
286 // Dest is now live and dirty (until/if we flush it to home location)
buzbee091cc402014-03-31 10:14:40 -0700287 MarkLive(rl_dest);
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800288 MarkDirty(rl_dest);
289
290
291 ResetDefLoc(rl_dest);
buzbee091cc402014-03-31 10:14:40 -0700292 if (IsDirty(rl_dest.reg) && LiveOut(rl_dest.s_reg_low)) {
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800293 LIR *def_start = last_lir_insn_;
Vladimir Marko8dea81c2014-06-06 14:50:36 +0100294 ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
Chao-ying Fua77ee512014-07-01 17:43:41 -0700295 Store32Disp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg);
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800296 MarkClean(rl_dest);
297 LIR *def_end = last_lir_insn_;
298 if (!rl_dest.ref) {
299 // Exclude references from store elimination
300 MarkDef(rl_dest, def_start, def_end);
301 }
302 }
303}
304
Mark Mendelle02d48f2014-01-15 11:19:23 -0800305void Mir2Lir::StoreFinalValueWide(RegLocation rl_dest, RegLocation rl_src) {
Mark Mendelle02d48f2014-01-15 11:19:23 -0800306 DCHECK(rl_dest.wide);
307 DCHECK(rl_src.wide);
308 DCHECK_EQ(rl_src.location, kLocPhysReg);
309
310 if (rl_dest.location == kLocPhysReg) {
buzbee2700f7e2014-03-07 09:46:20 -0800311 OpRegCopyWide(rl_dest.reg, rl_src.reg);
Mark Mendelle02d48f2014-01-15 11:19:23 -0800312 } else {
313 // Just re-assign the registers. Dest gets Src's regs.
Mark Mendelle02d48f2014-01-15 11:19:23 -0800314 rl_dest.location = kLocPhysReg;
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000315 rl_dest.reg = rl_src.reg;
buzbee091cc402014-03-31 10:14:40 -0700316 Clobber(rl_src.reg);
Mark Mendelle02d48f2014-01-15 11:19:23 -0800317 }
318
319 // Dest is now live and dirty (until/if we flush it to home location).
buzbee091cc402014-03-31 10:14:40 -0700320 MarkLive(rl_dest);
321 MarkWide(rl_dest.reg);
322 MarkDirty(rl_dest);
Mark Mendelle02d48f2014-01-15 11:19:23 -0800323
324 ResetDefLocWide(rl_dest);
buzbee091cc402014-03-31 10:14:40 -0700325 if (IsDirty(rl_dest.reg) && (LiveOut(rl_dest.s_reg_low) ||
326 LiveOut(GetSRegHi(rl_dest.s_reg_low)))) {
Mark Mendelle02d48f2014-01-15 11:19:23 -0800327 LIR *def_start = last_lir_insn_;
328 DCHECK_EQ((mir_graph_->SRegToVReg(rl_dest.s_reg_low)+1),
329 mir_graph_->SRegToVReg(GetSRegHi(rl_dest.s_reg_low)));
Vladimir Marko8dea81c2014-06-06 14:50:36 +0100330 ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
Chao-ying Fua77ee512014-07-01 17:43:41 -0700331 StoreBaseDisp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg, k64, kNotVolatile);
Mark Mendelle02d48f2014-01-15 11:19:23 -0800332 MarkClean(rl_dest);
333 LIR *def_end = last_lir_insn_;
334 MarkDefWide(rl_dest, def_start, def_end);
335 }
336}
337
Brian Carlstrom7940e442013-07-12 13:46:57 -0700338/* Utilities to load the current Method* */
buzbee2700f7e2014-03-07 09:46:20 -0800339void Mir2Lir::LoadCurrMethodDirect(RegStorage r_tgt) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700340 LoadValueDirectFixed(mir_graph_->GetMethodLoc(), r_tgt);
341}
342
Vladimir Marko20f85592015-03-19 10:07:02 +0000343RegStorage Mir2Lir::LoadCurrMethodWithHint(RegStorage r_hint) {
344 // If the method is promoted to a register, return that register, otherwise load it to r_hint.
345 // (Replacement for LoadCurrMethod() usually used when LockCallTemps() is in effect.)
346 DCHECK(r_hint.Valid());
347 RegLocation rl_method = mir_graph_->GetMethodLoc();
348 if (rl_method.location == kLocPhysReg) {
349 DCHECK(!IsTemp(rl_method.reg));
350 return rl_method.reg;
351 } else {
352 LoadCurrMethodDirect(r_hint);
353 return r_hint;
354 }
355}
356
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700357RegLocation Mir2Lir::LoadCurrMethod() {
buzbeea0cd2d72014-06-01 09:33:49 -0700358 return LoadValue(mir_graph_->GetMethodLoc(), kRefReg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700359}
360
Mark Mendelle02d48f2014-01-15 11:19:23 -0800361RegLocation Mir2Lir::ForceTemp(RegLocation loc) {
362 DCHECK(!loc.wide);
363 DCHECK(loc.location == kLocPhysReg);
buzbee091cc402014-03-31 10:14:40 -0700364 DCHECK(!loc.reg.IsFloat());
buzbee2700f7e2014-03-07 09:46:20 -0800365 if (IsTemp(loc.reg)) {
366 Clobber(loc.reg);
Mark Mendelle02d48f2014-01-15 11:19:23 -0800367 } else {
buzbee2700f7e2014-03-07 09:46:20 -0800368 RegStorage temp_low = AllocTemp();
369 OpRegCopy(temp_low, loc.reg);
370 loc.reg = temp_low;
Mark Mendelle02d48f2014-01-15 11:19:23 -0800371 }
372
373 // Ensure that this doesn't represent the original SR any more.
374 loc.s_reg_low = INVALID_SREG;
375 return loc;
376}
377
378RegLocation Mir2Lir::ForceTempWide(RegLocation loc) {
379 DCHECK(loc.wide);
380 DCHECK(loc.location == kLocPhysReg);
buzbee091cc402014-03-31 10:14:40 -0700381 DCHECK(!loc.reg.IsFloat());
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700382
383 if (!loc.reg.IsPair()) {
384 if (IsTemp(loc.reg)) {
385 Clobber(loc.reg);
386 } else {
387 RegStorage temp = AllocTempWide();
388 OpRegCopy(temp, loc.reg);
389 loc.reg = temp;
390 }
Mark Mendelle02d48f2014-01-15 11:19:23 -0800391 } else {
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700392 if (IsTemp(loc.reg.GetLow())) {
393 Clobber(loc.reg.GetLow());
394 } else {
395 RegStorage temp_low = AllocTemp();
396 OpRegCopy(temp_low, loc.reg.GetLow());
397 loc.reg.SetLowReg(temp_low.GetReg());
398 }
399 if (IsTemp(loc.reg.GetHigh())) {
400 Clobber(loc.reg.GetHigh());
401 } else {
402 RegStorage temp_high = AllocTemp();
403 OpRegCopy(temp_high, loc.reg.GetHigh());
404 loc.reg.SetHighReg(temp_high.GetReg());
405 }
Mark Mendelle02d48f2014-01-15 11:19:23 -0800406 }
407
408 // Ensure that this doesn't represent the original SR any more.
409 loc.s_reg_low = INVALID_SREG;
410 return loc;
411}
412
Brian Carlstrom7940e442013-07-12 13:46:57 -0700413} // namespace art