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