gen_loadstore.cc revision e196567b50a084b163937ea9605b51ee1e48adeb
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 1711d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughesnamespace art { 1811d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes 1967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* 2067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * This file contains target-independent codegen and support, and is 2167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * included by: 2267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * 2367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * $(TARGET_ARCH)/Codegen-$(TARGET_ARCH_VARIANT).c 2467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * 2567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * which combines this common code with specific support found in the 2667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * applicable directories below this one. 2767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * 2867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */ 2967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 3031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 3131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Load an immediate value into a fixed or temp register. Target 3231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * register is clobbered, and marked inUse. 3331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 3431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeeLIR* loadConstant(CompilationUnit* cUnit, int rDest, int value) 3531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 3631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (oatIsTemp(cUnit, rDest)) { 3731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee oatClobber(cUnit, rDest); 3831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee oatMarkInUse(cUnit, rDest); 3931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 4031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee return loadConstantNoClobber(cUnit, rDest, value); 4131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 4267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 4367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* Load a word at base + displacement. Displacement must be word multiple */ 4431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeeLIR* loadWordDisp(CompilationUnit* cUnit, int rBase, int displacement, 4531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int rDest) 4667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 4767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee return loadBaseDisp(cUnit, NULL, rBase, displacement, rDest, kWord, 4867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee INVALID_SREG); 4967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 5067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 5131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeeLIR* storeWordDisp(CompilationUnit* cUnit, int rBase, int displacement, 5231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int rSrc) 5367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 5467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee return storeBaseDisp(cUnit, rBase, displacement, rSrc, kWord); 5567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 5667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 5767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* 5867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Load a Dalvik register into a physical register. Take care when 5967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * using this routine, as it doesn't perform any bookkeeping regarding 6067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * register liveness. That is the responsibility of the caller. 6167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */ 6231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeevoid loadValueDirect(CompilationUnit* cUnit, RegLocation rlSrc, int reg1) 6367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 6467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee rlSrc = oatUpdateLoc(cUnit, rlSrc); 6567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee if (rlSrc.location == kLocPhysReg) { 6682488f563e7f72f8c626052893c1792d76ab3fafbuzbee opRegCopy(cUnit, reg1, rlSrc.lowReg); 6767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } else { 68e196567b50a084b163937ea9605b51ee1e48adebbuzbee DCHECK((rlSrc.location == kLocDalvikFrame) || 69e196567b50a084b163937ea9605b51ee1e48adebbuzbee (rlSrc.location == kLocCompilerTemp)); 7067bc236a207852d652f6ddeab0a90efc1bd111bbbuzbee loadWordDisp(cUnit, rSP, oatSRegOffset(cUnit, rlSrc.sRegLow), reg1); 7167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 7267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 7367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 7467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* 7567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Similar to loadValueDirect, but clobbers and allocates the target 7667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * register. Should be used when loading to a fixed register (for example, 7767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * loading arguments to an out of line call. 7867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */ 7931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeevoid loadValueDirectFixed(CompilationUnit* cUnit, RegLocation rlSrc, int reg1) 8067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 8167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatClobber(cUnit, reg1); 8267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatMarkInUse(cUnit, reg1); 8367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee loadValueDirect(cUnit, rlSrc, reg1); 8467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 8567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 8667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* 8767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Load a Dalvik register pair into a physical register[s]. Take care when 8867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * using this routine, as it doesn't perform any bookkeeping regarding 8967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * register liveness. That is the responsibility of the caller. 9067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */ 9131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeevoid loadValueDirectWide(CompilationUnit* cUnit, RegLocation rlSrc, int regLo, 9231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int regHi) 9367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 9467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee rlSrc = oatUpdateLocWide(cUnit, rlSrc); 9567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee if (rlSrc.location == kLocPhysReg) { 9682488f563e7f72f8c626052893c1792d76ab3fafbuzbee opRegCopyWide(cUnit, regLo, regHi, rlSrc.lowReg, rlSrc.highReg); 9767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } else { 98e196567b50a084b163937ea9605b51ee1e48adebbuzbee DCHECK((rlSrc.location == kLocDalvikFrame) || 99e196567b50a084b163937ea9605b51ee1e48adebbuzbee (rlSrc.location == kLocCompilerTemp)); 10067bc236a207852d652f6ddeab0a90efc1bd111bbbuzbee loadBaseDispWide(cUnit, NULL, rSP, 10167bc236a207852d652f6ddeab0a90efc1bd111bbbuzbee oatSRegOffset(cUnit, rlSrc.sRegLow), 10267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee regLo, regHi, INVALID_SREG); 10367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 10467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 10567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 10667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* 10767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Similar to loadValueDirect, but clobbers and allocates the target 10867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * registers. Should be used when loading to a fixed registers (for example, 10967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * loading arguments to an out of line call. 11067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */ 11131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeevoid loadValueDirectWideFixed(CompilationUnit* cUnit, RegLocation rlSrc, 11231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int regLo, int regHi) 11367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 11467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatClobber(cUnit, regLo); 11567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatClobber(cUnit, regHi); 11667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatMarkInUse(cUnit, regLo); 11767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatMarkInUse(cUnit, regHi); 11867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee loadValueDirectWide(cUnit, rlSrc, regLo, regHi); 11967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 12067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 12131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeeRegLocation loadValue(CompilationUnit* cUnit, RegLocation rlSrc, 12231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee RegisterClass opKind) 12367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 12467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee rlSrc = oatEvalLoc(cUnit, rlSrc, opKind, false); 125e196567b50a084b163937ea9605b51ee1e48adebbuzbee if (rlSrc.location != kLocPhysReg) { 126e196567b50a084b163937ea9605b51ee1e48adebbuzbee DCHECK((rlSrc.location == kLocDalvikFrame) || 127e196567b50a084b163937ea9605b51ee1e48adebbuzbee (rlSrc.location == kLocCompilerTemp)); 12867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee loadValueDirect(cUnit, rlSrc, rlSrc.lowReg); 12967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee rlSrc.location = kLocPhysReg; 13067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatMarkLive(cUnit, rlSrc.lowReg, rlSrc.sRegLow); 13167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 13267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee return rlSrc; 13367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 13467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 13531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeevoid storeValue(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc) 13667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 13767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee LIR* defStart; 13867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee LIR* defEnd; 139ed3e930109e3f01804ca32cee4afe4f2d4b3f4d8buzbee DCHECK(!rlDest.wide); 140ed3e930109e3f01804ca32cee4afe4f2d4b3f4d8buzbee DCHECK(!rlSrc.wide); 14167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee rlSrc = oatUpdateLoc(cUnit, rlSrc); 14267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee rlDest = oatUpdateLoc(cUnit, rlDest); 14367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee if (rlSrc.location == kLocPhysReg) { 14467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee if (oatIsLive(cUnit, rlSrc.lowReg) || 145b29e4d1423028fab47db3be6e41e4b2a067bf100buzbee oatIsPromoted(cUnit, rlSrc.lowReg) || 14667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee (rlDest.location == kLocPhysReg)) { 147b29e4d1423028fab47db3be6e41e4b2a067bf100buzbee // Src is live/promoted or Dest has assigned reg. 14867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee rlDest = oatEvalLoc(cUnit, rlDest, kAnyReg, false); 14982488f563e7f72f8c626052893c1792d76ab3fafbuzbee opRegCopy(cUnit, rlDest.lowReg, rlSrc.lowReg); 15067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } else { 15167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee // Just re-assign the registers. Dest gets Src's regs 15267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee rlDest.lowReg = rlSrc.lowReg; 15367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatClobber(cUnit, rlSrc.lowReg); 15467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 15567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } else { 15667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee // Load Src either into promoted Dest or temps allocated for Dest 15767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee rlDest = oatEvalLoc(cUnit, rlDest, kAnyReg, false); 15867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee loadValueDirect(cUnit, rlSrc, rlDest.lowReg); 15967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 16067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 16167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee // Dest is now live and dirty (until/if we flush it to home location) 16267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatMarkLive(cUnit, rlDest.lowReg, rlDest.sRegLow); 16367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatMarkDirty(cUnit, rlDest); 16467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 16567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 16667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatResetDefLoc(cUnit, rlDest); 16767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee if (oatIsDirty(cUnit, rlDest.lowReg) && 16867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatLiveOut(cUnit, rlDest.sRegLow)) { 16967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee defStart = (LIR* )cUnit->lastLIRInsn; 17067bc236a207852d652f6ddeab0a90efc1bd111bbbuzbee storeBaseDisp(cUnit, rSP, oatSRegOffset(cUnit, rlDest.sRegLow), 17167bc236a207852d652f6ddeab0a90efc1bd111bbbuzbee rlDest.lowReg, kWord); 17267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatMarkClean(cUnit, rlDest); 17367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee defEnd = (LIR* )cUnit->lastLIRInsn; 17467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatMarkDef(cUnit, rlDest, defStart, defEnd); 17567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 17667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 17767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 17831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeeRegLocation loadValueWide(CompilationUnit* cUnit, RegLocation rlSrc, 17931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee RegisterClass opKind) 18067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 181ed3e930109e3f01804ca32cee4afe4f2d4b3f4d8buzbee DCHECK(rlSrc.wide); 18267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee rlSrc = oatEvalLoc(cUnit, rlSrc, opKind, false); 183e196567b50a084b163937ea9605b51ee1e48adebbuzbee if (rlSrc.location != kLocPhysReg) { 184e196567b50a084b163937ea9605b51ee1e48adebbuzbee DCHECK((rlSrc.location == kLocDalvikFrame) || 185e196567b50a084b163937ea9605b51ee1e48adebbuzbee (rlSrc.location == kLocCompilerTemp)); 18667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee loadValueDirectWide(cUnit, rlSrc, rlSrc.lowReg, rlSrc.highReg); 18767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee rlSrc.location = kLocPhysReg; 18867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatMarkLive(cUnit, rlSrc.lowReg, rlSrc.sRegLow); 18967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatMarkLive(cUnit, rlSrc.highReg, 19067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatSRegHi(rlSrc.sRegLow)); 19167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 19267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee return rlSrc; 19367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 19467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 19531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeevoid storeValueWide(CompilationUnit* cUnit, RegLocation rlDest, 19631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee RegLocation rlSrc) 19767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee{ 19867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee LIR* defStart; 19967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee LIR* defEnd; 200ed3e930109e3f01804ca32cee4afe4f2d4b3f4d8buzbee DCHECK_EQ(FPREG(rlSrc.lowReg), FPREG(rlSrc.highReg)); 201ed3e930109e3f01804ca32cee4afe4f2d4b3f4d8buzbee DCHECK(rlDest.wide); 202ed3e930109e3f01804ca32cee4afe4f2d4b3f4d8buzbee DCHECK(rlSrc.wide); 20367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee if (rlSrc.location == kLocPhysReg) { 20467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee if (oatIsLive(cUnit, rlSrc.lowReg) || 20567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatIsLive(cUnit, rlSrc.highReg) || 206b29e4d1423028fab47db3be6e41e4b2a067bf100buzbee oatIsPromoted(cUnit, rlSrc.lowReg) || 207b29e4d1423028fab47db3be6e41e4b2a067bf100buzbee oatIsPromoted(cUnit, rlSrc.highReg) || 20867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee (rlDest.location == kLocPhysReg)) { 209b29e4d1423028fab47db3be6e41e4b2a067bf100buzbee // Src is live or promoted or Dest has assigned reg. 21067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee rlDest = oatEvalLoc(cUnit, rlDest, kAnyReg, false); 21182488f563e7f72f8c626052893c1792d76ab3fafbuzbee opRegCopyWide(cUnit, rlDest.lowReg, rlDest.highReg, 21267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee rlSrc.lowReg, rlSrc.highReg); 21367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } else { 21467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee // Just re-assign the registers. Dest gets Src's regs 21567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee rlDest.lowReg = rlSrc.lowReg; 21667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee rlDest.highReg = rlSrc.highReg; 21767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatClobber(cUnit, rlSrc.lowReg); 21867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatClobber(cUnit, rlSrc.highReg); 21967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 22067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } else { 22167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee // Load Src either into promoted Dest or temps allocated for Dest 22267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee rlDest = oatEvalLoc(cUnit, rlDest, kAnyReg, false); 22367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee loadValueDirectWide(cUnit, rlSrc, rlDest.lowReg, 22467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee rlDest.highReg); 22567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 22667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 22767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee // Dest is now live and dirty (until/if we flush it to home location) 22867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatMarkLive(cUnit, rlDest.lowReg, rlDest.sRegLow); 22967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatMarkLive(cUnit, rlDest.highReg, 23067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatSRegHi(rlDest.sRegLow)); 23167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatMarkDirty(cUnit, rlDest); 23267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatMarkPair(cUnit, rlDest.lowReg, rlDest.highReg); 23367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 23467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 23567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatResetDefLocWide(cUnit, rlDest); 23667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee if ((oatIsDirty(cUnit, rlDest.lowReg) || 23767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatIsDirty(cUnit, rlDest.highReg)) && 23867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee (oatLiveOut(cUnit, rlDest.sRegLow) || 23967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatLiveOut(cUnit, oatSRegHi(rlDest.sRegLow)))) { 24067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee defStart = (LIR*)cUnit->lastLIRInsn; 241e196567b50a084b163937ea9605b51ee1e48adebbuzbee DCHECK_EQ((SRegToVReg(cUnit, rlDest.sRegLow)+1), 242e196567b50a084b163937ea9605b51ee1e48adebbuzbee SRegToVReg(cUnit, oatSRegHi(rlDest.sRegLow))); 24367bc236a207852d652f6ddeab0a90efc1bd111bbbuzbee storeBaseDispWide(cUnit, rSP, oatSRegOffset(cUnit, rlDest.sRegLow), 24467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee rlDest.lowReg, rlDest.highReg); 24567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatMarkClean(cUnit, rlDest); 24667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee defEnd = (LIR*)cUnit->lastLIRInsn; 24767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee oatMarkDefWide(cUnit, rlDest, defStart, defEnd); 24867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee } 24967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee} 25011d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes 25131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 25231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Mark garbage collection card. Skip if the value we're storing is null. 25331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 25431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeevoid markGCCard(CompilationUnit* cUnit, int valReg, int tgtAddrReg) 25531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 256a7678db092ac6bb79f7cad490099a1015fbbc714buzbee#if defined(TARGET_X86) 257a7678db092ac6bb79f7cad490099a1015fbbc714buzbee UNIMPLEMENTED(WARNING) << "markGCCard"; 258a7678db092ac6bb79f7cad490099a1015fbbc714buzbee#else 25931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int regCardBase = oatAllocTemp(cUnit); 26031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int regCardNo = oatAllocTemp(cUnit); 26182488f563e7f72f8c626052893c1792d76ab3fafbuzbee LIR* branchOver = opCmpImmBranch(cUnit, kCondEq, valReg, 0, NULL); 26231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee loadWordDisp(cUnit, rSELF, Thread::CardTableOffset().Int32Value(), 26331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee regCardBase); 26431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee opRegRegImm(cUnit, kOpLsr, regCardNo, tgtAddrReg, GC_CARD_SHIFT); 26531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee storeBaseIndexed(cUnit, regCardBase, regCardNo, regCardBase, 0, 26631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee kUnsignedByte); 26731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee LIR* target = newLIR0(cUnit, kPseudoTargetLabel); 26831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee branchOver->target = (LIR*)target; 26931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee oatFreeTemp(cUnit, regCardBase); 27031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee oatFreeTemp(cUnit, regCardNo); 271a7678db092ac6bb79f7cad490099a1015fbbc714buzbee#endif 27231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 27331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 274e196567b50a084b163937ea9605b51ee1e48adebbuzbee/* Utilities to load the current Method* */ 27531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeevoid loadCurrMethodDirect(CompilationUnit *cUnit, int rTgt) 27631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 277e196567b50a084b163937ea9605b51ee1e48adebbuzbee loadValueDirectFixed(cUnit, cUnit->regLocation[cUnit->methodSReg], rTgt); 27831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 27931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 280e196567b50a084b163937ea9605b51ee1e48adebbuzbeeRegLocation loadCurrMethod(CompilationUnit *cUnit) 28131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 282e196567b50a084b163937ea9605b51ee1e48adebbuzbee return loadValue(cUnit, cUnit->regLocation[cUnit->methodSReg], kCoreReg); 28331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 28431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 28531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 28611d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes} // namespace art 287