gen_loadstore.cc revision 2073e7553d1ca65f13b6c4e4fe364c2a345a1511
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
177940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/compiler_ir.h"
187940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/compiler_internals.h"
197940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/quick/mir_to_lir-inl.h"
20265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#include "invoke_type.h"
211bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee
2211d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughesnamespace art {
2311d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes
24b046e16d8b8da318d6055f9308950131f1255e08buzbee/* This file contains target-independent codegen and support. */
2567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
2631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/*
2731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Load an immediate value into a fixed or temp register.  Target
28fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * register is clobbered, and marked in_use.
2931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */
302700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* Mir2Lir::LoadConstant(RegStorage r_dest, int value) {
311fd3346740dfb7f47be9922312b68a4227fada96buzbee  if (IsTemp(r_dest)) {
321fd3346740dfb7f47be9922312b68a4227fada96buzbee    Clobber(r_dest);
331fd3346740dfb7f47be9922312b68a4227fada96buzbee    MarkInUse(r_dest);
34a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
351fd3346740dfb7f47be9922312b68a4227fada96buzbee  return LoadConstantNoClobber(r_dest, value);
3631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
3767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
385f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee/*
395f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee * Temporary workaround for Issue 7250540.  If we're loading a constant zero into a
405f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee * promoted floating point register, also copy a zero into the int/ref identity of
415f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee * that sreg.
425f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee */
432700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeevoid Mir2Lir::Workaround7250540(RegLocation rl_dest, RegStorage zero_reg) {
447da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee  if (rl_dest.fp) {
451fd3346740dfb7f47be9922312b68a4227fada96buzbee    int pmap_index = SRegToPMap(rl_dest.s_reg_low);
461fd3346740dfb7f47be9922312b68a4227fada96buzbee    if (promotion_map_[pmap_index].fp_location == kLocPhysReg) {
477da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee      // Now, determine if this vreg is ever used as a reference.  If not, we're done.
481fd3346740dfb7f47be9922312b68a4227fada96buzbee      bool used_as_reference = false;
491fd3346740dfb7f47be9922312b68a4227fada96buzbee      int base_vreg = mir_graph_->SRegToVReg(rl_dest.s_reg_low);
501fd3346740dfb7f47be9922312b68a4227fada96buzbee      for (int i = 0; !used_as_reference && (i < mir_graph_->GetNumSSARegs()); i++) {
511fd3346740dfb7f47be9922312b68a4227fada96buzbee        if (mir_graph_->SRegToVReg(mir_graph_->reg_location_[i].s_reg_low) == base_vreg) {
521fd3346740dfb7f47be9922312b68a4227fada96buzbee          used_as_reference |= mir_graph_->reg_location_[i].ref;
537da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee        }
547da142fc1cefeeb24d997ae21b34381fdd2c0466buzbee      }
551fd3346740dfb7f47be9922312b68a4227fada96buzbee      if (!used_as_reference) {
561fd3346740dfb7f47be9922312b68a4227fada96buzbee        return;
571fd3346740dfb7f47be9922312b68a4227fada96buzbee      }
582700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      RegStorage temp_reg = zero_reg;
592700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      if (!temp_reg.Valid()) {
601fd3346740dfb7f47be9922312b68a4227fada96buzbee        temp_reg = AllocTemp();
611fd3346740dfb7f47be9922312b68a4227fada96buzbee        LoadConstant(temp_reg, 0);
624ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      }
631fd3346740dfb7f47be9922312b68a4227fada96buzbee      if (promotion_map_[pmap_index].core_location == kLocPhysReg) {
645f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee        // Promoted - just copy in a zero
652700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee        OpRegCopy(RegStorage::Solo32(promotion_map_[pmap_index].core_reg), temp_reg);
665f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee      } else {
675f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee        // Lives in the frame, need to store.
688dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko        ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
69695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee        StoreBaseDisp(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low), temp_reg, k32);
704ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      }
712700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      if (!zero_reg.Valid()) {
721fd3346740dfb7f47be9922312b68a4227fada96buzbee        FreeTemp(temp_reg);
735f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee      }
745f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee    }
755f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee  }
765f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee}
775f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee
7867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/*
7967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Load a Dalvik register into a physical register.  Take care when
8067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * using this routine, as it doesn't perform any bookkeeping regarding
8167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * register liveness.  That is the responsibility of the caller.
8267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */
832700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeevoid Mir2Lir::LoadValueDirect(RegLocation rl_src, RegStorage r_dest) {
841fd3346740dfb7f47be9922312b68a4227fada96buzbee  rl_src = UpdateLoc(rl_src);
85fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (rl_src.location == kLocPhysReg) {
862700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    OpRegCopy(r_dest, rl_src.reg);
871fd3346740dfb7f47be9922312b68a4227fada96buzbee  } else if (IsInexpensiveConstant(rl_src)) {
88695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    // On 64-bit targets, will sign extend.  Make sure constant reference is always NULL.
89695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    DCHECK(!rl_src.ref || (mir_graph_->ConstantValue(rl_src) == 0));
901fd3346740dfb7f47be9922312b68a4227fada96buzbee    LoadConstantNoClobber(r_dest, mir_graph_->ConstantValue(rl_src));
91a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
92fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    DCHECK((rl_src.location == kLocDalvikFrame) ||
93fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee           (rl_src.location == kLocCompilerTemp));
948dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
95695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    if (rl_src.ref) {
96695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee      LoadRefDisp(TargetReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest);
97695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    } else {
98695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee      Load32Disp(TargetReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest);
99695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    }
100a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
10167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
10267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
10367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/*
10452a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee * Similar to LoadValueDirect, but clobbers and allocates the target
10567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * register.  Should be used when loading to a fixed register (for example,
10667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * loading arguments to an out of line call.
10767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */
1082700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeevoid Mir2Lir::LoadValueDirectFixed(RegLocation rl_src, RegStorage r_dest) {
1091fd3346740dfb7f47be9922312b68a4227fada96buzbee  Clobber(r_dest);
1101fd3346740dfb7f47be9922312b68a4227fada96buzbee  MarkInUse(r_dest);
1111fd3346740dfb7f47be9922312b68a4227fada96buzbee  LoadValueDirect(rl_src, r_dest);
11267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
11367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
11467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/*
11567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Load a Dalvik register pair into a physical register[s].  Take care when
11667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * using this routine, as it doesn't perform any bookkeeping regarding
11767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * register liveness.  That is the responsibility of the caller.
11867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */
1192700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeevoid Mir2Lir::LoadValueDirectWide(RegLocation rl_src, RegStorage r_dest) {
1201fd3346740dfb7f47be9922312b68a4227fada96buzbee  rl_src = UpdateLocWide(rl_src);
121fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (rl_src.location == kLocPhysReg) {
1222700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    OpRegCopyWide(r_dest, rl_src.reg);
1231fd3346740dfb7f47be9922312b68a4227fada96buzbee  } else if (IsInexpensiveConstant(rl_src)) {
1242700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    LoadConstantWide(r_dest, mir_graph_->ConstantValueWide(rl_src));
125a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
126fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    DCHECK((rl_src.location == kLocDalvikFrame) ||
127fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee           (rl_src.location == kLocCompilerTemp));
1288dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
1293bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko    LoadBaseDisp(TargetReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest, k64);
130a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
13167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
13267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
13367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/*
13452a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee * Similar to LoadValueDirect, but clobbers and allocates the target
13567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * registers.  Should be used when loading to a fixed registers (for example,
13667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * loading arguments to an out of line call.
13767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */
1382700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeevoid Mir2Lir::LoadValueDirectWideFixed(RegLocation rl_src, RegStorage r_dest) {
1392700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  Clobber(r_dest);
1402700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  MarkInUse(r_dest);
1412700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  LoadValueDirectWide(rl_src, r_dest);
14267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
14367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
1442ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation Mir2Lir::LoadValue(RegLocation rl_src, RegisterClass op_kind) {
145a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbee  DCHECK(!rl_src.ref || op_kind == kRefReg);
1460dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  rl_src = UpdateLoc(rl_src);
1470dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  if (rl_src.location == kLocPhysReg) {
1480dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko    if (!RegClassMatches(op_kind, rl_src.reg)) {
1490dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      // Wrong register class, realloc, copy and transfer ownership.
1500dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      RegStorage new_reg = AllocTypedTemp(rl_src.fp, op_kind);
1510dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      OpRegCopy(new_reg, rl_src.reg);
152082833c8d577db0b2bebc100602f31e4e971613ebuzbee      // Clobber the old reg.
1530dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      Clobber(rl_src.reg);
154082833c8d577db0b2bebc100602f31e4e971613ebuzbee      // ...and mark the new one live.
1550dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      rl_src.reg = new_reg;
156082833c8d577db0b2bebc100602f31e4e971613ebuzbee      MarkLive(rl_src);
1570dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko    }
1580dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko    return rl_src;
159a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
1600dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko
1610dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  DCHECK_NE(rl_src.s_reg_low, INVALID_SREG);
1620dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  rl_src.reg = AllocTypedTemp(rl_src.fp, op_kind);
1630dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  LoadValueDirect(rl_src, rl_src.reg);
1640dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  rl_src.location = kLocPhysReg;
1650dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  MarkLive(rl_src);
166fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  return rl_src;
16767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
16867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
169a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbeeRegLocation Mir2Lir::LoadValue(RegLocation rl_src) {
170a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbee  return LoadValue(rl_src, LocToRegClass(rl_src));
171a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbee}
172a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbee
1732ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::StoreValue(RegLocation rl_dest, RegLocation rl_src) {
174a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /*
175a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * Sanity checking - should never try to store to the same
176a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * ssa name during the compilation of a single instruction
17752a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee   * without an intervening ClobberSReg().
178a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   */
179311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  if (kIsDebugBuild) {
1801fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK((live_sreg_ == INVALID_SREG) ||
1811fd3346740dfb7f47be9922312b68a4227fada96buzbee           (rl_dest.s_reg_low != live_sreg_));
1821fd3346740dfb7f47be9922312b68a4227fada96buzbee    live_sreg_ = rl_dest.s_reg_low;
183311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  }
184fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LIR* def_start;
185fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LIR* def_end;
186fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK(!rl_dest.wide);
187fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK(!rl_src.wide);
1881fd3346740dfb7f47be9922312b68a4227fada96buzbee  rl_src = UpdateLoc(rl_src);
1891fd3346740dfb7f47be9922312b68a4227fada96buzbee  rl_dest = UpdateLoc(rl_dest);
190fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (rl_src.location == kLocPhysReg) {
1912700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    if (IsLive(rl_src.reg) ||
1922700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      IsPromoted(rl_src.reg) ||
193fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      (rl_dest.location == kLocPhysReg)) {
194a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      // Src is live/promoted or Dest has assigned reg.
1951fd3346740dfb7f47be9922312b68a4227fada96buzbee      rl_dest = EvalLoc(rl_dest, kAnyReg, false);
1962700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      OpRegCopy(rl_dest.reg, rl_src.reg);
19767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    } else {
198a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      // Just re-assign the registers.  Dest gets Src's regs
19900e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee      rl_dest.reg = rl_src.reg;
2002700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      Clobber(rl_src.reg);
20167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    }
202a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
203a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    // Load Src either into promoted Dest or temps allocated for Dest
2041fd3346740dfb7f47be9922312b68a4227fada96buzbee    rl_dest = EvalLoc(rl_dest, kAnyReg, false);
2052700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    LoadValueDirect(rl_src, rl_dest.reg);
206a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
20767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
208a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  // Dest is now live and dirty (until/if we flush it to home location)
209091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  MarkLive(rl_dest);
2101fd3346740dfb7f47be9922312b68a4227fada96buzbee  MarkDirty(rl_dest);
21167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
21267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
2131fd3346740dfb7f47be9922312b68a4227fada96buzbee  ResetDefLoc(rl_dest);
214091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  if (IsDirty(rl_dest.reg) && LiveOut(rl_dest.s_reg_low)) {
2151fd3346740dfb7f47be9922312b68a4227fada96buzbee    def_start = last_lir_insn_;
216e98297bafe84e2ac15eb73739f27826fcaae1203Ian Rogers    ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
2172073e7553d1ca65f13b6c4e4fe364c2a345a1511Andreas Gampe    if (rl_dest.ref) {
2182073e7553d1ca65f13b6c4e4fe364c2a345a1511Andreas Gampe      StoreRefDisp(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg);
2192073e7553d1ca65f13b6c4e4fe364c2a345a1511Andreas Gampe    } else {
2202073e7553d1ca65f13b6c4e4fe364c2a345a1511Andreas Gampe      Store32Disp(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg);
2212073e7553d1ca65f13b6c4e4fe364c2a345a1511Andreas Gampe    }
2221fd3346740dfb7f47be9922312b68a4227fada96buzbee    MarkClean(rl_dest);
2231fd3346740dfb7f47be9922312b68a4227fada96buzbee    def_end = last_lir_insn_;
2245f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee    if (!rl_dest.ref) {
2255f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee      // Exclude references from store elimination
2261fd3346740dfb7f47be9922312b68a4227fada96buzbee      MarkDef(rl_dest, def_start, def_end);
2275f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee    }
228a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
22967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
23067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
2312ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation Mir2Lir::LoadValueWide(RegLocation rl_src, RegisterClass op_kind) {
232fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK(rl_src.wide);
2330dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  rl_src = UpdateLocWide(rl_src);
2340dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  if (rl_src.location == kLocPhysReg) {
2350dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko    if (!RegClassMatches(op_kind, rl_src.reg)) {
2360dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      // Wrong register class, realloc, copy and transfer ownership.
2370dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      RegStorage new_regs = AllocTypedTempWide(rl_src.fp, op_kind);
2380dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      OpRegCopyWide(new_regs, rl_src.reg);
239082833c8d577db0b2bebc100602f31e4e971613ebuzbee      // Clobber the old regs.
2400dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      Clobber(rl_src.reg);
241082833c8d577db0b2bebc100602f31e4e971613ebuzbee      // ...and mark the new ones live.
2420dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko      rl_src.reg = new_regs;
243082833c8d577db0b2bebc100602f31e4e971613ebuzbee      MarkLive(rl_src);
2440dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko    }
2450dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko    return rl_src;
246a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
2470dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko
2480dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  DCHECK_NE(rl_src.s_reg_low, INVALID_SREG);
2490dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  DCHECK_NE(GetSRegHi(rl_src.s_reg_low), INVALID_SREG);
2500dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  rl_src.reg = AllocTypedTempWide(rl_src.fp, op_kind);
2510dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  LoadValueDirectWide(rl_src, rl_src.reg);
2520dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  rl_src.location = kLocPhysReg;
2530dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko  MarkLive(rl_src);
254fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  return rl_src;
25567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
25667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
2572ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::StoreValueWide(RegLocation rl_dest, RegLocation rl_src) {
258a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /*
259a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * Sanity checking - should never try to store to the same
260a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * ssa name during the compilation of a single instruction
26152a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee   * without an intervening ClobberSReg().
262a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   */
263311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  if (kIsDebugBuild) {
2641fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK((live_sreg_ == INVALID_SREG) ||
2651fd3346740dfb7f47be9922312b68a4227fada96buzbee           (rl_dest.s_reg_low != live_sreg_));
2661fd3346740dfb7f47be9922312b68a4227fada96buzbee    live_sreg_ = rl_dest.s_reg_low;
267311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  }
268fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LIR* def_start;
269fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LIR* def_end;
270fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK(rl_dest.wide);
271fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK(rl_src.wide);
272c17ebe866beb50eb6da1e6a47555cb4731467f3bAlexei Zavjalov  rl_src = UpdateLocWide(rl_src);
273c17ebe866beb50eb6da1e6a47555cb4731467f3bAlexei Zavjalov  rl_dest = UpdateLocWide(rl_dest);
274fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (rl_src.location == kLocPhysReg) {
2752700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    if (IsLive(rl_src.reg) ||
2762700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee        IsPromoted(rl_src.reg) ||
277fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        (rl_dest.location == kLocPhysReg)) {
27830adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee      /*
27930adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee       * If src reg[s] are tied to the original Dalvik vreg via liveness or promotion, we
28030adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee       * can't repurpose them.  Similarly, if the dest reg[s] are tied to Dalvik vregs via
28130adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee       * promotion, we can't just re-assign.  In these cases, we have to copy.
28230adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee       */
2831fd3346740dfb7f47be9922312b68a4227fada96buzbee      rl_dest = EvalLoc(rl_dest, kAnyReg, false);
2842700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      OpRegCopyWide(rl_dest.reg, rl_src.reg);
28567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    } else {
286a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      // Just re-assign the registers.  Dest gets Src's regs
28700e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee      rl_dest.reg = rl_src.reg;
2882700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      Clobber(rl_src.reg);
28967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    }
290a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
291a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    // Load Src either into promoted Dest or temps allocated for Dest
2921fd3346740dfb7f47be9922312b68a4227fada96buzbee    rl_dest = EvalLoc(rl_dest, kAnyReg, false);
2932700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    LoadValueDirectWide(rl_src, rl_dest.reg);
294a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
29567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
296a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  // Dest is now live and dirty (until/if we flush it to home location)
297091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  MarkLive(rl_dest);
298091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  MarkWide(rl_dest.reg);
299091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  MarkDirty(rl_dest);
30067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
3011fd3346740dfb7f47be9922312b68a4227fada96buzbee  ResetDefLocWide(rl_dest);
302091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  if (IsDirty(rl_dest.reg) && (LiveOut(rl_dest.s_reg_low) ||
303091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      LiveOut(GetSRegHi(rl_dest.s_reg_low)))) {
3041fd3346740dfb7f47be9922312b68a4227fada96buzbee    def_start = last_lir_insn_;
3051fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK_EQ((mir_graph_->SRegToVReg(rl_dest.s_reg_low)+1),
3061fd3346740dfb7f47be9922312b68a4227fada96buzbee              mir_graph_->SRegToVReg(GetSRegHi(rl_dest.s_reg_low)));
3078dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
308455759b5702b9435b91d1b4dada22c4cce7cae3cVladimir Marko    StoreBaseDisp(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg, k64);
3091fd3346740dfb7f47be9922312b68a4227fada96buzbee    MarkClean(rl_dest);
3101fd3346740dfb7f47be9922312b68a4227fada96buzbee    def_end = last_lir_insn_;
3111fd3346740dfb7f47be9922312b68a4227fada96buzbee    MarkDefWide(rl_dest, def_start, def_end);
312a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
31367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
31411d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes
315feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendellvoid Mir2Lir::StoreFinalValue(RegLocation rl_dest, RegLocation rl_src) {
316feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  DCHECK_EQ(rl_src.location, kLocPhysReg);
317feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell
318feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  if (rl_dest.location == kLocPhysReg) {
3192700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    OpRegCopy(rl_dest.reg, rl_src.reg);
320feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  } else {
321feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    // Just re-assign the register.  Dest gets Src's reg.
322feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    rl_dest.location = kLocPhysReg;
32300e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee    rl_dest.reg = rl_src.reg;
3242700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    Clobber(rl_src.reg);
325feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  }
326feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell
327feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  // Dest is now live and dirty (until/if we flush it to home location)
328091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  MarkLive(rl_dest);
329feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  MarkDirty(rl_dest);
330feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell
331feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell
332feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  ResetDefLoc(rl_dest);
333091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  if (IsDirty(rl_dest.reg) && LiveOut(rl_dest.s_reg_low)) {
334feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    LIR *def_start = last_lir_insn_;
3358dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
336695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    Store32Disp(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg);
337feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    MarkClean(rl_dest);
338feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    LIR *def_end = last_lir_insn_;
339feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    if (!rl_dest.ref) {
340feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell      // Exclude references from store elimination
341feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell      MarkDef(rl_dest, def_start, def_end);
342feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    }
343feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  }
344feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell}
345feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell
346e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendellvoid Mir2Lir::StoreFinalValueWide(RegLocation rl_dest, RegLocation rl_src) {
347e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  DCHECK(rl_dest.wide);
348e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  DCHECK(rl_src.wide);
349e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  DCHECK_EQ(rl_src.location, kLocPhysReg);
350e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell
351e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  if (rl_dest.location == kLocPhysReg) {
3522700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    OpRegCopyWide(rl_dest.reg, rl_src.reg);
353e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  } else {
354e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell    // Just re-assign the registers.  Dest gets Src's regs.
355e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell    rl_dest.location = kLocPhysReg;
35600e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee    rl_dest.reg = rl_src.reg;
357091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee    Clobber(rl_src.reg);
358e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  }
359e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell
360e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  // Dest is now live and dirty (until/if we flush it to home location).
361091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  MarkLive(rl_dest);
362091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  MarkWide(rl_dest.reg);
363091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  MarkDirty(rl_dest);
364e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell
365e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  ResetDefLocWide(rl_dest);
366091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  if (IsDirty(rl_dest.reg) && (LiveOut(rl_dest.s_reg_low) ||
367091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      LiveOut(GetSRegHi(rl_dest.s_reg_low)))) {
368e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell    LIR *def_start = last_lir_insn_;
369e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell    DCHECK_EQ((mir_graph_->SRegToVReg(rl_dest.s_reg_low)+1),
370e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell              mir_graph_->SRegToVReg(GetSRegHi(rl_dest.s_reg_low)));
3718dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg);
372455759b5702b9435b91d1b4dada22c4cce7cae3cVladimir Marko    StoreBaseDisp(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg, k64);
373e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell    MarkClean(rl_dest);
374e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell    LIR *def_end = last_lir_insn_;
375e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell    MarkDefWide(rl_dest, def_start, def_end);
376e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  }
377e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell}
378e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell
379e196567b50a084b163937ea9605b51ee1e48adebbuzbee/* Utilities to load the current Method* */
3802700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeevoid Mir2Lir::LoadCurrMethodDirect(RegStorage r_tgt) {
3811fd3346740dfb7f47be9922312b68a4227fada96buzbee  LoadValueDirectFixed(mir_graph_->GetMethodLoc(), r_tgt);
38231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
38331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
3842ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation Mir2Lir::LoadCurrMethod() {
385a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbee  return LoadValue(mir_graph_->GetMethodLoc(), kRefReg);
38631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
38731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
388e02d48fb24747f90fd893e1c3572bb3c500afcedMark MendellRegLocation Mir2Lir::ForceTemp(RegLocation loc) {
389e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  DCHECK(!loc.wide);
390e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  DCHECK(loc.location == kLocPhysReg);
391091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  DCHECK(!loc.reg.IsFloat());
3922700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  if (IsTemp(loc.reg)) {
3932700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    Clobber(loc.reg);
394e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  } else {
3952700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    RegStorage temp_low = AllocTemp();
3962700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    OpRegCopy(temp_low, loc.reg);
3972700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    loc.reg = temp_low;
398e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  }
399e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell
400e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  // Ensure that this doesn't represent the original SR any more.
401e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  loc.s_reg_low = INVALID_SREG;
402e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  return loc;
403e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell}
404e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell
405e02d48fb24747f90fd893e1c3572bb3c500afcedMark MendellRegLocation Mir2Lir::ForceTempWide(RegLocation loc) {
406e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  DCHECK(loc.wide);
407e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  DCHECK(loc.location == kLocPhysReg);
408091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  DCHECK(!loc.reg.IsFloat());
409e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu
410e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu  if (!loc.reg.IsPair()) {
411e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    if (IsTemp(loc.reg)) {
412e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      Clobber(loc.reg);
413e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    } else {
414e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      RegStorage temp = AllocTempWide();
415e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      OpRegCopy(temp, loc.reg);
416e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      loc.reg = temp;
417e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    }
418e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  } else {
419e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    if (IsTemp(loc.reg.GetLow())) {
420e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      Clobber(loc.reg.GetLow());
421e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    } else {
422e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      RegStorage temp_low = AllocTemp();
423e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      OpRegCopy(temp_low, loc.reg.GetLow());
424e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      loc.reg.SetLowReg(temp_low.GetReg());
425e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    }
426e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    if (IsTemp(loc.reg.GetHigh())) {
427e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      Clobber(loc.reg.GetHigh());
428e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    } else {
429e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      RegStorage temp_high = AllocTemp();
430e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      OpRegCopy(temp_high, loc.reg.GetHigh());
431e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      loc.reg.SetHighReg(temp_high.GetReg());
432e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    }
433e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  }
434e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell
435e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  // Ensure that this doesn't represent the original SR any more.
436e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  loc.s_reg_low = INVALID_SREG;
437e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell  return loc;
438e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell}
439e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell
44011d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes}  // namespace art
441