gen_loadstore.cc revision 20f85597828194c12be10d3a927999def066555e
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) { 451fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = UpdateLoc(rl_src); 46fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rl_src.location == kLocPhysReg) { 472700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee OpRegCopy(r_dest, rl_src.reg); 481fd3346740dfb7f47be9922312b68a4227fada96buzbee } else if (IsInexpensiveConstant(rl_src)) { 49695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee // 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); 56695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee if (rl_src.ref) { 57a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu LoadRefDisp(TargetPtrReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest, kNotVolatile); 58695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee } else { 59a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu Load32Disp(TargetPtrReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest); 60695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee } 61a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 6267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 6367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 6467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* 6552a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee * Similar to LoadValueDirect, but clobbers and allocates the target 6667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * register. Should be used when loading to a fixed register (for example, 6767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * loading arguments to an out of line call. 6867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */ 692700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeevoid Mir2Lir::LoadValueDirectFixed(RegLocation rl_src, RegStorage r_dest) { 701fd3346740dfb7f47be9922312b68a4227fada96buzbee Clobber(r_dest); 711fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkInUse(r_dest); 721fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadValueDirect(rl_src, r_dest); 7367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 7467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 7567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* 7667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Load a Dalvik register pair into a physical register[s]. Take care when 7767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * using this routine, as it doesn't perform any bookkeeping regarding 7867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * register liveness. That is the responsibility of the caller. 7967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */ 802700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeevoid Mir2Lir::LoadValueDirectWide(RegLocation rl_src, RegStorage r_dest) { 811fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = UpdateLocWide(rl_src); 82fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rl_src.location == kLocPhysReg) { 832700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee OpRegCopyWide(r_dest, rl_src.reg); 841fd3346740dfb7f47be9922312b68a4227fada96buzbee } else if (IsInexpensiveConstant(rl_src)) { 852700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee LoadConstantWide(r_dest, mir_graph_->ConstantValueWide(rl_src)); 86a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 87fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK((rl_src.location == kLocDalvikFrame) || 88fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee (rl_src.location == kLocCompilerTemp)); 898dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg); 90a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu LoadBaseDisp(TargetPtrReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest, k64, kNotVolatile); 91a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 9267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 9367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 9467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* 9552a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee * Similar to LoadValueDirect, but clobbers and allocates the target 9667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * registers. Should be used when loading to a fixed registers (for example, 9767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * loading arguments to an out of line call. 9867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */ 992700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeevoid Mir2Lir::LoadValueDirectWideFixed(RegLocation rl_src, RegStorage r_dest) { 1002700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee Clobber(r_dest); 1012700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee MarkInUse(r_dest); 1022700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee LoadValueDirectWide(rl_src, r_dest); 10367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 10467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 1052ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation Mir2Lir::LoadValue(RegLocation rl_src, RegisterClass op_kind) { 106a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbee DCHECK(!rl_src.ref || op_kind == kRefReg); 1070dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko rl_src = UpdateLoc(rl_src); 1080dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko if (rl_src.location == kLocPhysReg) { 1090dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko if (!RegClassMatches(op_kind, rl_src.reg)) { 1100dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko // Wrong register class, realloc, copy and transfer ownership. 1110dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko RegStorage new_reg = AllocTypedTemp(rl_src.fp, op_kind); 1120dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko OpRegCopy(new_reg, rl_src.reg); 11302c637e8d6952aba19a432e01fc94cece5071e2fSerguei Katkov // Clobber the old regs and free it. 1140dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko Clobber(rl_src.reg); 11502c637e8d6952aba19a432e01fc94cece5071e2fSerguei Katkov FreeTemp(rl_src.reg); 116082833c8d577db0b2bebc100602f31e4e971613ebuzbee // ...and mark the new one live. 1170dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko rl_src.reg = new_reg; 118082833c8d577db0b2bebc100602f31e4e971613ebuzbee MarkLive(rl_src); 1190dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko } 1200dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko return rl_src; 121a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 1220dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko 1230dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko DCHECK_NE(rl_src.s_reg_low, INVALID_SREG); 1240dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko rl_src.reg = AllocTypedTemp(rl_src.fp, op_kind); 1250dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko LoadValueDirect(rl_src, rl_src.reg); 1260dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko rl_src.location = kLocPhysReg; 1270dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko MarkLive(rl_src); 128fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return rl_src; 12967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 13067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 1312ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::StoreValue(RegLocation rl_dest, RegLocation rl_src) { 132a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 133a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Sanity checking - should never try to store to the same 134a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * ssa name during the compilation of a single instruction 13552a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee * without an intervening ClobberSReg(). 136a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 137311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (kIsDebugBuild) { 1381fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK((live_sreg_ == INVALID_SREG) || 1391fd3346740dfb7f47be9922312b68a4227fada96buzbee (rl_dest.s_reg_low != live_sreg_)); 1401fd3346740dfb7f47be9922312b68a4227fada96buzbee live_sreg_ = rl_dest.s_reg_low; 141311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 142fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR* def_start; 143fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR* def_end; 144fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(!rl_dest.wide); 145fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(!rl_src.wide); 1461fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = UpdateLoc(rl_src); 1471fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_dest = UpdateLoc(rl_dest); 148fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rl_src.location == kLocPhysReg) { 1492700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee if (IsLive(rl_src.reg) || 1502700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee IsPromoted(rl_src.reg) || 151fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee (rl_dest.location == kLocPhysReg)) { 152a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee // Src is live/promoted or Dest has assigned reg. 1534b537a851b686402513a7c4a4e60f5457bb8d7c1Andreas Gampe rl_dest = EvalLoc(rl_dest, rl_dest.ref || rl_src.ref ? kRefReg : kAnyReg, false); 1542700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee OpRegCopy(rl_dest.reg, rl_src.reg); 15567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } else { 156a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee // Just re-assign the registers. Dest gets Src's regs 15700e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee rl_dest.reg = rl_src.reg; 1582700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee Clobber(rl_src.reg); 15967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 160a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 161a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee // Load Src either into promoted Dest or temps allocated for Dest 1624b537a851b686402513a7c4a4e60f5457bb8d7c1Andreas Gampe rl_dest = EvalLoc(rl_dest, rl_dest.ref ? kRefReg : kAnyReg, false); 1632700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee LoadValueDirect(rl_src, rl_dest.reg); 164a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 16567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 166a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee // Dest is now live and dirty (until/if we flush it to home location) 167091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee MarkLive(rl_dest); 1681fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkDirty(rl_dest); 16967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 17067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 1711fd3346740dfb7f47be9922312b68a4227fada96buzbee ResetDefLoc(rl_dest); 172091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (IsDirty(rl_dest.reg) && LiveOut(rl_dest.s_reg_low)) { 1731fd3346740dfb7f47be9922312b68a4227fada96buzbee def_start = last_lir_insn_; 174e98297bafe84e2ac15eb73739f27826fcaae1203Ian Rogers ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg); 1752073e7553d1ca65f13b6c4e4fe364c2a345a1511Andreas Gampe if (rl_dest.ref) { 176a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu StoreRefDisp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg, kNotVolatile); 1772073e7553d1ca65f13b6c4e4fe364c2a345a1511Andreas Gampe } else { 178a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu Store32Disp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg); 1792073e7553d1ca65f13b6c4e4fe364c2a345a1511Andreas Gampe } 1801fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkClean(rl_dest); 1811fd3346740dfb7f47be9922312b68a4227fada96buzbee def_end = last_lir_insn_; 1825f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee if (!rl_dest.ref) { 1835f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee // Exclude references from store elimination 1841fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkDef(rl_dest, def_start, def_end); 1855f61f678d0b61cda8cac954fb176edbfdb1a831ebuzbee } 186a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 18767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 18867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 1892ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation Mir2Lir::LoadValueWide(RegLocation rl_src, RegisterClass op_kind) { 190fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_src.wide); 1910dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko rl_src = UpdateLocWide(rl_src); 1920dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko if (rl_src.location == kLocPhysReg) { 1930dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko if (!RegClassMatches(op_kind, rl_src.reg)) { 1940dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko // Wrong register class, realloc, copy and transfer ownership. 1950dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko RegStorage new_regs = AllocTypedTempWide(rl_src.fp, op_kind); 1960dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko OpRegCopyWide(new_regs, rl_src.reg); 19702c637e8d6952aba19a432e01fc94cece5071e2fSerguei Katkov // Clobber the old regs and free it. 1980dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko Clobber(rl_src.reg); 19902c637e8d6952aba19a432e01fc94cece5071e2fSerguei Katkov FreeTemp(rl_src.reg); 200082833c8d577db0b2bebc100602f31e4e971613ebuzbee // ...and mark the new ones live. 2010dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko rl_src.reg = new_regs; 202082833c8d577db0b2bebc100602f31e4e971613ebuzbee MarkLive(rl_src); 2030dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko } 2040dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko return rl_src; 205a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 2060dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko 2070dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko DCHECK_NE(rl_src.s_reg_low, INVALID_SREG); 2080dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko DCHECK_NE(GetSRegHi(rl_src.s_reg_low), INVALID_SREG); 2090dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko rl_src.reg = AllocTypedTempWide(rl_src.fp, op_kind); 2100dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko LoadValueDirectWide(rl_src, rl_src.reg); 2110dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko rl_src.location = kLocPhysReg; 2120dc242d6fc1254e6ca1c31e08e612bbf45644b17Vladimir Marko MarkLive(rl_src); 213fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return rl_src; 21467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 21567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 2162ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::StoreValueWide(RegLocation rl_dest, RegLocation rl_src) { 217a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 218a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Sanity checking - should never try to store to the same 219a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * ssa name during the compilation of a single instruction 22052a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee * without an intervening ClobberSReg(). 221a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 222311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (kIsDebugBuild) { 2231fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK((live_sreg_ == INVALID_SREG) || 2241fd3346740dfb7f47be9922312b68a4227fada96buzbee (rl_dest.s_reg_low != live_sreg_)); 2251fd3346740dfb7f47be9922312b68a4227fada96buzbee live_sreg_ = rl_dest.s_reg_low; 226311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 227fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR* def_start; 228fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR* def_end; 229fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_dest.wide); 230fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(rl_src.wide); 231c17ebe866beb50eb6da1e6a47555cb4731467f3bAlexei Zavjalov rl_src = UpdateLocWide(rl_src); 232c17ebe866beb50eb6da1e6a47555cb4731467f3bAlexei Zavjalov rl_dest = UpdateLocWide(rl_dest); 233fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rl_src.location == kLocPhysReg) { 2342700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee if (IsLive(rl_src.reg) || 2352700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee IsPromoted(rl_src.reg) || 236fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee (rl_dest.location == kLocPhysReg)) { 23730adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee /* 23830adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee * If src reg[s] are tied to the original Dalvik vreg via liveness or promotion, we 23930adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee * can't repurpose them. Similarly, if the dest reg[s] are tied to Dalvik vregs via 24030adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee * promotion, we can't just re-assign. In these cases, we have to copy. 24130adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee */ 2421fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_dest = EvalLoc(rl_dest, kAnyReg, false); 2432700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee OpRegCopyWide(rl_dest.reg, rl_src.reg); 24467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } else { 245a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee // Just re-assign the registers. Dest gets Src's regs 24600e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee rl_dest.reg = rl_src.reg; 2472700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee Clobber(rl_src.reg); 24867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 249a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 250a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee // Load Src either into promoted Dest or temps allocated for Dest 2511fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_dest = EvalLoc(rl_dest, kAnyReg, false); 2522700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee LoadValueDirectWide(rl_src, rl_dest.reg); 253a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 25467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 255a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee // Dest is now live and dirty (until/if we flush it to home location) 256091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee MarkLive(rl_dest); 257091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee MarkWide(rl_dest.reg); 258091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee MarkDirty(rl_dest); 25967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 2601fd3346740dfb7f47be9922312b68a4227fada96buzbee ResetDefLocWide(rl_dest); 261091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (IsDirty(rl_dest.reg) && (LiveOut(rl_dest.s_reg_low) || 262091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee LiveOut(GetSRegHi(rl_dest.s_reg_low)))) { 2631fd3346740dfb7f47be9922312b68a4227fada96buzbee def_start = last_lir_insn_; 2641fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK_EQ((mir_graph_->SRegToVReg(rl_dest.s_reg_low)+1), 2651fd3346740dfb7f47be9922312b68a4227fada96buzbee mir_graph_->SRegToVReg(GetSRegHi(rl_dest.s_reg_low))); 2668dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg); 267a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu StoreBaseDisp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg, k64, kNotVolatile); 2681fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkClean(rl_dest); 2691fd3346740dfb7f47be9922312b68a4227fada96buzbee def_end = last_lir_insn_; 2701fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkDefWide(rl_dest, def_start, def_end); 271a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 27267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 27311d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes 274feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendellvoid Mir2Lir::StoreFinalValue(RegLocation rl_dest, RegLocation rl_src) { 275feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell DCHECK_EQ(rl_src.location, kLocPhysReg); 276feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell 277feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell if (rl_dest.location == kLocPhysReg) { 2782700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee OpRegCopy(rl_dest.reg, rl_src.reg); 279feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell } else { 280feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell // Just re-assign the register. Dest gets Src's reg. 281feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell rl_dest.location = kLocPhysReg; 28200e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee rl_dest.reg = rl_src.reg; 2832700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee Clobber(rl_src.reg); 284feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell } 285feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell 286feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell // Dest is now live and dirty (until/if we flush it to home location) 287091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee MarkLive(rl_dest); 288feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell MarkDirty(rl_dest); 289feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell 290feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell 291feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell ResetDefLoc(rl_dest); 292091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (IsDirty(rl_dest.reg) && LiveOut(rl_dest.s_reg_low)) { 293feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell LIR *def_start = last_lir_insn_; 2948dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg); 295a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu Store32Disp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg); 296feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell MarkClean(rl_dest); 297feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell LIR *def_end = last_lir_insn_; 298feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell if (!rl_dest.ref) { 299feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell // Exclude references from store elimination 300feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell MarkDef(rl_dest, def_start, def_end); 301feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell } 302feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell } 303feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell} 304feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell 305e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendellvoid Mir2Lir::StoreFinalValueWide(RegLocation rl_dest, RegLocation rl_src) { 306e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell DCHECK(rl_dest.wide); 307e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell DCHECK(rl_src.wide); 308e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell DCHECK_EQ(rl_src.location, kLocPhysReg); 309e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell 310e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell if (rl_dest.location == kLocPhysReg) { 3112700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee OpRegCopyWide(rl_dest.reg, rl_src.reg); 312e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell } else { 313e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell // Just re-assign the registers. Dest gets Src's regs. 314e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell rl_dest.location = kLocPhysReg; 31500e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee rl_dest.reg = rl_src.reg; 316091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee Clobber(rl_src.reg); 317e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell } 318e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell 319e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell // Dest is now live and dirty (until/if we flush it to home location). 320091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee MarkLive(rl_dest); 321091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee MarkWide(rl_dest.reg); 322091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee MarkDirty(rl_dest); 323e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell 324e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell ResetDefLocWide(rl_dest); 325091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (IsDirty(rl_dest.reg) && (LiveOut(rl_dest.s_reg_low) || 326091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee LiveOut(GetSRegHi(rl_dest.s_reg_low)))) { 327e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell LIR *def_start = last_lir_insn_; 328e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell DCHECK_EQ((mir_graph_->SRegToVReg(rl_dest.s_reg_low)+1), 329e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell mir_graph_->SRegToVReg(GetSRegHi(rl_dest.s_reg_low))); 3308dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg); 331a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu StoreBaseDisp(TargetPtrReg(kSp), SRegOffset(rl_dest.s_reg_low), rl_dest.reg, k64, kNotVolatile); 332e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell MarkClean(rl_dest); 333e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell LIR *def_end = last_lir_insn_; 334e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell MarkDefWide(rl_dest, def_start, def_end); 335e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell } 336e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell} 337e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell 338e196567b50a084b163937ea9605b51ee1e48adebbuzbee/* Utilities to load the current Method* */ 3392700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeevoid Mir2Lir::LoadCurrMethodDirect(RegStorage r_tgt) { 3401fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadValueDirectFixed(mir_graph_->GetMethodLoc(), r_tgt); 34131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 34231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 34320f85597828194c12be10d3a927999def066555eVladimir MarkoRegStorage Mir2Lir::LoadCurrMethodWithHint(RegStorage r_hint) { 34420f85597828194c12be10d3a927999def066555eVladimir Marko // If the method is promoted to a register, return that register, otherwise load it to r_hint. 34520f85597828194c12be10d3a927999def066555eVladimir Marko // (Replacement for LoadCurrMethod() usually used when LockCallTemps() is in effect.) 34620f85597828194c12be10d3a927999def066555eVladimir Marko DCHECK(r_hint.Valid()); 34720f85597828194c12be10d3a927999def066555eVladimir Marko RegLocation rl_method = mir_graph_->GetMethodLoc(); 34820f85597828194c12be10d3a927999def066555eVladimir Marko if (rl_method.location == kLocPhysReg) { 34920f85597828194c12be10d3a927999def066555eVladimir Marko DCHECK(!IsTemp(rl_method.reg)); 35020f85597828194c12be10d3a927999def066555eVladimir Marko return rl_method.reg; 35120f85597828194c12be10d3a927999def066555eVladimir Marko } else { 35220f85597828194c12be10d3a927999def066555eVladimir Marko LoadCurrMethodDirect(r_hint); 35320f85597828194c12be10d3a927999def066555eVladimir Marko return r_hint; 35420f85597828194c12be10d3a927999def066555eVladimir Marko } 35520f85597828194c12be10d3a927999def066555eVladimir Marko} 35620f85597828194c12be10d3a927999def066555eVladimir Marko 3572ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromRegLocation Mir2Lir::LoadCurrMethod() { 358a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbee return LoadValue(mir_graph_->GetMethodLoc(), kRefReg); 35931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 36031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 361e02d48fb24747f90fd893e1c3572bb3c500afcedMark MendellRegLocation Mir2Lir::ForceTemp(RegLocation loc) { 362e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell DCHECK(!loc.wide); 363e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell DCHECK(loc.location == kLocPhysReg); 364091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(!loc.reg.IsFloat()); 3652700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee if (IsTemp(loc.reg)) { 3662700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee Clobber(loc.reg); 367e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell } else { 3682700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage temp_low = AllocTemp(); 3692700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee OpRegCopy(temp_low, loc.reg); 3702700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee loc.reg = temp_low; 371e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell } 372e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell 373e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell // Ensure that this doesn't represent the original SR any more. 374e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell loc.s_reg_low = INVALID_SREG; 375e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell return loc; 376e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell} 377e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell 378e02d48fb24747f90fd893e1c3572bb3c500afcedMark MendellRegLocation Mir2Lir::ForceTempWide(RegLocation loc) { 379e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell DCHECK(loc.wide); 380e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell DCHECK(loc.location == kLocPhysReg); 381091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(!loc.reg.IsFloat()); 382e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu 383e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu if (!loc.reg.IsPair()) { 384e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu if (IsTemp(loc.reg)) { 385e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu Clobber(loc.reg); 386e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } else { 387e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu RegStorage temp = AllocTempWide(); 388e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu OpRegCopy(temp, loc.reg); 389e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu loc.reg = temp; 390e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } 391e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell } else { 392e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu if (IsTemp(loc.reg.GetLow())) { 393e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu Clobber(loc.reg.GetLow()); 394e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } else { 395e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu RegStorage temp_low = AllocTemp(); 396e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu OpRegCopy(temp_low, loc.reg.GetLow()); 397e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu loc.reg.SetLowReg(temp_low.GetReg()); 398e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } 399e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu if (IsTemp(loc.reg.GetHigh())) { 400e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu Clobber(loc.reg.GetHigh()); 401e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } else { 402e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu RegStorage temp_high = AllocTemp(); 403e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu OpRegCopy(temp_high, loc.reg.GetHigh()); 404e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu loc.reg.SetHighReg(temp_high.GetReg()); 405e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } 406e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell } 407e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell 408e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell // Ensure that this doesn't represent the original SR any more. 409e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell loc.s_reg_low = INVALID_SREG; 410e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell return loc; 411e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell} 412e02d48fb24747f90fd893e1c3572bb3c500afcedMark Mendell 41311d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes} // namespace art 414