blob: 6ef793427cb36e2c91e6816eedf655f453299a29 [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
17#include "dex/compiler_ir.h"
18#include "dex/compiler_internals.h"
19#include "dex/quick/mir_to_lir-inl.h"
20#include "invoke_type.h"
21
22namespace art {
23
24/* This file contains target-independent codegen and support. */
25
26/*
27 * Load an immediate value into a fixed or temp register. Target
28 * register is clobbered, and marked in_use.
29 */
buzbee2700f7e2014-03-07 09:46:20 -080030LIR* Mir2Lir::LoadConstant(RegStorage r_dest, int value) {
Brian Carlstrom7940e442013-07-12 13:46:57 -070031 if (IsTemp(r_dest)) {
32 Clobber(r_dest);
33 MarkInUse(r_dest);
34 }
35 return LoadConstantNoClobber(r_dest, value);
36}
37
38/*
39 * Temporary workaround for Issue 7250540. If we're loading a constant zero into a
40 * promoted floating point register, also copy a zero into the int/ref identity of
41 * that sreg.
42 */
buzbee2700f7e2014-03-07 09:46:20 -080043void Mir2Lir::Workaround7250540(RegLocation rl_dest, RegStorage zero_reg) {
Brian Carlstrom7940e442013-07-12 13:46:57 -070044 if (rl_dest.fp) {
45 int pmap_index = SRegToPMap(rl_dest.s_reg_low);
46 if (promotion_map_[pmap_index].fp_location == kLocPhysReg) {
47 // Now, determine if this vreg is ever used as a reference. If not, we're done.
48 bool used_as_reference = false;
49 int base_vreg = mir_graph_->SRegToVReg(rl_dest.s_reg_low);
50 for (int i = 0; !used_as_reference && (i < mir_graph_->GetNumSSARegs()); i++) {
51 if (mir_graph_->SRegToVReg(mir_graph_->reg_location_[i].s_reg_low) == base_vreg) {
52 used_as_reference |= mir_graph_->reg_location_[i].ref;
53 }
54 }
55 if (!used_as_reference) {
56 return;
57 }
buzbee2700f7e2014-03-07 09:46:20 -080058 RegStorage temp_reg = zero_reg;
59 if (!temp_reg.Valid()) {
Brian Carlstrom7940e442013-07-12 13:46:57 -070060 temp_reg = AllocTemp();
61 LoadConstant(temp_reg, 0);
62 }
63 if (promotion_map_[pmap_index].core_location == kLocPhysReg) {
64 // Promoted - just copy in a zero
buzbee2700f7e2014-03-07 09:46:20 -080065 OpRegCopy(RegStorage::Solo32(promotion_map_[pmap_index].core_reg), temp_reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -070066 } else {
67 // Lives in the frame, need to store.
buzbee695d13a2014-04-19 13:32:20 -070068 StoreBaseDisp(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low), temp_reg, k32);
Brian Carlstrom7940e442013-07-12 13:46:57 -070069 }
buzbee2700f7e2014-03-07 09:46:20 -080070 if (!zero_reg.Valid()) {
Brian Carlstrom7940e442013-07-12 13:46:57 -070071 FreeTemp(temp_reg);
72 }
73 }
74 }
75}
76
Brian Carlstrom7940e442013-07-12 13:46:57 -070077/*
78 * Load a Dalvik register into a physical register. Take care when
79 * using this routine, as it doesn't perform any bookkeeping regarding
80 * register liveness. That is the responsibility of the caller.
81 */
buzbee2700f7e2014-03-07 09:46:20 -080082void Mir2Lir::LoadValueDirect(RegLocation rl_src, RegStorage r_dest) {
Brian Carlstrom7940e442013-07-12 13:46:57 -070083 rl_src = UpdateLoc(rl_src);
84 if (rl_src.location == kLocPhysReg) {
buzbee2700f7e2014-03-07 09:46:20 -080085 OpRegCopy(r_dest, rl_src.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -070086 } else if (IsInexpensiveConstant(rl_src)) {
buzbee695d13a2014-04-19 13:32:20 -070087 // On 64-bit targets, will sign extend. Make sure constant reference is always NULL.
88 DCHECK(!rl_src.ref || (mir_graph_->ConstantValue(rl_src) == 0));
Brian Carlstrom7940e442013-07-12 13:46:57 -070089 LoadConstantNoClobber(r_dest, mir_graph_->ConstantValue(rl_src));
90 } else {
91 DCHECK((rl_src.location == kLocDalvikFrame) ||
92 (rl_src.location == kLocCompilerTemp));
buzbee695d13a2014-04-19 13:32:20 -070093 if (rl_src.ref) {
94 LoadRefDisp(TargetReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest);
95 } else {
96 Load32Disp(TargetReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest);
97 }
Brian Carlstrom7940e442013-07-12 13:46:57 -070098 }
99}
100
101/*
102 * Similar to LoadValueDirect, but clobbers and allocates the target
103 * register. Should be used when loading to a fixed register (for example,
104 * loading arguments to an out of line call.
105 */
buzbee2700f7e2014-03-07 09:46:20 -0800106void Mir2Lir::LoadValueDirectFixed(RegLocation rl_src, RegStorage r_dest) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700107 Clobber(r_dest);
108 MarkInUse(r_dest);
109 LoadValueDirect(rl_src, r_dest);
110}
111
112/*
113 * Load a Dalvik register pair into a physical register[s]. Take care when
114 * using this routine, as it doesn't perform any bookkeeping regarding
115 * register liveness. That is the responsibility of the caller.
116 */
buzbee2700f7e2014-03-07 09:46:20 -0800117void Mir2Lir::LoadValueDirectWide(RegLocation rl_src, RegStorage r_dest) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700118 rl_src = UpdateLocWide(rl_src);
119 if (rl_src.location == kLocPhysReg) {
buzbee2700f7e2014-03-07 09:46:20 -0800120 OpRegCopyWide(r_dest, rl_src.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700121 } else if (IsInexpensiveConstant(rl_src)) {
buzbee2700f7e2014-03-07 09:46:20 -0800122 LoadConstantWide(r_dest, mir_graph_->ConstantValueWide(rl_src));
Brian Carlstrom7940e442013-07-12 13:46:57 -0700123 } else {
124 DCHECK((rl_src.location == kLocDalvikFrame) ||
125 (rl_src.location == kLocCompilerTemp));
Vladimir Marko3bf7c602014-05-07 14:55:43 +0100126 LoadBaseDisp(TargetReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest, k64);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700127 }
128}
129
130/*
131 * Similar to LoadValueDirect, but clobbers and allocates the target
132 * registers. Should be used when loading to a fixed registers (for example,
133 * loading arguments to an out of line call.
134 */
buzbee2700f7e2014-03-07 09:46:20 -0800135void Mir2Lir::LoadValueDirectWideFixed(RegLocation rl_src, RegStorage r_dest) {
136 Clobber(r_dest);
137 MarkInUse(r_dest);
138 LoadValueDirectWide(rl_src, r_dest);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700139}
140
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700141RegLocation Mir2Lir::LoadValue(RegLocation rl_src, RegisterClass op_kind) {
buzbeea0cd2d72014-06-01 09:33:49 -0700142 DCHECK(!rl_src.ref || op_kind == kRefReg);
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100143 rl_src = UpdateLoc(rl_src);
144 if (rl_src.location == kLocPhysReg) {
145 if (!RegClassMatches(op_kind, rl_src.reg)) {
146 // Wrong register class, realloc, copy and transfer ownership.
147 RegStorage new_reg = AllocTypedTemp(rl_src.fp, op_kind);
148 OpRegCopy(new_reg, rl_src.reg);
buzbee082833c2014-05-17 23:16:26 -0700149 // Clobber the old reg.
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100150 Clobber(rl_src.reg);
buzbee082833c2014-05-17 23:16:26 -0700151 // ...and mark the new one live.
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100152 rl_src.reg = new_reg;
buzbee082833c2014-05-17 23:16:26 -0700153 MarkLive(rl_src);
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100154 }
155 return rl_src;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700156 }
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100157
158 DCHECK_NE(rl_src.s_reg_low, INVALID_SREG);
159 rl_src.reg = AllocTypedTemp(rl_src.fp, op_kind);
160 LoadValueDirect(rl_src, rl_src.reg);
161 rl_src.location = kLocPhysReg;
162 MarkLive(rl_src);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700163 return rl_src;
164}
165
buzbeea0cd2d72014-06-01 09:33:49 -0700166RegLocation Mir2Lir::LoadValue(RegLocation rl_src) {
167 return LoadValue(rl_src, LocToRegClass(rl_src));
168}
169
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700170void Mir2Lir::StoreValue(RegLocation rl_dest, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700171 /*
172 * Sanity checking - should never try to store to the same
173 * ssa name during the compilation of a single instruction
174 * without an intervening ClobberSReg().
175 */
176 if (kIsDebugBuild) {
177 DCHECK((live_sreg_ == INVALID_SREG) ||
178 (rl_dest.s_reg_low != live_sreg_));
179 live_sreg_ = rl_dest.s_reg_low;
180 }
181 LIR* def_start;
182 LIR* def_end;
183 DCHECK(!rl_dest.wide);
184 DCHECK(!rl_src.wide);
185 rl_src = UpdateLoc(rl_src);
186 rl_dest = UpdateLoc(rl_dest);
187 if (rl_src.location == kLocPhysReg) {
buzbee2700f7e2014-03-07 09:46:20 -0800188 if (IsLive(rl_src.reg) ||
189 IsPromoted(rl_src.reg) ||
Brian Carlstrom7940e442013-07-12 13:46:57 -0700190 (rl_dest.location == kLocPhysReg)) {
191 // Src is live/promoted or Dest has assigned reg.
192 rl_dest = EvalLoc(rl_dest, kAnyReg, false);
buzbee2700f7e2014-03-07 09:46:20 -0800193 OpRegCopy(rl_dest.reg, rl_src.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700194 } else {
195 // Just re-assign the registers. Dest gets Src's regs
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000196 rl_dest.reg = rl_src.reg;
buzbee2700f7e2014-03-07 09:46:20 -0800197 Clobber(rl_src.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700198 }
199 } else {
200 // Load Src either into promoted Dest or temps allocated for Dest
201 rl_dest = EvalLoc(rl_dest, kAnyReg, false);
buzbee2700f7e2014-03-07 09:46:20 -0800202 LoadValueDirect(rl_src, rl_dest.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700203 }
204
205 // Dest is now live and dirty (until/if we flush it to home location)
buzbee091cc402014-03-31 10:14:40 -0700206 MarkLive(rl_dest);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700207 MarkDirty(rl_dest);
208
209
210 ResetDefLoc(rl_dest);
buzbee091cc402014-03-31 10:14:40 -0700211 if (IsDirty(rl_dest.reg) && LiveOut(rl_dest.s_reg_low)) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700212 def_start = last_lir_insn_;
buzbee695d13a2014-04-19 13:32:20 -0700213 Store32Disp(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700214 MarkClean(rl_dest);
215 def_end = last_lir_insn_;
216 if (!rl_dest.ref) {
217 // Exclude references from store elimination
218 MarkDef(rl_dest, def_start, def_end);
219 }
220 }
221}
222
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700223RegLocation Mir2Lir::LoadValueWide(RegLocation rl_src, RegisterClass op_kind) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700224 DCHECK(rl_src.wide);
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100225 rl_src = UpdateLocWide(rl_src);
226 if (rl_src.location == kLocPhysReg) {
227 if (!RegClassMatches(op_kind, rl_src.reg)) {
228 // Wrong register class, realloc, copy and transfer ownership.
229 RegStorage new_regs = AllocTypedTempWide(rl_src.fp, op_kind);
230 OpRegCopyWide(new_regs, rl_src.reg);
buzbee082833c2014-05-17 23:16:26 -0700231 // Clobber the old regs.
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100232 Clobber(rl_src.reg);
buzbee082833c2014-05-17 23:16:26 -0700233 // ...and mark the new ones live.
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100234 rl_src.reg = new_regs;
buzbee082833c2014-05-17 23:16:26 -0700235 MarkLive(rl_src);
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100236 }
237 return rl_src;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700238 }
Vladimir Marko0dc242d2014-05-12 16:22:14 +0100239
240 DCHECK_NE(rl_src.s_reg_low, INVALID_SREG);
241 DCHECK_NE(GetSRegHi(rl_src.s_reg_low), INVALID_SREG);
242 rl_src.reg = AllocTypedTempWide(rl_src.fp, op_kind);
243 LoadValueDirectWide(rl_src, rl_src.reg);
244 rl_src.location = kLocPhysReg;
245 MarkLive(rl_src);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700246 return rl_src;
247}
248
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700249void Mir2Lir::StoreValueWide(RegLocation rl_dest, RegLocation rl_src) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700250 /*
251 * Sanity checking - should never try to store to the same
252 * ssa name during the compilation of a single instruction
253 * without an intervening ClobberSReg().
254 */
255 if (kIsDebugBuild) {
256 DCHECK((live_sreg_ == INVALID_SREG) ||
257 (rl_dest.s_reg_low != live_sreg_));
258 live_sreg_ = rl_dest.s_reg_low;
259 }
260 LIR* def_start;
261 LIR* def_end;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700262 DCHECK(rl_dest.wide);
263 DCHECK(rl_src.wide);
Alexei Zavjalovc17ebe82014-02-26 10:38:23 +0700264 rl_src = UpdateLocWide(rl_src);
265 rl_dest = UpdateLocWide(rl_dest);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700266 if (rl_src.location == kLocPhysReg) {
buzbee2700f7e2014-03-07 09:46:20 -0800267 if (IsLive(rl_src.reg) ||
268 IsPromoted(rl_src.reg) ||
Brian Carlstrom7940e442013-07-12 13:46:57 -0700269 (rl_dest.location == kLocPhysReg)) {
buzbee30adc732014-05-09 15:10:18 -0700270 /*
271 * If src reg[s] are tied to the original Dalvik vreg via liveness or promotion, we
272 * can't repurpose them. Similarly, if the dest reg[s] are tied to Dalvik vregs via
273 * promotion, we can't just re-assign. In these cases, we have to copy.
274 */
Brian Carlstrom7940e442013-07-12 13:46:57 -0700275 rl_dest = EvalLoc(rl_dest, kAnyReg, false);
buzbee2700f7e2014-03-07 09:46:20 -0800276 OpRegCopyWide(rl_dest.reg, rl_src.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700277 } else {
278 // Just re-assign the registers. Dest gets Src's regs
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000279 rl_dest.reg = rl_src.reg;
buzbee2700f7e2014-03-07 09:46:20 -0800280 Clobber(rl_src.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700281 }
282 } else {
283 // Load Src either into promoted Dest or temps allocated for Dest
284 rl_dest = EvalLoc(rl_dest, kAnyReg, false);
buzbee2700f7e2014-03-07 09:46:20 -0800285 LoadValueDirectWide(rl_src, rl_dest.reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700286 }
287
288 // Dest is now live and dirty (until/if we flush it to home location)
buzbee091cc402014-03-31 10:14:40 -0700289 MarkLive(rl_dest);
290 MarkWide(rl_dest.reg);
291 MarkDirty(rl_dest);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700292
293 ResetDefLocWide(rl_dest);
buzbee091cc402014-03-31 10:14:40 -0700294 if (IsDirty(rl_dest.reg) && (LiveOut(rl_dest.s_reg_low) ||
295 LiveOut(GetSRegHi(rl_dest.s_reg_low)))) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700296 def_start = last_lir_insn_;
297 DCHECK_EQ((mir_graph_->SRegToVReg(rl_dest.s_reg_low)+1),
298 mir_graph_->SRegToVReg(GetSRegHi(rl_dest.s_reg_low)));
Vladimir Marko455759b2014-05-06 20:49:36 +0100299 StoreBaseDisp(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg, k64);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700300 MarkClean(rl_dest);
301 def_end = last_lir_insn_;
302 MarkDefWide(rl_dest, def_start, def_end);
303 }
304}
305
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800306void Mir2Lir::StoreFinalValue(RegLocation rl_dest, RegLocation rl_src) {
307 DCHECK_EQ(rl_src.location, kLocPhysReg);
308
309 if (rl_dest.location == kLocPhysReg) {
buzbee2700f7e2014-03-07 09:46:20 -0800310 OpRegCopy(rl_dest.reg, rl_src.reg);
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800311 } else {
312 // Just re-assign the register. Dest gets Src's reg.
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800313 rl_dest.location = kLocPhysReg;
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000314 rl_dest.reg = rl_src.reg;
buzbee2700f7e2014-03-07 09:46:20 -0800315 Clobber(rl_src.reg);
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800316 }
317
318 // Dest is now live and dirty (until/if we flush it to home location)
buzbee091cc402014-03-31 10:14:40 -0700319 MarkLive(rl_dest);
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800320 MarkDirty(rl_dest);
321
322
323 ResetDefLoc(rl_dest);
buzbee091cc402014-03-31 10:14:40 -0700324 if (IsDirty(rl_dest.reg) && LiveOut(rl_dest.s_reg_low)) {
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800325 LIR *def_start = last_lir_insn_;
buzbee695d13a2014-04-19 13:32:20 -0700326 Store32Disp(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg);
Mark Mendellfeb2b4e2014-01-28 12:59:49 -0800327 MarkClean(rl_dest);
328 LIR *def_end = last_lir_insn_;
329 if (!rl_dest.ref) {
330 // Exclude references from store elimination
331 MarkDef(rl_dest, def_start, def_end);
332 }
333 }
334}
335
Mark Mendelle02d48f2014-01-15 11:19:23 -0800336void Mir2Lir::StoreFinalValueWide(RegLocation rl_dest, RegLocation rl_src) {
Mark Mendelle02d48f2014-01-15 11:19:23 -0800337 DCHECK(rl_dest.wide);
338 DCHECK(rl_src.wide);
339 DCHECK_EQ(rl_src.location, kLocPhysReg);
340
341 if (rl_dest.location == kLocPhysReg) {
buzbee2700f7e2014-03-07 09:46:20 -0800342 OpRegCopyWide(rl_dest.reg, rl_src.reg);
Mark Mendelle02d48f2014-01-15 11:19:23 -0800343 } else {
344 // Just re-assign the registers. Dest gets Src's regs.
Mark Mendelle02d48f2014-01-15 11:19:23 -0800345 rl_dest.location = kLocPhysReg;
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000346 rl_dest.reg = rl_src.reg;
buzbee091cc402014-03-31 10:14:40 -0700347 Clobber(rl_src.reg);
Mark Mendelle02d48f2014-01-15 11:19:23 -0800348 }
349
350 // Dest is now live and dirty (until/if we flush it to home location).
buzbee091cc402014-03-31 10:14:40 -0700351 MarkLive(rl_dest);
352 MarkWide(rl_dest.reg);
353 MarkDirty(rl_dest);
Mark Mendelle02d48f2014-01-15 11:19:23 -0800354
355 ResetDefLocWide(rl_dest);
buzbee091cc402014-03-31 10:14:40 -0700356 if (IsDirty(rl_dest.reg) && (LiveOut(rl_dest.s_reg_low) ||
357 LiveOut(GetSRegHi(rl_dest.s_reg_low)))) {
Mark Mendelle02d48f2014-01-15 11:19:23 -0800358 LIR *def_start = last_lir_insn_;
359 DCHECK_EQ((mir_graph_->SRegToVReg(rl_dest.s_reg_low)+1),
360 mir_graph_->SRegToVReg(GetSRegHi(rl_dest.s_reg_low)));
Vladimir Marko455759b2014-05-06 20:49:36 +0100361 StoreBaseDisp(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg, k64);
Mark Mendelle02d48f2014-01-15 11:19:23 -0800362 MarkClean(rl_dest);
363 LIR *def_end = last_lir_insn_;
364 MarkDefWide(rl_dest, def_start, def_end);
365 }
366}
367
Brian Carlstrom7940e442013-07-12 13:46:57 -0700368/* Utilities to load the current Method* */
buzbee2700f7e2014-03-07 09:46:20 -0800369void Mir2Lir::LoadCurrMethodDirect(RegStorage r_tgt) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700370 LoadValueDirectFixed(mir_graph_->GetMethodLoc(), r_tgt);
371}
372
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700373RegLocation Mir2Lir::LoadCurrMethod() {
buzbeea0cd2d72014-06-01 09:33:49 -0700374 return LoadValue(mir_graph_->GetMethodLoc(), kRefReg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700375}
376
Mark Mendelle02d48f2014-01-15 11:19:23 -0800377RegLocation Mir2Lir::ForceTemp(RegLocation loc) {
378 DCHECK(!loc.wide);
379 DCHECK(loc.location == kLocPhysReg);
buzbee091cc402014-03-31 10:14:40 -0700380 DCHECK(!loc.reg.IsFloat());
buzbee2700f7e2014-03-07 09:46:20 -0800381 if (IsTemp(loc.reg)) {
382 Clobber(loc.reg);
Mark Mendelle02d48f2014-01-15 11:19:23 -0800383 } else {
buzbee2700f7e2014-03-07 09:46:20 -0800384 RegStorage temp_low = AllocTemp();
385 OpRegCopy(temp_low, loc.reg);
386 loc.reg = temp_low;
Mark Mendelle02d48f2014-01-15 11:19:23 -0800387 }
388
389 // Ensure that this doesn't represent the original SR any more.
390 loc.s_reg_low = INVALID_SREG;
391 return loc;
392}
393
394RegLocation Mir2Lir::ForceTempWide(RegLocation loc) {
395 DCHECK(loc.wide);
396 DCHECK(loc.location == kLocPhysReg);
buzbee091cc402014-03-31 10:14:40 -0700397 DCHECK(!loc.reg.IsFloat());
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700398
399 if (!loc.reg.IsPair()) {
400 if (IsTemp(loc.reg)) {
401 Clobber(loc.reg);
402 } else {
403 RegStorage temp = AllocTempWide();
404 OpRegCopy(temp, loc.reg);
405 loc.reg = temp;
406 }
Mark Mendelle02d48f2014-01-15 11:19:23 -0800407 } else {
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700408 if (IsTemp(loc.reg.GetLow())) {
409 Clobber(loc.reg.GetLow());
410 } else {
411 RegStorage temp_low = AllocTemp();
412 OpRegCopy(temp_low, loc.reg.GetLow());
413 loc.reg.SetLowReg(temp_low.GetReg());
414 }
415 if (IsTemp(loc.reg.GetHigh())) {
416 Clobber(loc.reg.GetHigh());
417 } else {
418 RegStorage temp_high = AllocTemp();
419 OpRegCopy(temp_high, loc.reg.GetHigh());
420 loc.reg.SetHighReg(temp_high.GetReg());
421 }
Mark Mendelle02d48f2014-01-15 11:19:23 -0800422 }
423
424 // Ensure that this doesn't represent the original SR any more.
425 loc.s_reg_low = INVALID_SREG;
426 return loc;
427}
428
Brian Carlstrom7940e442013-07-12 13:46:57 -0700429} // namespace art