15d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng/* 25d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Copyright (C) 2009 The Android Open Source Project 35d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * 45d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Licensed under the Apache License, Version 2.0 (the "License"); 55d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * you may not use this file except in compliance with the License. 65d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * You may obtain a copy of the License at 75d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * 85d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * http://www.apache.org/licenses/LICENSE-2.0 95d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * 105d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Unless required by applicable law or agreed to in writing, software 115d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * distributed under the License is distributed on an "AS IS" BASIS, 125d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * See the License for the specific language governing permissions and 145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * limitations under the License. 155d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */ 165d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 175d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng/* 18e3f97d3bf789bfa7cd9d295d019396d85481a87fbuzbee * This file contains target-independent codegen and support, and is 19e3f97d3bf789bfa7cd9d295d019396d85481a87fbuzbee * included by: 205d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * 21e3f97d3bf789bfa7cd9d295d019396d85481a87fbuzbee * $(TARGET_ARCH)/Codegen-$(TARGET_ARCH_VARIANT).c 225d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * 235d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * which combines this common code with specific support found in the 24e3f97d3bf789bfa7cd9d295d019396d85481a87fbuzbee * applicable directories below this one. 25e3f97d3bf789bfa7cd9d295d019396d85481a87fbuzbee * 26e3f97d3bf789bfa7cd9d295d019396d85481a87fbuzbee * Prior to including this file, TGT_LIR should be #defined. 27e3f97d3bf789bfa7cd9d295d019396d85481a87fbuzbee * For example, for arm: 28e3f97d3bf789bfa7cd9d295d019396d85481a87fbuzbee * #define TGT_LIR ArmLIR 29e3f97d3bf789bfa7cd9d295d019396d85481a87fbuzbee * and for x86: 30e3f97d3bf789bfa7cd9d295d019396d85481a87fbuzbee * #define TGT_LIR X86LIR 315d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */ 325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 335d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng/* Load a word at base + displacement. Displacement must be word multiple */ 35e3f97d3bf789bfa7cd9d295d019396d85481a87fbuzbeestatic TGT_LIR *loadWordDisp(CompilationUnit *cUnit, int rBase, 36e3f97d3bf789bfa7cd9d295d019396d85481a87fbuzbee int displacement, int rDest) 375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return loadBaseDisp(cUnit, NULL, rBase, displacement, rDest, kWord, 395d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng INVALID_SREG); 405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 42e3f97d3bf789bfa7cd9d295d019396d85481a87fbuzbeestatic TGT_LIR *storeWordDisp(CompilationUnit *cUnit, int rBase, 435d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int displacement, int rSrc) 445d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return storeBaseDisp(cUnit, rBase, displacement, rSrc, kWord); 465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 485d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng/* 495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Load a Dalvik register into a physical register. Take care when 505d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * using this routine, as it doesn't perform any bookkeeping regarding 515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * register liveness. That is the responsibility of the caller. 525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */ 535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic void loadValueDirect(CompilationUnit *cUnit, RegLocation rlSrc, 54e3f97d3bf789bfa7cd9d295d019396d85481a87fbuzbee int reg1) 555d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 56c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlSrc = dvmCompilerUpdateLoc(cUnit, rlSrc); 575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (rlSrc.location == kLocPhysReg) { 585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, reg1, rlSrc.lowReg); 595d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else if (rlSrc.location == kLocRetval) { 60cf4a20cf0cbc53f03a5b16c7152bbb29907f7108buzbee loadWordDisp(cUnit, rSELF, offsetof(Thread, interpSave.retval), reg1); 615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 625d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(rlSrc.location == kLocDalvikFrame); 63c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee loadWordDisp(cUnit, rFP, dvmCompilerS2VReg(cUnit, rlSrc.sRegLow) << 2, 645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng reg1); 655d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng/* 695d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Similar to loadValueDirect, but clobbers and allocates the target 705d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * register. Should be used when loading to a fixed register (for example, 715d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * loading arguments to an out of line call. 725d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */ 735d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic void loadValueDirectFixed(CompilationUnit *cUnit, RegLocation rlSrc, 745d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int reg1) 755d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 76c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, reg1); 776a55513b0d268bc0721834050a3698316854fa0aElliott Hughes dvmCompilerMarkInUse(cUnit, reg1); 785d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadValueDirect(cUnit, rlSrc, reg1); 795d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 805d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 815d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng/* 825d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Load a Dalvik register pair into a physical register[s]. Take care when 835d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * using this routine, as it doesn't perform any bookkeeping regarding 845d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * register liveness. That is the responsibility of the caller. 855d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */ 865d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic void loadValueDirectWide(CompilationUnit *cUnit, RegLocation rlSrc, 875d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int regLo, int regHi) 885d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 89c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlSrc = dvmCompilerUpdateLocWide(cUnit, rlSrc); 905d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (rlSrc.location == kLocPhysReg) { 915d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopyWide(cUnit, regLo, regHi, rlSrc.lowReg, rlSrc.highReg); 925d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else if (rlSrc.location == kLocRetval) { 93cf4a20cf0cbc53f03a5b16c7152bbb29907f7108buzbee loadBaseDispWide(cUnit, NULL, rSELF, 94cf4a20cf0cbc53f03a5b16c7152bbb29907f7108buzbee offsetof(Thread, interpSave.retval), 955d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng regLo, regHi, INVALID_SREG); 965d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 975d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(rlSrc.location == kLocDalvikFrame); 985d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadBaseDispWide(cUnit, NULL, rFP, 99c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerS2VReg(cUnit, rlSrc.sRegLow) << 2, 1005d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng regLo, regHi, INVALID_SREG); 1015d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 1025d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 1035d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 1045d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng/* 1055d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * Similar to loadValueDirect, but clobbers and allocates the target 1065d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * registers. Should be used when loading to a fixed registers (for example, 1075d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng * loading arguments to an out of line call. 1085d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng */ 1095d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic void loadValueDirectWideFixed(CompilationUnit *cUnit, RegLocation rlSrc, 1105d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng int regLo, int regHi) 1115d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 112c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, regLo); 113c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, regHi); 1146a55513b0d268bc0721834050a3698316854fa0aElliott Hughes dvmCompilerMarkInUse(cUnit, regLo); 1156a55513b0d268bc0721834050a3698316854fa0aElliott Hughes dvmCompilerMarkInUse(cUnit, regHi); 1165d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadValueDirectWide(cUnit, rlSrc, regLo, regHi); 1175d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 1185d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 1195d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic RegLocation loadValue(CompilationUnit *cUnit, RegLocation rlSrc, 1205d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegisterClass opKind) 1215d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 122c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlSrc = dvmCompilerEvalLoc(cUnit, rlSrc, opKind, false); 1235d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (rlSrc.location == kLocDalvikFrame) { 1245d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadValueDirect(cUnit, rlSrc, rlSrc.lowReg); 1255d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc.location = kLocPhysReg; 126c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerMarkLive(cUnit, rlSrc.lowReg, rlSrc.sRegLow); 1275d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else if (rlSrc.location == kLocRetval) { 128cf4a20cf0cbc53f03a5b16c7152bbb29907f7108buzbee loadWordDisp(cUnit, rSELF, offsetof(Thread, interpSave.retval), 129cf4a20cf0cbc53f03a5b16c7152bbb29907f7108buzbee rlSrc.lowReg); 1305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc.location = kLocPhysReg; 131c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, rlSrc.lowReg); 1325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 1335d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return rlSrc; 1345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 1355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 1365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic void storeValue(CompilationUnit *cUnit, RegLocation rlDest, 1375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegLocation rlSrc) 1385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 1395d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng LIR *defStart; 1405d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng LIR *defEnd; 1415d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(!rlDest.wide); 1425d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(!rlSrc.wide); 143c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerKillNullCheckedLoc(cUnit, rlDest); 144c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlSrc = dvmCompilerUpdateLoc(cUnit, rlSrc); 145c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlDest = dvmCompilerUpdateLoc(cUnit, rlDest); 1465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (rlSrc.location == kLocPhysReg) { 147c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee if (dvmCompilerIsLive(cUnit, rlSrc.lowReg) || 148c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee (rlDest.location == kLocPhysReg)) { 1495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng // Src is live or Dest has assigned reg. 150c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlDest = dvmCompilerEvalLoc(cUnit, rlDest, kAnyReg, false); 1515d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopy(cUnit, rlDest.lowReg, rlSrc.lowReg); 1525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 1535d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng // Just re-assign the registers. Dest gets Src's regs 1545d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlDest.lowReg = rlSrc.lowReg; 155c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, rlSrc.lowReg); 1565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 1575d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 1585d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng // Load Src either into promoted Dest or temps allocated for Dest 159c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlDest = dvmCompilerEvalLoc(cUnit, rlDest, kAnyReg, false); 1605d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadValueDirect(cUnit, rlSrc, rlDest.lowReg); 1615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 1625d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 1635d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng // Dest is now live and dirty (until/if we flush it to home location) 164c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerMarkLive(cUnit, rlDest.lowReg, rlDest.sRegLow); 165c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerMarkDirty(cUnit, rlDest.lowReg); 1665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 1675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 1685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (rlDest.location == kLocRetval) { 169cf4a20cf0cbc53f03a5b16c7152bbb29907f7108buzbee storeBaseDisp(cUnit, rSELF, offsetof(Thread, interpSave.retval), 1705d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlDest.lowReg, kWord); 171c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, rlDest.lowReg); 1725d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 173c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerResetDefLoc(cUnit, rlDest); 174c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee if (dvmCompilerLiveOut(cUnit, rlDest.sRegLow)) { 1755d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng defStart = (LIR *)cUnit->lastLIRInsn; 176c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int vReg = dvmCompilerS2VReg(cUnit, rlDest.sRegLow); 1775d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeBaseDisp(cUnit, rFP, vReg << 2, rlDest.lowReg, kWord); 178c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerMarkClean(cUnit, rlDest.lowReg); 1795d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng defEnd = (LIR *)cUnit->lastLIRInsn; 180c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerMarkDef(cUnit, rlDest, defStart, defEnd); 1815d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 1825d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 1835d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 1845d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 1855d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic RegLocation loadValueWide(CompilationUnit *cUnit, RegLocation rlSrc, 1865d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng RegisterClass opKind) 1875d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 1885d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(rlSrc.wide); 189c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlSrc = dvmCompilerEvalLoc(cUnit, rlSrc, opKind, false); 1905d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (rlSrc.location == kLocDalvikFrame) { 1915d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadValueDirectWide(cUnit, rlSrc, rlSrc.lowReg, rlSrc.highReg); 1925d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc.location = kLocPhysReg; 193c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerMarkLive(cUnit, rlSrc.lowReg, rlSrc.sRegLow); 194c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerMarkLive(cUnit, rlSrc.highReg, 195c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerSRegHi(rlSrc.sRegLow)); 1965d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else if (rlSrc.location == kLocRetval) { 197cf4a20cf0cbc53f03a5b16c7152bbb29907f7108buzbee loadBaseDispWide(cUnit, NULL, rSELF, 198cf4a20cf0cbc53f03a5b16c7152bbb29907f7108buzbee offsetof(Thread, interpSave.retval), 1995d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc.lowReg, rlSrc.highReg, INVALID_SREG); 2005d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc.location = kLocPhysReg; 201c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, rlSrc.lowReg); 202c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, rlSrc.highReg); 2035d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 2045d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng return rlSrc; 2055d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 2065d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 2075d90c20bd7903d7bba966b224e576bf137bf8b4bBen Chengstatic void storeValueWide(CompilationUnit *cUnit, RegLocation rlDest, 208e3f97d3bf789bfa7cd9d295d019396d85481a87fbuzbee RegLocation rlSrc) 2095d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng{ 2105d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng LIR *defStart; 2115d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng LIR *defEnd; 2125d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(FPREG(rlSrc.lowReg)==FPREG(rlSrc.highReg)); 2135d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(rlDest.wide); 2145d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng assert(rlSrc.wide); 215c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerKillNullCheckedLoc(cUnit, rlDest); 2165d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (rlSrc.location == kLocPhysReg) { 217c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee if (dvmCompilerIsLive(cUnit, rlSrc.lowReg) || 218c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerIsLive(cUnit, rlSrc.highReg) || 2195d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng (rlDest.location == kLocPhysReg)) { 2205d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng // Src is live or Dest has assigned reg. 221c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlDest = dvmCompilerEvalLoc(cUnit, rlDest, kAnyReg, false); 2225d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng genRegCopyWide(cUnit, rlDest.lowReg, rlDest.highReg, 2235d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlSrc.lowReg, rlSrc.highReg); 2245d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 2255d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng // Just re-assign the registers. Dest gets Src's regs 2265d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlDest.lowReg = rlSrc.lowReg; 2275d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlDest.highReg = rlSrc.highReg; 228c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, rlSrc.lowReg); 229c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, rlSrc.highReg); 2305d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 2315d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 2325d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng // Load Src either into promoted Dest or temps allocated for Dest 233c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee rlDest = dvmCompilerEvalLoc(cUnit, rlDest, kAnyReg, false); 2345d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng loadValueDirectWide(cUnit, rlSrc, rlDest.lowReg, 2355d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlDest.highReg); 2365d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 2375d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 2385d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng // Dest is now live and dirty (until/if we flush it to home location) 239c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerMarkLive(cUnit, rlDest.lowReg, rlDest.sRegLow); 240c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerMarkLive(cUnit, rlDest.highReg, 241c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerSRegHi(rlDest.sRegLow)); 242c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerMarkDirty(cUnit, rlDest.lowReg); 243c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerMarkDirty(cUnit, rlDest.highReg); 244c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerMarkPair(cUnit, rlDest.lowReg, rlDest.highReg); 2455d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 2465d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng 2475d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng if (rlDest.location == kLocRetval) { 248cf4a20cf0cbc53f03a5b16c7152bbb29907f7108buzbee storeBaseDispWide(cUnit, rSELF, offsetof(Thread, interpSave.retval), 2495d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlDest.lowReg, rlDest.highReg); 250c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, rlDest.lowReg); 251c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerClobber(cUnit, rlDest.highReg); 2525d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } else { 253c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerResetDefLocWide(cUnit, rlDest); 254c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee if (dvmCompilerLiveOut(cUnit, rlDest.sRegLow) || 255c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerLiveOut(cUnit, dvmCompilerSRegHi(rlDest.sRegLow))) { 2565d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng defStart = (LIR *)cUnit->lastLIRInsn; 257c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee int vReg = dvmCompilerS2VReg(cUnit, rlDest.sRegLow); 258c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee assert((vReg+1) == dvmCompilerS2VReg(cUnit, 259c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerSRegHi(rlDest.sRegLow))); 2605d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng storeBaseDispWide(cUnit, rFP, vReg << 2, rlDest.lowReg, 2615d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng rlDest.highReg); 262c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerMarkClean(cUnit, rlDest.lowReg); 263c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerMarkClean(cUnit, rlDest.highReg); 2645d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng defEnd = (LIR *)cUnit->lastLIRInsn; 265c6f1066fd2dd761349128a9f422bc1ce3c3de595Bill Buzbee dvmCompilerMarkDefWide(cUnit, rlDest, defStart, defEnd); 2665d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 2675d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng } 2685d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng} 269