blob: 3f8900177241f0e259214deb51a4eeb2878902a3 [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) {
Mathieu Chartiere401d142015-04-22 13:56:20 -070045 rl_src = rl_src.wide ? UpdateLocWide(rl_src) : UpdateLoc(rl_src);
Brian Carlstrom7940e442013-07-12 13:46:57 -070046 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)) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -070049 // On 64-bit targets, will sign extend. Make sure constant reference is always null.
buzbee695d13a2014-04-19 13:32:20 -070050 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);
Mathieu Chartiere401d142015-04-22 13:56:20 -070056 OpSize op_size;
buzbee695d13a2014-04-19 13:32:20 -070057 if (rl_src.ref) {
Mathieu Chartiere401d142015-04-22 13:56:20 -070058 op_size = kReference;
59 } else if (rl_src.wide) {
60 op_size = k64;
buzbee695d13a2014-04-19 13:32:20 -070061 } else {
Mathieu Chartiere401d142015-04-22 13:56:20 -070062 op_size = k32;
buzbee695d13a2014-04-19 13:32:20 -070063 }
Mathieu Chartiere401d142015-04-22 13:56:20 -070064 LoadBaseDisp(TargetPtrReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest, op_size, kNotVolatile);
Brian Carlstrom7940e442013-07-12 13:46:57 -070065 }
66}
67
68/*
69 * Similar to LoadValueDirect, but clobbers and allocates the target
70 * register. Should be used when loading to a fixed register (for example,
71 * loading arguments to an out of line call.
72 */
buzbee2700f7e2014-03-07 09:46:20 -080073void Mir2Lir::LoadValueDirectFixed(RegLocation rl_src, RegStorage r_dest) {
Brian Carlstrom7940e442013-07-12 13:46:57 -070074 Clobber(r_dest);
75 MarkInUse(r_dest);
76 LoadValueDirect(rl_src, r_dest);
77}
78
79/*
80 * Load a Dalvik register pair into a physical register[s]. Take care when
81 * using this routine, as it doesn't perform any bookkeeping regarding
82 * register liveness. That is the responsibility of the caller.
83 */
buzbee2700f7e2014-03-07 09:46:20 -080084void Mir2Lir::LoadValueDirectWide(RegLocation rl_src, RegStorage r_dest) {
Brian Carlstrom7940e442013-07-12 13:46:57 -070085 rl_src = UpdateLocWide(rl_src);
86 if (rl_src.location == kLocPhysReg) {
buzbee2700f7e2014-03-07 09:46:20 -080087 OpRegCopyWide(r_dest, rl_src.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -070088 } else if (IsInexpensiveConstant(rl_src)) {
buzbee2700f7e2014-03-07 09:46:20 -080089 LoadConstantWide(r_dest, mir_graph_->ConstantValueWide(rl_src));
Brian Carlstrom7940e442013-07-12 13:46:57 -070090 } else {
91 DCHECK((rl_src.location == kLocDalvikFrame) ||
92 (rl_src.location == kLocCompilerTemp));
Vladimir Marko8dea81c2014-06-06 14:50:36 +010093 ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
Chao-ying Fua77ee512014-07-01 17:43:41 -070094 LoadBaseDisp(TargetPtrReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest, k64, kNotVolatile);
Brian Carlstrom7940e442013-07-12 13:46:57 -070095 }
96}
97
98/*
99 * Similar to LoadValueDirect, but clobbers and allocates the target
100 * registers. Should be used when loading to a fixed registers (for example,
101 * loading arguments to an out of line call.
102 */
buzbee2700f7e2014-03-07 09:46:20 -0800103void Mir2Lir::LoadValueDirectWideFixed(RegLocation rl_src, RegStorage r_dest) {
104 Clobber(r_dest);
105 MarkInUse(r_dest);
106 LoadValueDirectWide(rl_src, r_dest);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700107}
108
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700109RegLocation Mir2Lir::LoadValue(RegLocation rl_src, RegisterClass op_kind) {
Vladimir Marko5e6926c2015-06-27 13:44:06 +0100110 // If op_kind isn't a reference, rl_src should not be marked as a reference either
111 // unless we've seen type conflicts (i.e. register promotion is disabled).
112 DCHECK(op_kind == kRefReg || (!rl_src.ref || (cu_->disable_opt & (1u << kPromoteRegs)) != 0u));
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100113 rl_src = UpdateLoc(rl_src);
114 if (rl_src.location == kLocPhysReg) {
115 if (!RegClassMatches(op_kind, rl_src.reg)) {
116 // Wrong register class, realloc, copy and transfer ownership.
117 RegStorage new_reg = AllocTypedTemp(rl_src.fp, op_kind);
118 OpRegCopy(new_reg, rl_src.reg);
Serguei Katkov02c637e2014-10-29 13:48:02 +0600119 // Clobber the old regs and free it.
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100120 Clobber(rl_src.reg);
Serguei Katkov02c637e2014-10-29 13:48:02 +0600121 FreeTemp(rl_src.reg);
buzbee082833c2014-05-17 23:16:26 -0700122 // ...and mark the new one live.
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100123 rl_src.reg = new_reg;
buzbee082833c2014-05-17 23:16:26 -0700124 MarkLive(rl_src);
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100125 }
126 return rl_src;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700127 }
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100128
129 DCHECK_NE(rl_src.s_reg_low, INVALID_SREG);
130 rl_src.reg = AllocTypedTemp(rl_src.fp, op_kind);
131 LoadValueDirect(rl_src, rl_src.reg);
132 rl_src.location = kLocPhysReg;
133 MarkLive(rl_src);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700134 return rl_src;
135}
136
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700137void Mir2Lir::StoreValue(RegLocation rl_dest, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700138 /*
139 * Sanity checking - should never try to store to the same
140 * ssa name during the compilation of a single instruction
141 * without an intervening ClobberSReg().
142 */
143 if (kIsDebugBuild) {
144 DCHECK((live_sreg_ == INVALID_SREG) ||
145 (rl_dest.s_reg_low != live_sreg_));
146 live_sreg_ = rl_dest.s_reg_low;
147 }
148 LIR* def_start;
149 LIR* def_end;
150 DCHECK(!rl_dest.wide);
151 DCHECK(!rl_src.wide);
152 rl_src = UpdateLoc(rl_src);
153 rl_dest = UpdateLoc(rl_dest);
154 if (rl_src.location == kLocPhysReg) {
buzbee2700f7e2014-03-07 09:46:20 -0800155 if (IsLive(rl_src.reg) ||
156 IsPromoted(rl_src.reg) ||
Brian Carlstrom7940e442013-07-12 13:46:57 -0700157 (rl_dest.location == kLocPhysReg)) {
158 // Src is live/promoted or Dest has assigned reg.
Andreas Gampe4b537a82014-06-30 22:24:53 -0700159 rl_dest = EvalLoc(rl_dest, rl_dest.ref || rl_src.ref ? kRefReg : kAnyReg, false);
buzbee2700f7e2014-03-07 09:46:20 -0800160 OpRegCopy(rl_dest.reg, rl_src.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700161 } else {
162 // Just re-assign the registers. Dest gets Src's regs
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000163 rl_dest.reg = rl_src.reg;
buzbee2700f7e2014-03-07 09:46:20 -0800164 Clobber(rl_src.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700165 }
166 } else {
167 // Load Src either into promoted Dest or temps allocated for Dest
Andreas Gampe4b537a82014-06-30 22:24:53 -0700168 rl_dest = EvalLoc(rl_dest, rl_dest.ref ? kRefReg : kAnyReg, false);
buzbee2700f7e2014-03-07 09:46:20 -0800169 LoadValueDirect(rl_src, rl_dest.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700170 }
171
172 // Dest is now live and dirty (until/if we flush it to home location)
buzbee091cc402014-03-31 10:14:40 -0700173 MarkLive(rl_dest);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700174 MarkDirty(rl_dest);
175
176
177 ResetDefLoc(rl_dest);
buzbee091cc402014-03-31 10:14:40 -0700178 if (IsDirty(rl_dest.reg) && LiveOut(rl_dest.s_reg_low)) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700179 def_start = last_lir_insn_;
Ian Rogerse98297b2014-06-22 07:47:53 +0000180 ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
Andreas Gampe2073e752014-06-23 15:39:00 +0000181 if (rl_dest.ref) {
Chao-ying Fua77ee512014-07-01 17:43:41 -0700182 StoreRefDisp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg, kNotVolatile);
Andreas Gampe2073e752014-06-23 15:39:00 +0000183 } else {
Chao-ying Fua77ee512014-07-01 17:43:41 -0700184 Store32Disp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg);
Andreas Gampe2073e752014-06-23 15:39:00 +0000185 }
Brian Carlstrom7940e442013-07-12 13:46:57 -0700186 MarkClean(rl_dest);
187 def_end = last_lir_insn_;
188 if (!rl_dest.ref) {
189 // Exclude references from store elimination
190 MarkDef(rl_dest, def_start, def_end);
191 }
192 }
193}
194
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700195RegLocation Mir2Lir::LoadValueWide(RegLocation rl_src, RegisterClass op_kind) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700196 DCHECK(rl_src.wide);
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100197 rl_src = UpdateLocWide(rl_src);
198 if (rl_src.location == kLocPhysReg) {
199 if (!RegClassMatches(op_kind, rl_src.reg)) {
200 // Wrong register class, realloc, copy and transfer ownership.
201 RegStorage new_regs = AllocTypedTempWide(rl_src.fp, op_kind);
202 OpRegCopyWide(new_regs, rl_src.reg);
Serguei Katkov02c637e2014-10-29 13:48:02 +0600203 // Clobber the old regs and free it.
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100204 Clobber(rl_src.reg);
Serguei Katkov02c637e2014-10-29 13:48:02 +0600205 FreeTemp(rl_src.reg);
buzbee082833c2014-05-17 23:16:26 -0700206 // ...and mark the new ones live.
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100207 rl_src.reg = new_regs;
buzbee082833c2014-05-17 23:16:26 -0700208 MarkLive(rl_src);
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100209 }
210 return rl_src;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700211 }
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100212
213 DCHECK_NE(rl_src.s_reg_low, INVALID_SREG);
214 DCHECK_NE(GetSRegHi(rl_src.s_reg_low), INVALID_SREG);
215 rl_src.reg = AllocTypedTempWide(rl_src.fp, op_kind);
216 LoadValueDirectWide(rl_src, rl_src.reg);
217 rl_src.location = kLocPhysReg;
218 MarkLive(rl_src);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700219 return rl_src;
220}
221
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700222void Mir2Lir::StoreValueWide(RegLocation rl_dest, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700223 /*
224 * Sanity checking - should never try to store to the same
225 * ssa name during the compilation of a single instruction
226 * without an intervening ClobberSReg().
227 */
228 if (kIsDebugBuild) {
229 DCHECK((live_sreg_ == INVALID_SREG) ||
230 (rl_dest.s_reg_low != live_sreg_));
231 live_sreg_ = rl_dest.s_reg_low;
232 }
233 LIR* def_start;
234 LIR* def_end;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700235 DCHECK(rl_dest.wide);
236 DCHECK(rl_src.wide);
Alexei Zavjalovc17ebe82014-02-26 10:38:23 +0700237 rl_src = UpdateLocWide(rl_src);
238 rl_dest = UpdateLocWide(rl_dest);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700239 if (rl_src.location == kLocPhysReg) {
buzbee2700f7e2014-03-07 09:46:20 -0800240 if (IsLive(rl_src.reg) ||
241 IsPromoted(rl_src.reg) ||
Brian Carlstrom7940e442013-07-12 13:46:57 -0700242 (rl_dest.location == kLocPhysReg)) {
buzbee30adc732014-05-09 15:10:18 -0700243 /*
244 * If src reg[s] are tied to the original Dalvik vreg via liveness or promotion, we
245 * can't repurpose them. Similarly, if the dest reg[s] are tied to Dalvik vregs via
246 * promotion, we can't just re-assign. In these cases, we have to copy.
247 */
Brian Carlstrom7940e442013-07-12 13:46:57 -0700248 rl_dest = EvalLoc(rl_dest, kAnyReg, false);
buzbee2700f7e2014-03-07 09:46:20 -0800249 OpRegCopyWide(rl_dest.reg, rl_src.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700250 } else {
251 // Just re-assign the registers. Dest gets Src's regs
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000252 rl_dest.reg = rl_src.reg;
buzbee2700f7e2014-03-07 09:46:20 -0800253 Clobber(rl_src.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700254 }
255 } else {
256 // Load Src either into promoted Dest or temps allocated for Dest
257 rl_dest = EvalLoc(rl_dest, kAnyReg, false);
buzbee2700f7e2014-03-07 09:46:20 -0800258 LoadValueDirectWide(rl_src, rl_dest.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700259 }
260
261 // Dest is now live and dirty (until/if we flush it to home location)
buzbee091cc402014-03-31 10:14:40 -0700262 MarkLive(rl_dest);
263 MarkWide(rl_dest.reg);
264 MarkDirty(rl_dest);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700265
266 ResetDefLocWide(rl_dest);
buzbee091cc402014-03-31 10:14:40 -0700267 if (IsDirty(rl_dest.reg) && (LiveOut(rl_dest.s_reg_low) ||
268 LiveOut(GetSRegHi(rl_dest.s_reg_low)))) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700269 def_start = last_lir_insn_;
270 DCHECK_EQ((mir_graph_->SRegToVReg(rl_dest.s_reg_low)+1),
271 mir_graph_->SRegToVReg(GetSRegHi(rl_dest.s_reg_low)));
Vladimir Marko8dea81c2014-06-06 14:50:36 +0100272 ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
Chao-ying Fua77ee512014-07-01 17:43:41 -0700273 StoreBaseDisp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg, k64, kNotVolatile);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700274 MarkClean(rl_dest);
275 def_end = last_lir_insn_;
276 MarkDefWide(rl_dest, def_start, def_end);
277 }
278}
279
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800280void Mir2Lir::StoreFinalValue(RegLocation rl_dest, RegLocation rl_src) {
281 DCHECK_EQ(rl_src.location, kLocPhysReg);
282
283 if (rl_dest.location == kLocPhysReg) {
buzbee2700f7e2014-03-07 09:46:20 -0800284 OpRegCopy(rl_dest.reg, rl_src.reg);
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800285 } else {
286 // Just re-assign the register. Dest gets Src's reg.
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800287 rl_dest.location = kLocPhysReg;
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000288 rl_dest.reg = rl_src.reg;
buzbee2700f7e2014-03-07 09:46:20 -0800289 Clobber(rl_src.reg);
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800290 }
291
292 // Dest is now live and dirty (until/if we flush it to home location)
buzbee091cc402014-03-31 10:14:40 -0700293 MarkLive(rl_dest);
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800294 MarkDirty(rl_dest);
295
296
297 ResetDefLoc(rl_dest);
buzbee091cc402014-03-31 10:14:40 -0700298 if (IsDirty(rl_dest.reg) && LiveOut(rl_dest.s_reg_low)) {
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800299 LIR *def_start = last_lir_insn_;
Vladimir Marko8dea81c2014-06-06 14:50:36 +0100300 ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
Chao-ying Fua77ee512014-07-01 17:43:41 -0700301 Store32Disp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg);
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800302 MarkClean(rl_dest);
303 LIR *def_end = last_lir_insn_;
304 if (!rl_dest.ref) {
305 // Exclude references from store elimination
306 MarkDef(rl_dest, def_start, def_end);
307 }
308 }
309}
310
Mark Mendelle02d48f2014-01-15 11:19:23 -0800311void Mir2Lir::StoreFinalValueWide(RegLocation rl_dest, RegLocation rl_src) {
Mark Mendelle02d48f2014-01-15 11:19:23 -0800312 DCHECK(rl_dest.wide);
313 DCHECK(rl_src.wide);
314 DCHECK_EQ(rl_src.location, kLocPhysReg);
315
316 if (rl_dest.location == kLocPhysReg) {
buzbee2700f7e2014-03-07 09:46:20 -0800317 OpRegCopyWide(rl_dest.reg, rl_src.reg);
Mark Mendelle02d48f2014-01-15 11:19:23 -0800318 } else {
319 // Just re-assign the registers. Dest gets Src's regs.
Mark Mendelle02d48f2014-01-15 11:19:23 -0800320 rl_dest.location = kLocPhysReg;
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000321 rl_dest.reg = rl_src.reg;
buzbee091cc402014-03-31 10:14:40 -0700322 Clobber(rl_src.reg);
Mark Mendelle02d48f2014-01-15 11:19:23 -0800323 }
324
325 // Dest is now live and dirty (until/if we flush it to home location).
buzbee091cc402014-03-31 10:14:40 -0700326 MarkLive(rl_dest);
327 MarkWide(rl_dest.reg);
328 MarkDirty(rl_dest);
Mark Mendelle02d48f2014-01-15 11:19:23 -0800329
330 ResetDefLocWide(rl_dest);
buzbee091cc402014-03-31 10:14:40 -0700331 if (IsDirty(rl_dest.reg) && (LiveOut(rl_dest.s_reg_low) ||
332 LiveOut(GetSRegHi(rl_dest.s_reg_low)))) {
Mark Mendelle02d48f2014-01-15 11:19:23 -0800333 LIR *def_start = last_lir_insn_;
334 DCHECK_EQ((mir_graph_->SRegToVReg(rl_dest.s_reg_low)+1),
335 mir_graph_->SRegToVReg(GetSRegHi(rl_dest.s_reg_low)));
Vladimir Marko8dea81c2014-06-06 14:50:36 +0100336 ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
Chao-ying Fua77ee512014-07-01 17:43:41 -0700337 StoreBaseDisp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg, k64, kNotVolatile);
Mark Mendelle02d48f2014-01-15 11:19:23 -0800338 MarkClean(rl_dest);
339 LIR *def_end = last_lir_insn_;
340 MarkDefWide(rl_dest, def_start, def_end);
341 }
342}
343
Brian Carlstrom7940e442013-07-12 13:46:57 -0700344/* Utilities to load the current Method* */
buzbee2700f7e2014-03-07 09:46:20 -0800345void Mir2Lir::LoadCurrMethodDirect(RegStorage r_tgt) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700346 if (GetCompilationUnit()->target64) {
347 LoadValueDirectWideFixed(mir_graph_->GetMethodLoc(), r_tgt);
348 } else {
349 LoadValueDirectFixed(mir_graph_->GetMethodLoc(), r_tgt);
350 }
Brian Carlstrom7940e442013-07-12 13:46:57 -0700351}
352
Vladimir Marko20f85592015-03-19 10:07:02 +0000353RegStorage Mir2Lir::LoadCurrMethodWithHint(RegStorage r_hint) {
354 // If the method is promoted to a register, return that register, otherwise load it to r_hint.
355 // (Replacement for LoadCurrMethod() usually used when LockCallTemps() is in effect.)
356 DCHECK(r_hint.Valid());
357 RegLocation rl_method = mir_graph_->GetMethodLoc();
358 if (rl_method.location == kLocPhysReg) {
359 DCHECK(!IsTemp(rl_method.reg));
360 return rl_method.reg;
361 } else {
362 LoadCurrMethodDirect(r_hint);
363 return r_hint;
364 }
365}
366
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700367RegLocation Mir2Lir::LoadCurrMethod() {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700368 return GetCompilationUnit()->target64 ?
369 LoadValueWide(mir_graph_->GetMethodLoc(), kCoreReg) :
370 LoadValue(mir_graph_->GetMethodLoc(), kRefReg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700371}
372
Mark Mendelle02d48f2014-01-15 11:19:23 -0800373RegLocation Mir2Lir::ForceTemp(RegLocation loc) {
374 DCHECK(!loc.wide);
375 DCHECK(loc.location == kLocPhysReg);
buzbee091cc402014-03-31 10:14:40 -0700376 DCHECK(!loc.reg.IsFloat());
buzbee2700f7e2014-03-07 09:46:20 -0800377 if (IsTemp(loc.reg)) {
378 Clobber(loc.reg);
Mark Mendelle02d48f2014-01-15 11:19:23 -0800379 } else {
buzbee2700f7e2014-03-07 09:46:20 -0800380 RegStorage temp_low = AllocTemp();
381 OpRegCopy(temp_low, loc.reg);
382 loc.reg = temp_low;
Mark Mendelle02d48f2014-01-15 11:19:23 -0800383 }
384
385 // Ensure that this doesn't represent the original SR any more.
386 loc.s_reg_low = INVALID_SREG;
387 return loc;
388}
389
390RegLocation Mir2Lir::ForceTempWide(RegLocation loc) {
391 DCHECK(loc.wide);
392 DCHECK(loc.location == kLocPhysReg);
buzbee091cc402014-03-31 10:14:40 -0700393 DCHECK(!loc.reg.IsFloat());
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700394
395 if (!loc.reg.IsPair()) {
396 if (IsTemp(loc.reg)) {
397 Clobber(loc.reg);
398 } else {
399 RegStorage temp = AllocTempWide();
400 OpRegCopy(temp, loc.reg);
401 loc.reg = temp;
402 }
Mark Mendelle02d48f2014-01-15 11:19:23 -0800403 } else {
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700404 if (IsTemp(loc.reg.GetLow())) {
405 Clobber(loc.reg.GetLow());
406 } else {
407 RegStorage temp_low = AllocTemp();
408 OpRegCopy(temp_low, loc.reg.GetLow());
409 loc.reg.SetLowReg(temp_low.GetReg());
410 }
411 if (IsTemp(loc.reg.GetHigh())) {
412 Clobber(loc.reg.GetHigh());
413 } else {
414 RegStorage temp_high = AllocTemp();
415 OpRegCopy(temp_high, loc.reg.GetHigh());
416 loc.reg.SetHighReg(temp_high.GetReg());
417 }
Mark Mendelle02d48f2014-01-15 11:19:23 -0800418 }
419
420 // Ensure that this doesn't represent the original SR any more.
421 loc.s_reg_low = INVALID_SREG;
422 return loc;
423}
424
Brian Carlstrom7940e442013-07-12 13:46:57 -0700425} // namespace art