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 */
302ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::LoadConstant(int 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 */
432ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::Workaround7250540(RegLocation rl_dest, int 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      }
584ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      int temp_reg = zero_reg;
594ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      if (temp_reg == INVALID_REG) {
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
651fd3346740dfb7f47be9922312b68a4227fada96buzbee        OpRegCopy(promotion_map_[pmap_index].core_reg, temp_reg);
665f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee      } else {
675f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee        // Lives in the frame, need to store.
681fd3346740dfb7f47be9922312b68a4227fada96buzbee        StoreBaseDisp(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low), temp_reg, kWord);
694ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      }
704ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      if (zero_reg == INVALID_REG) {
711fd3346740dfb7f47be9922312b68a4227fada96buzbee        FreeTemp(temp_reg);
725f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee      }
735f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee    }
745f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee  }
755f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee}
765f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee
7767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* Load a word at base + displacement.  Displacement must be word multiple */
782ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::LoadWordDisp(int rBase, int displacement, int r_dest) {
791fd3346740dfb7f47be9922312b68a4227fada96buzbee  return LoadBaseDisp(rBase, displacement, r_dest, kWord,
80a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                      INVALID_SREG);
8167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
8267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
832ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::StoreWordDisp(int rBase, int displacement, int r_src) {
841fd3346740dfb7f47be9922312b68a4227fada96buzbee  return StoreBaseDisp(rBase, displacement, r_src, kWord);
8567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
8667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
8767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/*
8867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Load a Dalvik register into a physical register.  Take care when
8967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * using this routine, as it doesn't perform any bookkeeping regarding
9067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * register liveness.  That is the responsibility of the caller.
9167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */
922ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::LoadValueDirect(RegLocation rl_src, int r_dest) {
931fd3346740dfb7f47be9922312b68a4227fada96buzbee  rl_src = UpdateLoc(rl_src);
94fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (rl_src.location == kLocPhysReg) {
951fd3346740dfb7f47be9922312b68a4227fada96buzbee    OpRegCopy(r_dest, rl_src.low_reg);
961fd3346740dfb7f47be9922312b68a4227fada96buzbee  } else if (IsInexpensiveConstant(rl_src)) {
971fd3346740dfb7f47be9922312b68a4227fada96buzbee    LoadConstantNoClobber(r_dest, mir_graph_->ConstantValue(rl_src));
98a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
99fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    DCHECK((rl_src.location == kLocDalvikFrame) ||
100fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee           (rl_src.location == kLocCompilerTemp));
1011fd3346740dfb7f47be9922312b68a4227fada96buzbee    LoadWordDisp(TargetReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest);
102a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
10367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
10467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
10567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/*
10652a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee * Similar to LoadValueDirect, but clobbers and allocates the target
10767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * register.  Should be used when loading to a fixed register (for example,
10867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * loading arguments to an out of line call.
10967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */
1102ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::LoadValueDirectFixed(RegLocation rl_src, int r_dest) {
1111fd3346740dfb7f47be9922312b68a4227fada96buzbee  Clobber(r_dest);
1121fd3346740dfb7f47be9922312b68a4227fada96buzbee  MarkInUse(r_dest);
1131fd3346740dfb7f47be9922312b68a4227fada96buzbee  LoadValueDirect(rl_src, r_dest);
11467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
11567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
11667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/*
11767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Load a Dalvik register pair into a physical register[s].  Take care when
11867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * using this routine, as it doesn't perform any bookkeeping regarding
11967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * register liveness.  That is the responsibility of the caller.
12067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */
1211fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::LoadValueDirectWide(RegLocation rl_src, int reg_lo,
1222ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom             int reg_hi) {
1231fd3346740dfb7f47be9922312b68a4227fada96buzbee  rl_src = UpdateLocWide(rl_src);
124fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (rl_src.location == kLocPhysReg) {
1251fd3346740dfb7f47be9922312b68a4227fada96buzbee    OpRegCopyWide(reg_lo, reg_hi, rl_src.low_reg, rl_src.high_reg);
1261fd3346740dfb7f47be9922312b68a4227fada96buzbee  } else if (IsInexpensiveConstant(rl_src)) {
1271fd3346740dfb7f47be9922312b68a4227fada96buzbee    LoadConstantWide(reg_lo, reg_hi, mir_graph_->ConstantValueWide(rl_src));
128a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
129fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    DCHECK((rl_src.location == kLocDalvikFrame) ||
130fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee           (rl_src.location == kLocCompilerTemp));
1311fd3346740dfb7f47be9922312b68a4227fada96buzbee    LoadBaseDispWide(TargetReg(kSp), SRegOffset(rl_src.s_reg_low),
132fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                     reg_lo, reg_hi, INVALID_SREG);
133a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
13467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
13567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
13667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/*
13752a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee * Similar to LoadValueDirect, but clobbers and allocates the target
13867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * registers.  Should be used when loading to a fixed registers (for example,
13967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * loading arguments to an out of line call.
14067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */
1411fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::LoadValueDirectWideFixed(RegLocation rl_src, int reg_lo,
1422ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom                                       int reg_hi) {
1431fd3346740dfb7f47be9922312b68a4227fada96buzbee  Clobber(reg_lo);
1441fd3346740dfb7f47be9922312b68a4227fada96buzbee  Clobber(reg_hi);
1451fd3346740dfb7f47be9922312b68a4227fada96buzbee  MarkInUse(reg_lo);
1461fd3346740dfb7f47be9922312b68a4227fada96buzbee  MarkInUse(reg_hi);
1471fd3346740dfb7f47be9922312b68a4227fada96buzbee  LoadValueDirectWide(rl_src, reg_lo, reg_hi);
14867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
14967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
1502ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation Mir2Lir::LoadValue(RegLocation rl_src, RegisterClass op_kind) {
1511fd3346740dfb7f47be9922312b68a4227fada96buzbee  rl_src = EvalLoc(rl_src, op_kind, false);
1521fd3346740dfb7f47be9922312b68a4227fada96buzbee  if (IsInexpensiveConstant(rl_src) || rl_src.location != kLocPhysReg) {
1531fd3346740dfb7f47be9922312b68a4227fada96buzbee    LoadValueDirect(rl_src, rl_src.low_reg);
154fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    rl_src.location = kLocPhysReg;
1551fd3346740dfb7f47be9922312b68a4227fada96buzbee    MarkLive(rl_src.low_reg, rl_src.s_reg_low);
156a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
157fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  return rl_src;
15867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
15967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
1602ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::StoreValue(RegLocation rl_dest, RegLocation rl_src) {
161a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /*
162a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * Sanity checking - should never try to store to the same
163a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * ssa name during the compilation of a single instruction
16452a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee   * without an intervening ClobberSReg().
165a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   */
166311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  if (kIsDebugBuild) {
1671fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK((live_sreg_ == INVALID_SREG) ||
1681fd3346740dfb7f47be9922312b68a4227fada96buzbee           (rl_dest.s_reg_low != live_sreg_));
1691fd3346740dfb7f47be9922312b68a4227fada96buzbee    live_sreg_ = rl_dest.s_reg_low;
170311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  }
171fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LIR* def_start;
172fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LIR* def_end;
173fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK(!rl_dest.wide);
174fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK(!rl_src.wide);
1751fd3346740dfb7f47be9922312b68a4227fada96buzbee  rl_src = UpdateLoc(rl_src);
1761fd3346740dfb7f47be9922312b68a4227fada96buzbee  rl_dest = UpdateLoc(rl_dest);
177fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (rl_src.location == kLocPhysReg) {
1781fd3346740dfb7f47be9922312b68a4227fada96buzbee    if (IsLive(rl_src.low_reg) ||
1791fd3346740dfb7f47be9922312b68a4227fada96buzbee      IsPromoted(rl_src.low_reg) ||
180fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      (rl_dest.location == kLocPhysReg)) {
181a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      // Src is live/promoted or Dest has assigned reg.
1821fd3346740dfb7f47be9922312b68a4227fada96buzbee      rl_dest = EvalLoc(rl_dest, kAnyReg, false);
1831fd3346740dfb7f47be9922312b68a4227fada96buzbee      OpRegCopy(rl_dest.low_reg, rl_src.low_reg);
18467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    } else {
185a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      // Just re-assign the registers.  Dest gets Src's regs
186fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      rl_dest.low_reg = rl_src.low_reg;
1871fd3346740dfb7f47be9922312b68a4227fada96buzbee      Clobber(rl_src.low_reg);
18867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    }
189a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
190a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    // Load Src either into promoted Dest or temps allocated for Dest
1911fd3346740dfb7f47be9922312b68a4227fada96buzbee    rl_dest = EvalLoc(rl_dest, kAnyReg, false);
1921fd3346740dfb7f47be9922312b68a4227fada96buzbee    LoadValueDirect(rl_src, rl_dest.low_reg);
193a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
19467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
195a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  // Dest is now live and dirty (until/if we flush it to home location)
1961fd3346740dfb7f47be9922312b68a4227fada96buzbee  MarkLive(rl_dest.low_reg, rl_dest.s_reg_low);
1971fd3346740dfb7f47be9922312b68a4227fada96buzbee  MarkDirty(rl_dest);
19867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
19967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
2001fd3346740dfb7f47be9922312b68a4227fada96buzbee  ResetDefLoc(rl_dest);
2011fd3346740dfb7f47be9922312b68a4227fada96buzbee  if (IsDirty(rl_dest.low_reg) &&
2021fd3346740dfb7f47be9922312b68a4227fada96buzbee      oat_live_out(rl_dest.s_reg_low)) {
2031fd3346740dfb7f47be9922312b68a4227fada96buzbee    def_start = last_lir_insn_;
2041fd3346740dfb7f47be9922312b68a4227fada96buzbee    StoreBaseDisp(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low),
205fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                  rl_dest.low_reg, kWord);
2061fd3346740dfb7f47be9922312b68a4227fada96buzbee    MarkClean(rl_dest);
2071fd3346740dfb7f47be9922312b68a4227fada96buzbee    def_end = last_lir_insn_;
2085f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee    if (!rl_dest.ref) {
2095f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee      // Exclude references from store elimination
2101fd3346740dfb7f47be9922312b68a4227fada96buzbee      MarkDef(rl_dest, def_start, def_end);
2115f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee    }
212a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
21367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
21467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
2152ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation Mir2Lir::LoadValueWide(RegLocation rl_src, RegisterClass op_kind) {
216fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK(rl_src.wide);
2171fd3346740dfb7f47be9922312b68a4227fada96buzbee  rl_src = EvalLoc(rl_src, op_kind, false);
2181fd3346740dfb7f47be9922312b68a4227fada96buzbee  if (IsInexpensiveConstant(rl_src) || rl_src.location != kLocPhysReg) {
2191fd3346740dfb7f47be9922312b68a4227fada96buzbee    LoadValueDirectWide(rl_src, rl_src.low_reg, rl_src.high_reg);
220fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    rl_src.location = kLocPhysReg;
2211fd3346740dfb7f47be9922312b68a4227fada96buzbee    MarkLive(rl_src.low_reg, rl_src.s_reg_low);
2221fd3346740dfb7f47be9922312b68a4227fada96buzbee    MarkLive(rl_src.high_reg, GetSRegHi(rl_src.s_reg_low));
223a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
224fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  return rl_src;
22567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
22667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
2272ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::StoreValueWide(RegLocation rl_dest, RegLocation rl_src) {
228a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /*
229a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * Sanity checking - should never try to store to the same
230a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * ssa name during the compilation of a single instruction
23152a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee   * without an intervening ClobberSReg().
232a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   */
233311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  if (kIsDebugBuild) {
2341fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK((live_sreg_ == INVALID_SREG) ||
2351fd3346740dfb7f47be9922312b68a4227fada96buzbee           (rl_dest.s_reg_low != live_sreg_));
2361fd3346740dfb7f47be9922312b68a4227fada96buzbee    live_sreg_ = rl_dest.s_reg_low;
237311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  }
238fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LIR* def_start;
239fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LIR* def_end;
24002031b185b4653e6c72e21f7a51238b903f6d638buzbee  DCHECK_EQ(IsFpReg(rl_src.low_reg), IsFpReg(rl_src.high_reg));
241fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK(rl_dest.wide);
242fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  DCHECK(rl_src.wide);
243fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (rl_src.location == kLocPhysReg) {
2441fd3346740dfb7f47be9922312b68a4227fada96buzbee    if (IsLive(rl_src.low_reg) ||
2451fd3346740dfb7f47be9922312b68a4227fada96buzbee        IsLive(rl_src.high_reg) ||
2461fd3346740dfb7f47be9922312b68a4227fada96buzbee        IsPromoted(rl_src.low_reg) ||
2471fd3346740dfb7f47be9922312b68a4227fada96buzbee        IsPromoted(rl_src.high_reg) ||
248fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        (rl_dest.location == kLocPhysReg)) {
249a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      // Src is live or promoted or Dest has assigned reg.
2501fd3346740dfb7f47be9922312b68a4227fada96buzbee      rl_dest = EvalLoc(rl_dest, kAnyReg, false);
2511fd3346740dfb7f47be9922312b68a4227fada96buzbee      OpRegCopyWide(rl_dest.low_reg, rl_dest.high_reg,
252fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                    rl_src.low_reg, rl_src.high_reg);
25367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    } else {
254a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      // Just re-assign the registers.  Dest gets Src's regs
255fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      rl_dest.low_reg = rl_src.low_reg;
256fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      rl_dest.high_reg = rl_src.high_reg;
2571fd3346740dfb7f47be9922312b68a4227fada96buzbee      Clobber(rl_src.low_reg);
2581fd3346740dfb7f47be9922312b68a4227fada96buzbee      Clobber(rl_src.high_reg);
25967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee    }
260a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
261a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    // Load Src either into promoted Dest or temps allocated for Dest
2621fd3346740dfb7f47be9922312b68a4227fada96buzbee    rl_dest = EvalLoc(rl_dest, kAnyReg, false);
2631fd3346740dfb7f47be9922312b68a4227fada96buzbee    LoadValueDirectWide(rl_src, rl_dest.low_reg, rl_dest.high_reg);
264a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
26567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
266a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  // Dest is now live and dirty (until/if we flush it to home location)
2671fd3346740dfb7f47be9922312b68a4227fada96buzbee  MarkLive(rl_dest.low_reg, rl_dest.s_reg_low);
2681fd3346740dfb7f47be9922312b68a4227fada96buzbee  MarkLive(rl_dest.high_reg, GetSRegHi(rl_dest.s_reg_low));
2691fd3346740dfb7f47be9922312b68a4227fada96buzbee  MarkDirty(rl_dest);
2701fd3346740dfb7f47be9922312b68a4227fada96buzbee  MarkPair(rl_dest.low_reg, rl_dest.high_reg);
27167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
27267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee
2731fd3346740dfb7f47be9922312b68a4227fada96buzbee  ResetDefLocWide(rl_dest);
2741fd3346740dfb7f47be9922312b68a4227fada96buzbee  if ((IsDirty(rl_dest.low_reg) ||
2751fd3346740dfb7f47be9922312b68a4227fada96buzbee      IsDirty(rl_dest.high_reg)) &&
2761fd3346740dfb7f47be9922312b68a4227fada96buzbee      (oat_live_out(rl_dest.s_reg_low) ||
2771fd3346740dfb7f47be9922312b68a4227fada96buzbee      oat_live_out(GetSRegHi(rl_dest.s_reg_low)))) {
2781fd3346740dfb7f47be9922312b68a4227fada96buzbee    def_start = last_lir_insn_;
2791fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK_EQ((mir_graph_->SRegToVReg(rl_dest.s_reg_low)+1),
2801fd3346740dfb7f47be9922312b68a4227fada96buzbee              mir_graph_->SRegToVReg(GetSRegHi(rl_dest.s_reg_low)));
2811fd3346740dfb7f47be9922312b68a4227fada96buzbee    StoreBaseDispWide(TargetReg(kSp), SRegOffset(rl_dest.s_reg_low),
282fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                      rl_dest.low_reg, rl_dest.high_reg);
2831fd3346740dfb7f47be9922312b68a4227fada96buzbee    MarkClean(rl_dest);
2841fd3346740dfb7f47be9922312b68a4227fada96buzbee    def_end = last_lir_insn_;
2851fd3346740dfb7f47be9922312b68a4227fada96buzbee    MarkDefWide(rl_dest, def_start, def_end);
286a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
28767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee}
28811d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes
289e196567b50a084b163937ea9605b51ee1e48adebbuzbee/* Utilities to load the current Method* */
2902ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::LoadCurrMethodDirect(int r_tgt) {
2911fd3346740dfb7f47be9922312b68a4227fada96buzbee  LoadValueDirectFixed(mir_graph_->GetMethodLoc(), r_tgt);
29231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
29331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
2942ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation Mir2Lir::LoadCurrMethod() {
2951fd3346740dfb7f47be9922312b68a4227fada96buzbee  return LoadValue(mir_graph_->GetMethodLoc(), kCoreReg);
29631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
29731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
29811d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes}  // namespace art
299