167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/*
267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Copyright (C) 2011 The Android Open Source Project
367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee *
467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Licensed under the Apache License, Version 2.0 (the "License");
567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * you may not use this file except in compliance with the License.
667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * You may obtain a copy of the License at
767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee *
867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee *      http://www.apache.org/licenses/LICENSE-2.0
967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee *
1067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Unless required by applicable law or agreed to in writing, software
1167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * distributed under the License is distributed on an "AS IS" BASIS,
1267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * See the License for the specific language governing permissions and
1467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * limitations under the License.
1567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */
1667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
170b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "mir_to_lir-inl.h"
180b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe
197940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/compiler_ir.h"
200b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "dex/mir_graph.h"
21265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#include "invoke_type.h"
221bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee
2311d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughesnamespace art {
2411d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes
25b046e16d8b8da318d6055f9308950131f1255e08buzbee/* This file contains target-independent codegen and support. */
2667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
2731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/*
2831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Load an immediate value into a fixed or temp register.  Target
29fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * register is clobbered, and marked in_use.
3031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */
312700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* Mir2Lir::LoadConstant(RegStorage r_dest, int value) {
321fd3346740dfb7f47be9922312b68a4227fada96buzbee  if (IsTemp(r_dest)) {
331fd3346740dfb7f47be9922312b68a4227fada96buzbee    Clobber(r_dest);
341fd3346740dfb7f47be9922312b68a4227fada96buzbee    MarkInUse(r_dest);
35a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
361fd3346740dfb7f47be9922312b68a4227fada96buzbee  return LoadConstantNoClobber(r_dest, value);
3731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
3867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
395f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee/*
4067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Load a Dalvik register into a physical register.  Take care when
4167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * using this routine, as it doesn't perform any bookkeeping regarding
4267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * register liveness.  That is the responsibility of the caller.
4367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */
442700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeevoid Mir2Lir::LoadValueDirect(RegLocation rl_src, RegStorage r_dest) {
453d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier  rl_src = rl_src.wide ? UpdateLocWide(rl_src) : UpdateLoc(rl_src);
46fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (rl_src.location == kLocPhysReg) {
472700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    OpRegCopy(r_dest, rl_src.reg);
481fd3346740dfb7f47be9922312b68a4227fada96buzbee  } else if (IsInexpensiveConstant(rl_src)) {
492cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    // On 64-bit targets, will sign extend.  Make sure constant reference is always null.
50695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    DCHECK(!rl_src.ref || (mir_graph_->ConstantValue(rl_src) == 0));
511fd3346740dfb7f47be9922312b68a4227fada96buzbee    LoadConstantNoClobber(r_dest, mir_graph_->ConstantValue(rl_src));
52a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
53fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    DCHECK((rl_src.location == kLocDalvikFrame) ||
54fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee           (rl_src.location == kLocCompilerTemp));
558dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
563d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier    OpSize op_size;
57695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    if (rl_src.ref) {
583d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier      op_size = kReference;
593d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier    } else if (rl_src.wide) {
603d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier      op_size = k64;
61695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    } else {
623d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier      op_size = k32;
63695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    }
643d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier    LoadBaseDisp(TargetPtrReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest, op_size, kNotVolatile);
65a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
6667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
6767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
6867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/*
6952a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee * Similar to LoadValueDirect, but clobbers and allocates the target
7067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * register.  Should be used when loading to a fixed register (for example,
7167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * loading arguments to an out of line call.
7267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */
732700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeevoid Mir2Lir::LoadValueDirectFixed(RegLocation rl_src, RegStorage r_dest) {
741fd3346740dfb7f47be9922312b68a4227fada96buzbee  Clobber(r_dest);
751fd3346740dfb7f47be9922312b68a4227fada96buzbee  MarkInUse(r_dest);
761fd3346740dfb7f47be9922312b68a4227fada96buzbee  LoadValueDirect(rl_src, r_dest);
7767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
7867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
7967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/*
8067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Load a Dalvik register pair into a physical register[s].  Take care when
8167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * using this routine, as it doesn't perform any bookkeeping regarding
8267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * register liveness.  That is the responsibility of the caller.
8367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */
842700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeevoid Mir2Lir::LoadValueDirectWide(RegLocation rl_src, RegStorage r_dest) {
851fd3346740dfb7f47be9922312b68a4227fada96buzbee  rl_src = UpdateLocWide(rl_src);
86fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (rl_src.location == kLocPhysReg) {
872700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    OpRegCopyWide(r_dest, rl_src.reg);
881fd3346740dfb7f47be9922312b68a4227fada96buzbee  } else if (IsInexpensiveConstant(rl_src)) {
892700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    LoadConstantWide(r_dest, mir_graph_->ConstantValueWide(rl_src));
90a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
91fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    DCHECK((rl_src.location == kLocDalvikFrame) ||
92fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee           (rl_src.location == kLocCompilerTemp));
938dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
94a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu    LoadBaseDisp(TargetPtrReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest, k64, kNotVolatile);
95a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
9667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
9767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
9867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/*
9952a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee * Similar to LoadValueDirect, but clobbers and allocates the target
10067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * registers.  Should be used when loading to a fixed registers (for example,
10167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * loading arguments to an out of line call.
10267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */
1032700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeevoid Mir2Lir::LoadValueDirectWideFixed(RegLocation rl_src, RegStorage r_dest) {
1042700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  Clobber(r_dest);
1052700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  MarkInUse(r_dest);
1062700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  LoadValueDirectWide(rl_src, r_dest);
10767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
10867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
1092ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation Mir2Lir::LoadValue(RegLocation rl_src, RegisterClass op_kind) {
110a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbee  DCHECK(!rl_src.ref || op_kind == kRefReg);
1110dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  rl_src = UpdateLoc(rl_src);
1120dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  if (rl_src.location == kLocPhysReg) {
1130dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko    if (!RegClassMatches(op_kind, rl_src.reg)) {
1140dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      // Wrong register class, realloc, copy and transfer ownership.
1150dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      RegStorage new_reg = AllocTypedTemp(rl_src.fp, op_kind);
1160dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      OpRegCopy(new_reg, rl_src.reg);
11702c637e8d6952aba19a432e01fc94cece5071e2fSerguei Katkov      // Clobber the old regs and free it.
1180dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      Clobber(rl_src.reg);
11902c637e8d6952aba19a432e01fc94cece5071e2fSerguei Katkov      FreeTemp(rl_src.reg);
120082833c8d577db0b2bebc100602f31e4e971613ebuzbee      // ...and mark the new one live.
1210dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      rl_src.reg = new_reg;
122082833c8d577db0b2bebc100602f31e4e971613ebuzbee      MarkLive(rl_src);
1230dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko    }
1240dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko    return rl_src;
125a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
1260dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko
1270dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  DCHECK_NE(rl_src.s_reg_low, INVALID_SREG);
1280dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  rl_src.reg = AllocTypedTemp(rl_src.fp, op_kind);
1290dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  LoadValueDirect(rl_src, rl_src.reg);
1300dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  rl_src.location = kLocPhysReg;
1310dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  MarkLive(rl_src);
132fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  return rl_src;
13367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
13467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
1352ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::StoreValue(RegLocation rl_dest, RegLocation rl_src) {
136a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /*
137a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * Sanity checking - should never try to store to the same
138a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * ssa name during the compilation of a single instruction
13952a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee   * without an intervening ClobberSReg().
140a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   */
141311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  if (kIsDebugBuild) {
1421fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK((live_sreg_ == INVALID_SREG) ||
1431fd3346740dfb7f47be9922312b68a4227fada96buzbee           (rl_dest.s_reg_low != live_sreg_));
1441fd3346740dfb7f47be9922312b68a4227fada96buzbee    live_sreg_ = rl_dest.s_reg_low;
145311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  }
146fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LIR* def_start;
147fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LIR* def_end;
148fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK(!rl_dest.wide);
149fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK(!rl_src.wide);
1501fd3346740dfb7f47be9922312b68a4227fada96buzbee  rl_src = UpdateLoc(rl_src);
1511fd3346740dfb7f47be9922312b68a4227fada96buzbee  rl_dest = UpdateLoc(rl_dest);
152fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (rl_src.location == kLocPhysReg) {
1532700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    if (IsLive(rl_src.reg) ||
1542700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      IsPromoted(rl_src.reg) ||
155fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      (rl_dest.location == kLocPhysReg)) {
156a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      // Src is live/promoted or Dest has assigned reg.
1574b537a851b686402513a7c4a4e60f5457bb8d7c1Andreas Gampe      rl_dest = EvalLoc(rl_dest, rl_dest.ref || rl_src.ref ? kRefReg : kAnyReg, false);
1582700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      OpRegCopy(rl_dest.reg, rl_src.reg);
15967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    } else {
160a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      // Just re-assign the registers.  Dest gets Src's regs
16100e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee      rl_dest.reg = rl_src.reg;
1622700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      Clobber(rl_src.reg);
16367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    }
164a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
165a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    // Load Src either into promoted Dest or temps allocated for Dest
1664b537a851b686402513a7c4a4e60f5457bb8d7c1Andreas Gampe    rl_dest = EvalLoc(rl_dest, rl_dest.ref ? kRefReg : kAnyReg, false);
1672700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    LoadValueDirect(rl_src, rl_dest.reg);
168a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
16967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
170a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  // Dest is now live and dirty (until/if we flush it to home location)
171091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  MarkLive(rl_dest);
1721fd3346740dfb7f47be9922312b68a4227fada96buzbee  MarkDirty(rl_dest);
17367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
17467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
1751fd3346740dfb7f47be9922312b68a4227fada96buzbee  ResetDefLoc(rl_dest);
176091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  if (IsDirty(rl_dest.reg) && LiveOut(rl_dest.s_reg_low)) {
1771fd3346740dfb7f47be9922312b68a4227fada96buzbee    def_start = last_lir_insn_;
178e98297bafe84e2ac15eb73739f27826fcaae1203Ian Rogers    ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
1792073e7553d1ca65f13b6c4e4fe364c2a345a1511Andreas Gampe    if (rl_dest.ref) {
180a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu      StoreRefDisp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg, kNotVolatile);
1812073e7553d1ca65f13b6c4e4fe364c2a345a1511Andreas Gampe    } else {
182a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu      Store32Disp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg);
1832073e7553d1ca65f13b6c4e4fe364c2a345a1511Andreas Gampe    }
1841fd3346740dfb7f47be9922312b68a4227fada96buzbee    MarkClean(rl_dest);
1851fd3346740dfb7f47be9922312b68a4227fada96buzbee    def_end = last_lir_insn_;
1865f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee    if (!rl_dest.ref) {
1875f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee      // Exclude references from store elimination
1881fd3346740dfb7f47be9922312b68a4227fada96buzbee      MarkDef(rl_dest, def_start, def_end);
1895f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee    }
190a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
19167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
19267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
1932ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation Mir2Lir::LoadValueWide(RegLocation rl_src, RegisterClass op_kind) {
194fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK(rl_src.wide);
1950dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  rl_src = UpdateLocWide(rl_src);
1960dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  if (rl_src.location == kLocPhysReg) {
1970dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko    if (!RegClassMatches(op_kind, rl_src.reg)) {
1980dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      // Wrong register class, realloc, copy and transfer ownership.
1990dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      RegStorage new_regs = AllocTypedTempWide(rl_src.fp, op_kind);
2000dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      OpRegCopyWide(new_regs, rl_src.reg);
20102c637e8d6952aba19a432e01fc94cece5071e2fSerguei Katkov      // Clobber the old regs and free it.
2020dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      Clobber(rl_src.reg);
20302c637e8d6952aba19a432e01fc94cece5071e2fSerguei Katkov      FreeTemp(rl_src.reg);
204082833c8d577db0b2bebc100602f31e4e971613ebuzbee      // ...and mark the new ones live.
2050dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      rl_src.reg = new_regs;
206082833c8d577db0b2bebc100602f31e4e971613ebuzbee      MarkLive(rl_src);
2070dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko    }
2080dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko    return rl_src;
209a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
2100dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko
2110dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  DCHECK_NE(rl_src.s_reg_low, INVALID_SREG);
2120dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  DCHECK_NE(GetSRegHi(rl_src.s_reg_low), INVALID_SREG);
2130dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  rl_src.reg = AllocTypedTempWide(rl_src.fp, op_kind);
2140dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  LoadValueDirectWide(rl_src, rl_src.reg);
2150dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  rl_src.location = kLocPhysReg;
2160dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  MarkLive(rl_src);
217fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  return rl_src;
21867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
21967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
2202ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::StoreValueWide(RegLocation rl_dest, RegLocation rl_src) {
221a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /*
222a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * Sanity checking - should never try to store to the same
223a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * ssa name during the compilation of a single instruction
22452a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee   * without an intervening ClobberSReg().
225a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   */
226311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  if (kIsDebugBuild) {
2271fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK((live_sreg_ == INVALID_SREG) ||
2281fd3346740dfb7f47be9922312b68a4227fada96buzbee           (rl_dest.s_reg_low != live_sreg_));
2291fd3346740dfb7f47be9922312b68a4227fada96buzbee    live_sreg_ = rl_dest.s_reg_low;
230311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  }
231fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LIR* def_start;
232fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LIR* def_end;
233fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK(rl_dest.wide);
234fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK(rl_src.wide);
235c17ebe866beb50eb6da1e6a47555cb4731467f3bAlexei Zavjalov  rl_src = UpdateLocWide(rl_src);
236c17ebe866beb50eb6da1e6a47555cb4731467f3bAlexei Zavjalov  rl_dest = UpdateLocWide(rl_dest);
237fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (rl_src.location == kLocPhysReg) {
2382700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    if (IsLive(rl_src.reg) ||
2392700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee        IsPromoted(rl_src.reg) ||
240fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        (rl_dest.location == kLocPhysReg)) {
24130adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee      /*
24230adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee       * If src reg[s] are tied to the original Dalvik vreg via liveness or promotion, we
24330adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee       * can't repurpose them.  Similarly, if the dest reg[s] are tied to Dalvik vregs via
24430adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee       * promotion, we can't just re-assign.  In these cases, we have to copy.
24530adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee       */
2461fd3346740dfb7f47be9922312b68a4227fada96buzbee      rl_dest = EvalLoc(rl_dest, kAnyReg, false);
2472700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      OpRegCopyWide(rl_dest.reg, rl_src.reg);
24867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    } else {
249a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      // Just re-assign the registers.  Dest gets Src's regs
25000e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee      rl_dest.reg = rl_src.reg;
2512700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      Clobber(rl_src.reg);
25267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    }
253a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
254a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    // Load Src either into promoted Dest or temps allocated for Dest
2551fd3346740dfb7f47be9922312b68a4227fada96buzbee    rl_dest = EvalLoc(rl_dest, kAnyReg, false);
2562700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    LoadValueDirectWide(rl_src, rl_dest.reg);
257a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
25867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
259a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  // Dest is now live and dirty (until/if we flush it to home location)
260091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  MarkLive(rl_dest);
261091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  MarkWide(rl_dest.reg);
262091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  MarkDirty(rl_dest);
26367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
2641fd3346740dfb7f47be9922312b68a4227fada96buzbee  ResetDefLocWide(rl_dest);
265091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  if (IsDirty(rl_dest.reg) && (LiveOut(rl_dest.s_reg_low) ||
266091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      LiveOut(GetSRegHi(rl_dest.s_reg_low)))) {
2671fd3346740dfb7f47be9922312b68a4227fada96buzbee    def_start = last_lir_insn_;
2681fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK_EQ((mir_graph_->SRegToVReg(rl_dest.s_reg_low)+1),
2691fd3346740dfb7f47be9922312b68a4227fada96buzbee              mir_graph_->SRegToVReg(GetSRegHi(rl_dest.s_reg_low)));
2708dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
271a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu    StoreBaseDisp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg, k64, kNotVolatile);
2721fd3346740dfb7f47be9922312b68a4227fada96buzbee    MarkClean(rl_dest);
2731fd3346740dfb7f47be9922312b68a4227fada96buzbee    def_end = last_lir_insn_;
2741fd3346740dfb7f47be9922312b68a4227fada96buzbee    MarkDefWide(rl_dest, def_start, def_end);
275a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
27667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
27711d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes
278feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendellvoid Mir2Lir::StoreFinalValue(RegLocation rl_dest, RegLocation rl_src) {
279feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  DCHECK_EQ(rl_src.location, kLocPhysReg);
280feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell
281feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  if (rl_dest.location == kLocPhysReg) {
2822700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    OpRegCopy(rl_dest.reg, rl_src.reg);
283feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  } else {
284feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    // Just re-assign the register.  Dest gets Src's reg.
285feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    rl_dest.location = kLocPhysReg;
28600e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee    rl_dest.reg = rl_src.reg;
2872700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    Clobber(rl_src.reg);
288feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  }
289feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell
290feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  // Dest is now live and dirty (until/if we flush it to home location)
291091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  MarkLive(rl_dest);
292feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  MarkDirty(rl_dest);
293feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell
294feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell
295feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  ResetDefLoc(rl_dest);
296091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  if (IsDirty(rl_dest.reg) && LiveOut(rl_dest.s_reg_low)) {
297feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    LIR *def_start = last_lir_insn_;
2988dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
299a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu    Store32Disp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg);
300feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    MarkClean(rl_dest);
301feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    LIR *def_end = last_lir_insn_;
302feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    if (!rl_dest.ref) {
303feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell      // Exclude references from store elimination
304feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell      MarkDef(rl_dest, def_start, def_end);
305feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    }
306feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  }
307feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell}
308feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell
309e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendellvoid Mir2Lir::StoreFinalValueWide(RegLocation rl_dest, RegLocation rl_src) {
310e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  DCHECK(rl_dest.wide);
311e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  DCHECK(rl_src.wide);
312e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  DCHECK_EQ(rl_src.location, kLocPhysReg);
313e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell
314e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  if (rl_dest.location == kLocPhysReg) {
3152700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    OpRegCopyWide(rl_dest.reg, rl_src.reg);
316e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  } else {
317e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell    // Just re-assign the registers.  Dest gets Src's regs.
318e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell    rl_dest.location = kLocPhysReg;
31900e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee    rl_dest.reg = rl_src.reg;
320091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee    Clobber(rl_src.reg);
321e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  }
322e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell
323e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  // Dest is now live and dirty (until/if we flush it to home location).
324091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  MarkLive(rl_dest);
325091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  MarkWide(rl_dest.reg);
326091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  MarkDirty(rl_dest);
327e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell
328e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  ResetDefLocWide(rl_dest);
329091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  if (IsDirty(rl_dest.reg) && (LiveOut(rl_dest.s_reg_low) ||
330091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      LiveOut(GetSRegHi(rl_dest.s_reg_low)))) {
331e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell    LIR *def_start = last_lir_insn_;
332e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell    DCHECK_EQ((mir_graph_->SRegToVReg(rl_dest.s_reg_low)+1),
333e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell              mir_graph_->SRegToVReg(GetSRegHi(rl_dest.s_reg_low)));
3348dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
335a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu    StoreBaseDisp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg, k64, kNotVolatile);
336e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell    MarkClean(rl_dest);
337e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell    LIR *def_end = last_lir_insn_;
338e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell    MarkDefWide(rl_dest, def_start, def_end);
339e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  }
340e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell}
341e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell
342e196567b50a084b163937ea9605b51ee1e48adebbuzbee/* Utilities to load the current Method* */
3432700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeevoid Mir2Lir::LoadCurrMethodDirect(RegStorage r_tgt) {
3443d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier  if (GetCompilationUnit()->target64) {
3453d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier    LoadValueDirectWideFixed(mir_graph_->GetMethodLoc(), r_tgt);
3463d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier  } else {
3473d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier    LoadValueDirectFixed(mir_graph_->GetMethodLoc(), r_tgt);
3483d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier  }
34931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
35031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
35120f85597828194c12be10d3a927999def066555eVladimir MarkoRegStorage Mir2Lir::LoadCurrMethodWithHint(RegStorage r_hint) {
35220f85597828194c12be10d3a927999def066555eVladimir Marko  // If the method is promoted to a register, return that register, otherwise load it to r_hint.
35320f85597828194c12be10d3a927999def066555eVladimir Marko  // (Replacement for LoadCurrMethod() usually used when LockCallTemps() is in effect.)
35420f85597828194c12be10d3a927999def066555eVladimir Marko  DCHECK(r_hint.Valid());
35520f85597828194c12be10d3a927999def066555eVladimir Marko  RegLocation rl_method = mir_graph_->GetMethodLoc();
35620f85597828194c12be10d3a927999def066555eVladimir Marko  if (rl_method.location == kLocPhysReg) {
35720f85597828194c12be10d3a927999def066555eVladimir Marko    DCHECK(!IsTemp(rl_method.reg));
35820f85597828194c12be10d3a927999def066555eVladimir Marko    return rl_method.reg;
35920f85597828194c12be10d3a927999def066555eVladimir Marko  } else {
36020f85597828194c12be10d3a927999def066555eVladimir Marko    LoadCurrMethodDirect(r_hint);
36120f85597828194c12be10d3a927999def066555eVladimir Marko    return r_hint;
36220f85597828194c12be10d3a927999def066555eVladimir Marko  }
36320f85597828194c12be10d3a927999def066555eVladimir Marko}
36420f85597828194c12be10d3a927999def066555eVladimir Marko
3652ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation Mir2Lir::LoadCurrMethod() {
3663d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier  return GetCompilationUnit()->target64 ?
3673d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier      LoadValueWide(mir_graph_->GetMethodLoc(), kCoreReg) :
3683d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier      LoadValue(mir_graph_->GetMethodLoc(), kRefReg);
36931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
37031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
371e02d48fb24747f90fd893e1c3572bb3c500afcedMark MendellRegLocation Mir2Lir::ForceTemp(RegLocation loc) {
372e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  DCHECK(!loc.wide);
373e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  DCHECK(loc.location == kLocPhysReg);
374091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  DCHECK(!loc.reg.IsFloat());
3752700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  if (IsTemp(loc.reg)) {
3762700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    Clobber(loc.reg);
377e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  } else {
3782700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    RegStorage temp_low = AllocTemp();
3792700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    OpRegCopy(temp_low, loc.reg);
3802700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    loc.reg = temp_low;
381e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  }
382e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell
383e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  // Ensure that this doesn't represent the original SR any more.
384e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  loc.s_reg_low = INVALID_SREG;
385e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  return loc;
386e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell}
387e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell
388e02d48fb24747f90fd893e1c3572bb3c500afcedMark MendellRegLocation Mir2Lir::ForceTempWide(RegLocation loc) {
389e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  DCHECK(loc.wide);
390e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  DCHECK(loc.location == kLocPhysReg);
391091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  DCHECK(!loc.reg.IsFloat());
392e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu
393e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu  if (!loc.reg.IsPair()) {
394e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    if (IsTemp(loc.reg)) {
395e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      Clobber(loc.reg);
396e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    } else {
397e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      RegStorage temp = AllocTempWide();
398e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      OpRegCopy(temp, loc.reg);
399e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      loc.reg = temp;
400e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    }
401e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  } else {
402e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    if (IsTemp(loc.reg.GetLow())) {
403e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      Clobber(loc.reg.GetLow());
404e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    } else {
405e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      RegStorage temp_low = AllocTemp();
406e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      OpRegCopy(temp_low, loc.reg.GetLow());
407e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      loc.reg.SetLowReg(temp_low.GetReg());
408e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    }
409e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    if (IsTemp(loc.reg.GetHigh())) {
410e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      Clobber(loc.reg.GetHigh());
411e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    } else {
412e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      RegStorage temp_high = AllocTemp();
413e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      OpRegCopy(temp_high, loc.reg.GetHigh());
414e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      loc.reg.SetHighReg(temp_high.GetReg());
415e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    }
416e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  }
417e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell
418e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  // Ensure that this doesn't represent the original SR any more.
419e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  loc.s_reg_low = INVALID_SREG;
420e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  return loc;
421e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell}
422e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell
42311d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes}  // namespace art
424