codegen_util.cc revision b5d09b2f87202bc132ac3991d4b6d71f4f6d9264
1e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* 2e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Copyright (C) 2011 The Android Open Source Project 3e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * 4e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Licensed under the Apache License, Version 2.0 (the "License"); 5e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * you may not use this file except in compliance with the License. 6e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * You may obtain a copy of the License at 7e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * 8e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * http://www.apache.org/licenses/LICENSE-2.0 9e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * 10e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Unless required by applicable law or agreed to in writing, software 11e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * distributed under the License is distributed on an "AS IS" BASIS, 12e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * See the License for the specific language governing permissions and 14e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * limitations under the License. 15e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee */ 16e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 17e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbeenamespace art { 18e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 1931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeevoid setMemRefType(LIR* lir, bool isLoad, int memType) 2031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 2131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee u8 *maskPtr; 2231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee u8 mask = ENCODE_MEM;; 2331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee DCHECK(EncodingMap[lir->opcode].flags & (IS_LOAD | IS_STORE)); 2431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (isLoad) { 2531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee maskPtr = &lir->useMask; 2631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } else { 2731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee maskPtr = &lir->defMask; 2831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 2931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee /* Clear out the memref flags */ 3031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee *maskPtr &= ~mask; 3131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee /* ..and then add back the one we need */ 3231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee switch(memType) { 3331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee case kLiteral: 3431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee DCHECK(isLoad); 3531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee *maskPtr |= ENCODE_LITERAL; 3631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee break; 3731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee case kDalvikReg: 3831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee *maskPtr |= ENCODE_DALVIK_REG; 3931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee break; 4031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee case kHeapRef: 4131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee *maskPtr |= ENCODE_HEAP_REF; 4231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee break; 4331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee case kMustNotAlias: 4431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee /* Currently only loads can be marked as kMustNotAlias */ 4531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee DCHECK(!(EncodingMap[lir->opcode].flags & IS_STORE)); 4631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee *maskPtr |= ENCODE_MUST_NOT_ALIAS; 4731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee break; 4831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee default: 4931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee LOG(FATAL) << "Oat: invalid memref kind - " << memType; 5031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 5131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 5231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 5331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 54b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers * Mark load/store instructions that access Dalvik registers through the stack. 5531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 56b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogersvoid annotateDalvikRegAccess(LIR* lir, int regId, bool isLoad, bool is64bit) 5731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 5831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee setMemRefType(lir, isLoad, kDalvikReg); 5931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 6031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee /* 61b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers * Store the Dalvik register id in aliasInfo. Mark the MSB if it is a 64-bit 6231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * access. 6331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 6431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->aliasInfo = regId; 65b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (is64bit) { 6631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->aliasInfo |= 0x80000000; 6731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 6831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 6931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 7031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 7131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Decode the register id. 7231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 7331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeeinline u8 getRegMaskCommon(int reg) 7431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 7531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee u8 seed; 7631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int shift; 7731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int regId = reg & 0x1f; 7831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 7931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee /* 8031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Each double register is equal to a pair of single-precision FP registers 8131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 8231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee seed = DOUBLEREG(reg) ? 3 : 1; 8331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee /* FP register starts at bit position 16 */ 8431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee shift = FPREG(reg) ? kFPReg0 : 0; 8531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee /* Expand the double register id into single offset */ 8631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee shift += regId; 8731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee return (seed << shift); 8831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 8931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 9031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 9131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Mark the corresponding bit(s). 9231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 9331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeeinline void setupRegMask(u8* mask, int reg) 9431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 9531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee *mask |= getRegMaskCommon(reg); 9631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 9731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 9831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 9931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Set up the proper fields in the resource mask 10031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 10131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeevoid setupResourceMasks(LIR* lir) 10231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 10331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int opcode = lir->opcode; 10431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int flags; 10531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 10631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (opcode <= 0) { 10731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->useMask = lir->defMask = 0; 10831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee return; 10931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 11031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 11131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee flags = EncodingMap[lir->opcode].flags; 11231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 11331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & NEEDS_FIXUP) { 11431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->flags.pcRelFixup = true; 11531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 11631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 117e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee /* Get the starting size of the instruction's template */ 118e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee lir->flags.size = oatGetInsnSize(lir); 119e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 12031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee /* Set up the mask for resources that are updated */ 12131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & (IS_LOAD | IS_STORE)) { 12231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee /* Default to heap - will catch specialized classes later */ 12331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee setMemRefType(lir, flags & IS_LOAD, kHeapRef); 12431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 12531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 12631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee /* 12731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Conservatively assume the branch here will call out a function that in 12831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * turn will trash everything. 12931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 13031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & IS_BRANCH) { 13131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->defMask = lir->useMask = ENCODE_ALL; 13231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee return; 13331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 13431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 13531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & REG_DEF0) { 13631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee setupRegMask(&lir->defMask, lir->operands[0]); 13731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 13831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 13931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & REG_DEF1) { 14031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee setupRegMask(&lir->defMask, lir->operands[1]); 14131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 14231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 14331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & REG_DEF_SP) { 14431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->defMask |= ENCODE_REG_SP; 14531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 14631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 147a7678db092ac6bb79f7cad490099a1015fbbc714buzbee#if !defined(TARGET_X86) 14831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & REG_DEF_LR) { 14931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->defMask |= ENCODE_REG_LR; 15031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 151a7678db092ac6bb79f7cad490099a1015fbbc714buzbee#endif 15231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 15331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & REG_DEF_LIST0) { 15431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->defMask |= ENCODE_REG_LIST(lir->operands[0]); 15531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 15631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 15731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & REG_DEF_LIST1) { 15831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->defMask |= ENCODE_REG_LIST(lir->operands[1]); 15931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 16031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 1615de3494e4297c0d480409da3fecee39173f1d4e1buzbee#if defined(TARGET_ARM) 16231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & REG_DEF_FPCS_LIST0) { 16331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->defMask |= ENCODE_REG_FPCS_LIST(lir->operands[0]); 16431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 16531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 16631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & REG_DEF_FPCS_LIST2) { 16731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee for (int i = 0; i < lir->operands[2]; i++) { 16831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee setupRegMask(&lir->defMask, lir->operands[1] + i); 16931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 17031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 1715de3494e4297c0d480409da3fecee39173f1d4e1buzbee#endif 17231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 17331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & SETS_CCODES) { 17431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->defMask |= ENCODE_CCODE; 17531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 17631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 17731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee#if defined(TARGET_ARM) 17831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee /* Conservatively treat the IT block */ 17931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & IS_IT) { 18031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->defMask = ENCODE_ALL; 18131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 18231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee#endif 18331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 18431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & (REG_USE0 | REG_USE1 | REG_USE2 | REG_USE3)) { 18531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int i; 18631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 18731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee for (i = 0; i < 4; i++) { 18831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & (1 << (kRegUse0 + i))) { 18931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee setupRegMask(&lir->useMask, lir->operands[i]); 19031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 19131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 19231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 19331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 194a7678db092ac6bb79f7cad490099a1015fbbc714buzbee#if defined(TARGET_ARM) 19531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & REG_USE_PC) { 19631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->useMask |= ENCODE_REG_PC; 19731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 198a7678db092ac6bb79f7cad490099a1015fbbc714buzbee#endif 19931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 20031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & REG_USE_SP) { 20131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->useMask |= ENCODE_REG_SP; 20231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 20331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 20431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & REG_USE_LIST0) { 20531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->useMask |= ENCODE_REG_LIST(lir->operands[0]); 20631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 20731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 20831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & REG_USE_LIST1) { 20931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->useMask |= ENCODE_REG_LIST(lir->operands[1]); 21031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 21131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 2125de3494e4297c0d480409da3fecee39173f1d4e1buzbee#if defined(TARGET_ARM) 21331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & REG_USE_FPCS_LIST0) { 21431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->useMask |= ENCODE_REG_FPCS_LIST(lir->operands[0]); 21531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 21631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 21731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & REG_USE_FPCS_LIST2) { 21831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee for (int i = 0; i < lir->operands[2]; i++) { 21931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee setupRegMask(&lir->useMask, lir->operands[1] + i); 22031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 22131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 2225de3494e4297c0d480409da3fecee39173f1d4e1buzbee#endif 22331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 22431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (flags & USES_CCODES) { 22531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->useMask |= ENCODE_CCODE; 22631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 22731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 22831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee#if defined(TARGET_ARM) 22931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee /* Fixup for kThumbPush/lr and kThumbPop/pc */ 23031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (opcode == kThumbPush || opcode == kThumbPop) { 23131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee u8 r8Mask = getRegMaskCommon(r8); 23231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if ((opcode == kThumbPush) && (lir->useMask & r8Mask)) { 23331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->useMask &= ~r8Mask; 23431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->useMask |= ENCODE_REG_LR; 23531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } else if ((opcode == kThumbPop) && (lir->defMask & r8Mask)) { 23631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->defMask &= ~r8Mask; 23731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee lir->defMask |= ENCODE_REG_PC; 23831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 23931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 24031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee#endif 24131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 24231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 24331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 2445de3494e4297c0d480409da3fecee39173f1d4e1buzbee * Debugging macros 2455de3494e4297c0d480409da3fecee39173f1d4e1buzbee */ 2465de3494e4297c0d480409da3fecee39173f1d4e1buzbee#define DUMP_RESOURCE_MASK(X) 2475de3494e4297c0d480409da3fecee39173f1d4e1buzbee#define DUMP_SSA_REP(X) 2485de3494e4297c0d480409da3fecee39173f1d4e1buzbee 2495de3494e4297c0d480409da3fecee39173f1d4e1buzbee/* Pretty-print a LIR instruction */ 2505de3494e4297c0d480409da3fecee39173f1d4e1buzbeevoid oatDumpLIRInsn(CompilationUnit* cUnit, LIR* arg, unsigned char* baseAddr) 2515de3494e4297c0d480409da3fecee39173f1d4e1buzbee{ 2525de3494e4297c0d480409da3fecee39173f1d4e1buzbee LIR* lir = (LIR*) arg; 2535de3494e4297c0d480409da3fecee39173f1d4e1buzbee int offset = lir->offset; 2545de3494e4297c0d480409da3fecee39173f1d4e1buzbee int dest = lir->operands[0]; 25586a4bce32e2aaf3d377c0acf865f0630a7c30495buzbee const bool dumpNop = (cUnit->enableDebug & (1 << kDebugShowNops)); 2565de3494e4297c0d480409da3fecee39173f1d4e1buzbee 2575de3494e4297c0d480409da3fecee39173f1d4e1buzbee /* Handle pseudo-ops individually, and all regular insns as a group */ 2585de3494e4297c0d480409da3fecee39173f1d4e1buzbee switch(lir->opcode) { 2595de3494e4297c0d480409da3fecee39173f1d4e1buzbee case kPseudoMethodEntry: 2605de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "-------- method entry " << 2615de3494e4297c0d480409da3fecee39173f1d4e1buzbee PrettyMethod(cUnit->method_idx, *cUnit->dex_file); 2625de3494e4297c0d480409da3fecee39173f1d4e1buzbee break; 2635de3494e4297c0d480409da3fecee39173f1d4e1buzbee case kPseudoMethodExit: 2645de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "-------- Method_Exit"; 2655de3494e4297c0d480409da3fecee39173f1d4e1buzbee break; 2665de3494e4297c0d480409da3fecee39173f1d4e1buzbee case kPseudoBarrier: 2675de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "-------- BARRIER"; 2685de3494e4297c0d480409da3fecee39173f1d4e1buzbee break; 2695de3494e4297c0d480409da3fecee39173f1d4e1buzbee case kPseudoExtended: 2705de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "-------- " << (char* ) dest; 2715de3494e4297c0d480409da3fecee39173f1d4e1buzbee break; 2725de3494e4297c0d480409da3fecee39173f1d4e1buzbee case kPseudoSSARep: 2735de3494e4297c0d480409da3fecee39173f1d4e1buzbee DUMP_SSA_REP(LOG(INFO) << "-------- kMirOpPhi: " << (char* ) dest); 2745de3494e4297c0d480409da3fecee39173f1d4e1buzbee break; 2755de3494e4297c0d480409da3fecee39173f1d4e1buzbee case kPseudoEntryBlock: 2765de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "-------- entry offset: 0x" << std::hex << dest; 2775de3494e4297c0d480409da3fecee39173f1d4e1buzbee break; 2785de3494e4297c0d480409da3fecee39173f1d4e1buzbee case kPseudoDalvikByteCodeBoundary: 2795de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "-------- dalvik offset: 0x" << std::hex << 2805de3494e4297c0d480409da3fecee39173f1d4e1buzbee lir->dalvikOffset << " @ " << (char* )lir->operands[0]; 2815de3494e4297c0d480409da3fecee39173f1d4e1buzbee break; 2825de3494e4297c0d480409da3fecee39173f1d4e1buzbee case kPseudoExitBlock: 2835de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "-------- exit offset: 0x" << std::hex << dest; 2845de3494e4297c0d480409da3fecee39173f1d4e1buzbee break; 2855de3494e4297c0d480409da3fecee39173f1d4e1buzbee case kPseudoPseudoAlign4: 2865de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << (intptr_t)baseAddr + offset << " (0x" << std::hex << 2875de3494e4297c0d480409da3fecee39173f1d4e1buzbee offset << "): .align4"; 2885de3494e4297c0d480409da3fecee39173f1d4e1buzbee break; 2895de3494e4297c0d480409da3fecee39173f1d4e1buzbee case kPseudoEHBlockLabel: 2905de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "Exception_Handling:"; 2915de3494e4297c0d480409da3fecee39173f1d4e1buzbee break; 2925de3494e4297c0d480409da3fecee39173f1d4e1buzbee case kPseudoTargetLabel: 2935de3494e4297c0d480409da3fecee39173f1d4e1buzbee case kPseudoNormalBlockLabel: 2945de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "L" << (intptr_t)lir << ":"; 2955de3494e4297c0d480409da3fecee39173f1d4e1buzbee break; 2965de3494e4297c0d480409da3fecee39173f1d4e1buzbee case kPseudoThrowTarget: 2975de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "LT" << (intptr_t)lir << ":"; 2985de3494e4297c0d480409da3fecee39173f1d4e1buzbee break; 2995de3494e4297c0d480409da3fecee39173f1d4e1buzbee case kPseudoSuspendTarget: 3005de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "LS" << (intptr_t)lir << ":"; 3015de3494e4297c0d480409da3fecee39173f1d4e1buzbee break; 3025de3494e4297c0d480409da3fecee39173f1d4e1buzbee case kPseudoCaseLabel: 3035de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "LC" << (intptr_t)lir << ": Case target 0x" << 3045de3494e4297c0d480409da3fecee39173f1d4e1buzbee std::hex << lir->operands[0] << "|" << std::dec << 3055de3494e4297c0d480409da3fecee39173f1d4e1buzbee lir->operands[0]; 3065de3494e4297c0d480409da3fecee39173f1d4e1buzbee break; 3075de3494e4297c0d480409da3fecee39173f1d4e1buzbee default: 3085de3494e4297c0d480409da3fecee39173f1d4e1buzbee if (lir->flags.isNop && !dumpNop) { 3095de3494e4297c0d480409da3fecee39173f1d4e1buzbee break; 3105de3494e4297c0d480409da3fecee39173f1d4e1buzbee } else { 3115de3494e4297c0d480409da3fecee39173f1d4e1buzbee std::string op_name(buildInsnString(EncodingMap[lir->opcode].name, lir, baseAddr)); 3125de3494e4297c0d480409da3fecee39173f1d4e1buzbee std::string op_operands(buildInsnString(EncodingMap[lir->opcode].fmt, lir, baseAddr)); 313be00364d260ea96323a070723af0bd61e3ea703abuzbee LOG(INFO) << StringPrintf("%05x: %-9s%s%s", (unsigned int)(baseAddr + offset), 3145de3494e4297c0d480409da3fecee39173f1d4e1buzbee op_name.c_str(), op_operands.c_str(), lir->flags.isNop ? "(nop)" : ""); 3155de3494e4297c0d480409da3fecee39173f1d4e1buzbee } 3165de3494e4297c0d480409da3fecee39173f1d4e1buzbee break; 3175de3494e4297c0d480409da3fecee39173f1d4e1buzbee } 3185de3494e4297c0d480409da3fecee39173f1d4e1buzbee 3195de3494e4297c0d480409da3fecee39173f1d4e1buzbee if (lir->useMask && (!lir->flags.isNop || dumpNop)) { 3205de3494e4297c0d480409da3fecee39173f1d4e1buzbee DUMP_RESOURCE_MASK(oatDumpResourceMask((LIR* ) lir, 3215de3494e4297c0d480409da3fecee39173f1d4e1buzbee lir->useMask, "use")); 3225de3494e4297c0d480409da3fecee39173f1d4e1buzbee } 3235de3494e4297c0d480409da3fecee39173f1d4e1buzbee if (lir->defMask && (!lir->flags.isNop || dumpNop)) { 3245de3494e4297c0d480409da3fecee39173f1d4e1buzbee DUMP_RESOURCE_MASK(oatDumpResourceMask((LIR* ) lir, 3255de3494e4297c0d480409da3fecee39173f1d4e1buzbee lir->defMask, "def")); 3265de3494e4297c0d480409da3fecee39173f1d4e1buzbee } 3275de3494e4297c0d480409da3fecee39173f1d4e1buzbee} 3285de3494e4297c0d480409da3fecee39173f1d4e1buzbee 3295de3494e4297c0d480409da3fecee39173f1d4e1buzbeevoid oatDumpPromotionMap(CompilationUnit *cUnit) 3305de3494e4297c0d480409da3fecee39173f1d4e1buzbee{ 3315de3494e4297c0d480409da3fecee39173f1d4e1buzbee for (int i = 0; i < cUnit->numDalvikRegisters; i++) { 3325de3494e4297c0d480409da3fecee39173f1d4e1buzbee PromotionMap vRegMap = cUnit->promotionMap[i]; 3335de3494e4297c0d480409da3fecee39173f1d4e1buzbee char buf[100]; 3345de3494e4297c0d480409da3fecee39173f1d4e1buzbee if (vRegMap.fpLocation == kLocPhysReg) { 3355de3494e4297c0d480409da3fecee39173f1d4e1buzbee snprintf(buf, 100, " : s%d", vRegMap.fpReg & FP_REG_MASK); 3365de3494e4297c0d480409da3fecee39173f1d4e1buzbee } else { 3375de3494e4297c0d480409da3fecee39173f1d4e1buzbee buf[0] = 0; 3385de3494e4297c0d480409da3fecee39173f1d4e1buzbee } 3395de3494e4297c0d480409da3fecee39173f1d4e1buzbee char buf2[100]; 3405de3494e4297c0d480409da3fecee39173f1d4e1buzbee snprintf(buf2, 100, "V[%02d] -> %s%d%s", i, 3415de3494e4297c0d480409da3fecee39173f1d4e1buzbee vRegMap.coreLocation == kLocPhysReg ? 3425de3494e4297c0d480409da3fecee39173f1d4e1buzbee "r" : "SP+", vRegMap.coreLocation == kLocPhysReg ? 3435de3494e4297c0d480409da3fecee39173f1d4e1buzbee vRegMap.coreReg : oatSRegOffset(cUnit, i), buf); 3445de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << buf2; 3455de3494e4297c0d480409da3fecee39173f1d4e1buzbee } 3465de3494e4297c0d480409da3fecee39173f1d4e1buzbee} 3475de3494e4297c0d480409da3fecee39173f1d4e1buzbee 3485de3494e4297c0d480409da3fecee39173f1d4e1buzbeevoid oatDumpFullPromotionMap(CompilationUnit *cUnit) 3495de3494e4297c0d480409da3fecee39173f1d4e1buzbee{ 3505de3494e4297c0d480409da3fecee39173f1d4e1buzbee for (int i = 0; i < cUnit->numDalvikRegisters; i++) { 3515de3494e4297c0d480409da3fecee39173f1d4e1buzbee PromotionMap vRegMap = cUnit->promotionMap[i]; 3525de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << i << " -> " << "CL:" << (int)vRegMap.coreLocation << 3535de3494e4297c0d480409da3fecee39173f1d4e1buzbee ", CR:" << (int)vRegMap.coreReg << ", FL:" << 3545de3494e4297c0d480409da3fecee39173f1d4e1buzbee (int)vRegMap.fpLocation << ", FR:" << (int)vRegMap.fpReg << 3555de3494e4297c0d480409da3fecee39173f1d4e1buzbee ", - " << (int)vRegMap.firstInPair; 3565de3494e4297c0d480409da3fecee39173f1d4e1buzbee } 3575de3494e4297c0d480409da3fecee39173f1d4e1buzbee} 3585de3494e4297c0d480409da3fecee39173f1d4e1buzbee 3595de3494e4297c0d480409da3fecee39173f1d4e1buzbee/* Dump instructions and constant pool contents */ 3605de3494e4297c0d480409da3fecee39173f1d4e1buzbeevoid oatCodegenDump(CompilationUnit* cUnit) 3615de3494e4297c0d480409da3fecee39173f1d4e1buzbee{ 3625de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "/*"; 3635de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "Dumping LIR insns for " 3645de3494e4297c0d480409da3fecee39173f1d4e1buzbee << PrettyMethod(cUnit->method_idx, *cUnit->dex_file); 3655de3494e4297c0d480409da3fecee39173f1d4e1buzbee LIR* lirInsn; 3665de3494e4297c0d480409da3fecee39173f1d4e1buzbee LIR* thisLIR; 3675de3494e4297c0d480409da3fecee39173f1d4e1buzbee int insnsSize = cUnit->insnsSize; 3685de3494e4297c0d480409da3fecee39173f1d4e1buzbee 3695de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "Regs (excluding ins) : " << cUnit->numRegs; 3705de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "Ins : " << cUnit->numIns; 3715de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "Outs : " << cUnit->numOuts; 3725de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "CoreSpills : " << cUnit->numCoreSpills; 3735de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "FPSpills : " << cUnit->numFPSpills; 3745de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "Frame size : " << cUnit->frameSize; 3755de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "code size is " << cUnit->totalSize << 3765de3494e4297c0d480409da3fecee39173f1d4e1buzbee " bytes, Dalvik size is " << insnsSize * 2; 3775de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << "expansion factor: " << 3785de3494e4297c0d480409da3fecee39173f1d4e1buzbee (float)cUnit->totalSize / (float)(insnsSize * 2); 3795de3494e4297c0d480409da3fecee39173f1d4e1buzbee oatDumpPromotionMap(cUnit); 3805de3494e4297c0d480409da3fecee39173f1d4e1buzbee for (lirInsn = cUnit->firstLIRInsn; lirInsn; lirInsn = lirInsn->next) { 3815de3494e4297c0d480409da3fecee39173f1d4e1buzbee oatDumpLIRInsn(cUnit, lirInsn, 0); 3825de3494e4297c0d480409da3fecee39173f1d4e1buzbee } 3835de3494e4297c0d480409da3fecee39173f1d4e1buzbee for (lirInsn = cUnit->classPointerList; lirInsn; lirInsn = lirInsn->next) { 3845de3494e4297c0d480409da3fecee39173f1d4e1buzbee thisLIR = (LIR*) lirInsn; 3855de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << StringPrintf("%x (%04x): .class (%s)", 3865de3494e4297c0d480409da3fecee39173f1d4e1buzbee thisLIR->offset, thisLIR->offset, 3875de3494e4297c0d480409da3fecee39173f1d4e1buzbee ((CallsiteInfo *) thisLIR->operands[0])->classDescriptor); 3885de3494e4297c0d480409da3fecee39173f1d4e1buzbee } 3895de3494e4297c0d480409da3fecee39173f1d4e1buzbee for (lirInsn = cUnit->literalList; lirInsn; lirInsn = lirInsn->next) { 3905de3494e4297c0d480409da3fecee39173f1d4e1buzbee thisLIR = (LIR*) lirInsn; 3915de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << StringPrintf("%x (%04x): .word (%#x)", 3925de3494e4297c0d480409da3fecee39173f1d4e1buzbee thisLIR->offset, thisLIR->offset, thisLIR->operands[0]); 3935de3494e4297c0d480409da3fecee39173f1d4e1buzbee } 3945de3494e4297c0d480409da3fecee39173f1d4e1buzbee 3955de3494e4297c0d480409da3fecee39173f1d4e1buzbee const DexFile::MethodId& method_id = 3965de3494e4297c0d480409da3fecee39173f1d4e1buzbee cUnit->dex_file->GetMethodId(cUnit->method_idx); 3975de3494e4297c0d480409da3fecee39173f1d4e1buzbee std::string signature(cUnit->dex_file->GetMethodSignature(method_id)); 3985de3494e4297c0d480409da3fecee39173f1d4e1buzbee std::string name(cUnit->dex_file->GetMethodName(method_id)); 3995de3494e4297c0d480409da3fecee39173f1d4e1buzbee std::string descriptor(cUnit->dex_file->GetMethodDeclaringClassDescriptor(method_id)); 4005de3494e4297c0d480409da3fecee39173f1d4e1buzbee 4015de3494e4297c0d480409da3fecee39173f1d4e1buzbee // Dump mapping table 4025de3494e4297c0d480409da3fecee39173f1d4e1buzbee if (cUnit->mappingTable.size() > 0) { 4035de3494e4297c0d480409da3fecee39173f1d4e1buzbee std::string line(StringPrintf("\n MappingTable %s%s_%s_mappingTable[%zu] = {", 4045de3494e4297c0d480409da3fecee39173f1d4e1buzbee descriptor.c_str(), name.c_str(), signature.c_str(), cUnit->mappingTable.size())); 4055de3494e4297c0d480409da3fecee39173f1d4e1buzbee std::replace(line.begin(), line.end(), ';', '_'); 4065de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << line; 4075de3494e4297c0d480409da3fecee39173f1d4e1buzbee for (uint32_t i = 0; i < cUnit->mappingTable.size(); i+=2) { 40882488f563e7f72f8c626052893c1792d76ab3fafbuzbee line = StringPrintf(" {0x%05x, 0x%04x},", 4095de3494e4297c0d480409da3fecee39173f1d4e1buzbee cUnit->mappingTable[i], cUnit->mappingTable[i+1]); 4105de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) << line; 4115de3494e4297c0d480409da3fecee39173f1d4e1buzbee } 4125de3494e4297c0d480409da3fecee39173f1d4e1buzbee LOG(INFO) <<" };\n\n"; 4135de3494e4297c0d480409da3fecee39173f1d4e1buzbee } 4145de3494e4297c0d480409da3fecee39173f1d4e1buzbee} 4155de3494e4297c0d480409da3fecee39173f1d4e1buzbee 416a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee 417a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbeeLIR* rawLIR(CompilationUnit* cUnit, int dalvikOffset, int opcode, int op0, 418b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers int op1, int op2, int op3, int op4, LIR* target) 41931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 42031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee LIR* insn = (LIR* ) oatNew(cUnit, sizeof(LIR), true, kAllocLIR); 421a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee insn->dalvikOffset = dalvikOffset; 42231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee insn->opcode = opcode; 423a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee insn->operands[0] = op0; 424a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee insn->operands[1] = op1; 425a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee insn->operands[2] = op2; 426a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee insn->operands[3] = op3; 427b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers insn->operands[4] = op4; 428a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee insn->target = target; 429a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee oatSetupResourceMasks(insn); 430c5159d55ca8e9022b748176f9f53676e8e9d4cd2buzbee if (opcode == kPseudoTargetLabel) { 431c5159d55ca8e9022b748176f9f53676e8e9d4cd2buzbee // Always make labels scheduling barriers 432c5159d55ca8e9022b748176f9f53676e8e9d4cd2buzbee insn->defMask = ENCODE_ALL; 433c5159d55ca8e9022b748176f9f53676e8e9d4cd2buzbee } 434a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee return insn; 435a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee} 436a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee 437a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee/* 438a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee * The following are building blocks to construct low-level IRs with 0 - 4 439a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee * operands. 440a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee */ 441a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbeeLIR* newLIR0(CompilationUnit* cUnit, int opcode) 442a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee{ 443b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & NO_OPERAND)) 444b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers << EncodingMap[opcode].name << " " << (int)opcode << " " 445b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers << PrettyMethod(cUnit->method_idx, *cUnit->dex_file) << " " 446b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers << cUnit->currentDalvikOffset; 447a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee LIR* insn = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode); 44831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee oatAppendLIR(cUnit, (LIR*) insn); 44931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee return insn; 45031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 45131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 4525de3494e4297c0d480409da3fecee39173f1d4e1buzbeeLIR* newLIR1(CompilationUnit* cUnit, int opcode, 45331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int dest) 45431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 455b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & IS_UNARY_OP)) 456b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers << EncodingMap[opcode].name << " " << (int)opcode << " " 457b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers << PrettyMethod(cUnit->method_idx, *cUnit->dex_file) << " " 458b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers << cUnit->currentDalvikOffset; 459a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee LIR* insn = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, dest); 46031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee oatAppendLIR(cUnit, (LIR*) insn); 46131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee return insn; 46231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 46331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 4645de3494e4297c0d480409da3fecee39173f1d4e1buzbeeLIR* newLIR2(CompilationUnit* cUnit, int opcode, 46531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int dest, int src1) 46631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 467b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & IS_BINARY_OP)) 468b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers << EncodingMap[opcode].name << " " << (int)opcode << " " 469b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers << PrettyMethod(cUnit->method_idx, *cUnit->dex_file) << " " 470b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers << cUnit->currentDalvikOffset; 471a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee LIR* insn = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, dest, src1); 47231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee oatAppendLIR(cUnit, (LIR*) insn); 47331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee return insn; 47431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 47531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 4765de3494e4297c0d480409da3fecee39173f1d4e1buzbeeLIR* newLIR3(CompilationUnit* cUnit, int opcode, 47731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int dest, int src1, int src2) 47831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 479b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & IS_TERTIARY_OP)) 480b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers << EncodingMap[opcode].name << " " << (int)opcode << " " 481b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers << PrettyMethod(cUnit->method_idx, *cUnit->dex_file) << " " 482b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers << cUnit->currentDalvikOffset; 483a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee LIR* insn = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, dest, src1, 484a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee src2); 48531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee oatAppendLIR(cUnit, (LIR*) insn); 48631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee return insn; 48731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 48831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 4895de3494e4297c0d480409da3fecee39173f1d4e1buzbeeLIR* newLIR4(CompilationUnit* cUnit, int opcode, 490b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers int dest, int src1, int src2, int info) 49131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 492b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & IS_QUAD_OP)) 493b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers << EncodingMap[opcode].name << " " << (int)opcode << " " 494b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers << PrettyMethod(cUnit->method_idx, *cUnit->dex_file) << " " 495b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers << cUnit->currentDalvikOffset; 496a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee LIR* insn = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, dest, src1, 497a2ebdd74eb2f36e6efa7a482bc11c7b93d97c2c3buzbee src2, info); 49831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee oatAppendLIR(cUnit, (LIR*) insn); 49931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee return insn; 50031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 50131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 502b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian RogersLIR* newLIR5(CompilationUnit* cUnit, int opcode, 503b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers int dest, int src1, int src2, int info1, int info2) 504b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers{ 505b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & IS_QUIN_OP)) 506b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers << EncodingMap[opcode].name << " " << (int)opcode << " " 507b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers << PrettyMethod(cUnit->method_idx, *cUnit->dex_file) << " " 508b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers << cUnit->currentDalvikOffset; 509b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers LIR* insn = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, dest, src1, 510b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers src2, info1, info2); 511b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers oatAppendLIR(cUnit, (LIR*) insn); 512b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return insn; 513b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers} 514b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 51531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 51631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Search the existing constants in the literal pool for an exact or close match 51731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * within specified delta (greater or equal to 0). 51831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 51931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeeLIR* scanLiteralPool(LIR* dataTarget, int value, unsigned int delta) 52031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 52131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee while (dataTarget) { 52231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (((unsigned) (value - ((LIR* ) dataTarget)->operands[0])) <= 52331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee delta) 52431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee return (LIR* ) dataTarget; 52531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee dataTarget = dataTarget->next; 52631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 52731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee return NULL; 52831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 52931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 53031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* Search the existing constants in the literal pool for an exact wide match */ 53131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeeLIR* scanLiteralPoolWide(LIR* dataTarget, int valLo, int valHi) 53231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 53331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee bool loMatch = false; 53431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee LIR* loTarget = NULL; 53531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee while (dataTarget) { 53631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (loMatch && (((LIR*)dataTarget)->operands[0] == valHi)) { 53731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee return (LIR*)loTarget; 53831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 53931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee loMatch = false; 54031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (((LIR*)dataTarget)->operands[0] == valLo) { 54131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee loMatch = true; 54231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee loTarget = dataTarget; 54331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 54431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee dataTarget = dataTarget->next; 54531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 54631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee return NULL; 54731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 54831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 54931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 55031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * The following are building blocks to insert constants into the pool or 55131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * instruction streams. 55231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 55331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 5545de3494e4297c0d480409da3fecee39173f1d4e1buzbee/* Add a 32-bit constant either in the constant pool */ 55531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeeLIR* addWordData(CompilationUnit* cUnit, LIR* *constantListP, 55631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int value) 55731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 55831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee /* Add the constant to the literal pool */ 55931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (constantListP) { 56031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee LIR* newValue = (LIR* ) oatNew(cUnit, sizeof(LIR), true, 56131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee kAllocData); 56231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee newValue->operands[0] = value; 56331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee newValue->next = *constantListP; 56431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee *constantListP = (LIR*) newValue; 56531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee return newValue; 56631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 56731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee return NULL; 56831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 56931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 57031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* Add a 64-bit constant to the constant pool or mixed with code */ 57131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeeLIR* addWideData(CompilationUnit* cUnit, LIR* *constantListP, 57231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int valLo, int valHi) 57331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 57431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee //FIXME: hard-coded little endian, need BE variant 5755de3494e4297c0d480409da3fecee39173f1d4e1buzbee // Insert high word into list first 5765de3494e4297c0d480409da3fecee39173f1d4e1buzbee addWordData(cUnit, constantListP, valHi); 5775de3494e4297c0d480409da3fecee39173f1d4e1buzbee return addWordData(cUnit, constantListP, valLo); 57831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 57931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 580ab058bb04d11ed086116d95f2d55bf6b35e8cc35Ian Rogersvoid pushWord(std::vector<uint8_t>&buf, int data) { 581ab058bb04d11ed086116d95f2d55bf6b35e8cc35Ian Rogers buf.push_back( data & 0xff); 582ab058bb04d11ed086116d95f2d55bf6b35e8cc35Ian Rogers buf.push_back( (data >> 8) & 0xff); 583ab058bb04d11ed086116d95f2d55bf6b35e8cc35Ian Rogers buf.push_back( (data >> 16) & 0xff); 584ab058bb04d11ed086116d95f2d55bf6b35e8cc35Ian Rogers buf.push_back( (data >> 24) & 0xff); 585e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 586e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 587ab058bb04d11ed086116d95f2d55bf6b35e8cc35Ian Rogersvoid alignBuffer(std::vector<uint8_t>&buf, size_t offset) { 588ab058bb04d11ed086116d95f2d55bf6b35e8cc35Ian Rogers while (buf.size() < offset) { 589e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee buf.push_back(0); 590ab058bb04d11ed086116d95f2d55bf6b35e8cc35Ian Rogers } 591e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 592e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 593e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the literal pool to the output stream */ 59431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeevoid installLiteralPools(CompilationUnit* cUnit) 595e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee{ 596e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee alignBuffer(cUnit->codeBuffer, cUnit->dataOffset); 59731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee LIR* dataLIR = (LIR*) cUnit->literalList; 598e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee while (dataLIR != NULL) { 599e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee pushWord(cUnit->codeBuffer, dataLIR->operands[0]); 600e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee dataLIR = NEXT_LIR(dataLIR); 601e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 602e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 603e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 604e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the switch tables to the output stream */ 60531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeevoid installSwitchTables(CompilationUnit* cUnit) 606e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee{ 607e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee GrowableListIterator iterator; 608e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee oatGrowableListIteratorInit(&cUnit->switchTables, &iterator); 609e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee while (true) { 610e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee SwitchTable* tabRec = (SwitchTable *) oatGrowableListIteratorNext( 611e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee &iterator); 612e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee if (tabRec == NULL) break; 613e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee alignBuffer(cUnit->codeBuffer, tabRec->offset); 614c5159d55ca8e9022b748176f9f53676e8e9d4cd2buzbee /* 615c5159d55ca8e9022b748176f9f53676e8e9d4cd2buzbee * For Arm, our reference point is the address of the bx 616c5159d55ca8e9022b748176f9f53676e8e9d4cd2buzbee * instruction that does the launch, so we have to subtract 617c5159d55ca8e9022b748176f9f53676e8e9d4cd2buzbee * the auto pc-advance. For other targets the reference point 618c5159d55ca8e9022b748176f9f53676e8e9d4cd2buzbee * is a label, so we can use the offset as-is. 619c5159d55ca8e9022b748176f9f53676e8e9d4cd2buzbee */ 620c5159d55ca8e9022b748176f9f53676e8e9d4cd2buzbee#if defined(TARGET_ARM) 621c5159d55ca8e9022b748176f9f53676e8e9d4cd2buzbee int bxOffset = tabRec->anchor->offset + 4; 622c5159d55ca8e9022b748176f9f53676e8e9d4cd2buzbee#else 623c5159d55ca8e9022b748176f9f53676e8e9d4cd2buzbee int bxOffset = tabRec->anchor->offset; 624c5159d55ca8e9022b748176f9f53676e8e9d4cd2buzbee#endif 625e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee if (cUnit->printMe) { 626e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee LOG(INFO) << "Switch table for offset 0x" << std::hex << bxOffset; 627e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 628adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes if (tabRec->table[0] == Instruction::kSparseSwitchSignature) { 629e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee int* keys = (int*)&(tabRec->table[2]); 630e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee for (int elems = 0; elems < tabRec->table[1]; elems++) { 63131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int disp = tabRec->targets[elems]->offset - bxOffset; 632e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee if (cUnit->printMe) { 633e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee LOG(INFO) << " Case[" << elems << "] key: 0x" << 634e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee std::hex << keys[elems] << ", disp: 0x" << 635e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee std::hex << disp; 636e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 637e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee pushWord(cUnit->codeBuffer, keys[elems]); 638e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee pushWord(cUnit->codeBuffer, 63931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee tabRec->targets[elems]->offset - bxOffset); 640e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 641e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } else { 642adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes DCHECK_EQ(static_cast<int>(tabRec->table[0]), static_cast<int>(Instruction::kPackedSwitchSignature)); 643e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee for (int elems = 0; elems < tabRec->table[1]; elems++) { 64431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int disp = tabRec->targets[elems]->offset - bxOffset; 645e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee if (cUnit->printMe) { 646e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee LOG(INFO) << " Case[" << elems << "] disp: 0x" << 647e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee std::hex << disp; 648e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 649e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee pushWord(cUnit->codeBuffer, 65031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee tabRec->targets[elems]->offset - bxOffset); 651e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 652e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 653e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 654e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 655e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 656e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the fill array dta to the output stream */ 65731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeevoid installFillArrayData(CompilationUnit* cUnit) 658e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee{ 659e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee GrowableListIterator iterator; 660e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee oatGrowableListIteratorInit(&cUnit->fillArrayData, &iterator); 661e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee while (true) { 662e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee FillArrayData *tabRec = (FillArrayData *) oatGrowableListIteratorNext( 663e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee &iterator); 664e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee if (tabRec == NULL) break; 665e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee alignBuffer(cUnit->codeBuffer, tabRec->offset); 666ab058bb04d11ed086116d95f2d55bf6b35e8cc35Ian Rogers for (int i = 0; i < (tabRec->size + 1) / 2; i++) { 667ab058bb04d11ed086116d95f2d55bf6b35e8cc35Ian Rogers cUnit->codeBuffer.push_back( tabRec->table[i] & 0xFF); 668ab058bb04d11ed086116d95f2d55bf6b35e8cc35Ian Rogers cUnit->codeBuffer.push_back( (tabRec->table[i] >> 8) & 0xFF); 669e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 670e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 671e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 672e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 67331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeeint assignLiteralOffsetCommon(LIR* lir, int offset) 674e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee{ 675e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee for (;lir != NULL; lir = lir->next) { 676e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee lir->offset = offset; 677e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee offset += 4; 678e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 679e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee return offset; 680e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 681e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 68231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeevoid createMappingTable(CompilationUnit* cUnit) 683e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee{ 68431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee LIR* tgtLIR; 685e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee int currentDalvikOffset = -1; 686e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 68731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee for (tgtLIR = (LIR *) cUnit->firstLIRInsn; 688e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee tgtLIR; 689e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee tgtLIR = NEXT_LIR(tgtLIR)) { 690e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee if ((tgtLIR->opcode >= 0) && !tgtLIR->flags.isNop && 69131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee (currentDalvikOffset != tgtLIR->dalvikOffset)) { 692e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee // Changed - need to emit a record 69331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee cUnit->mappingTable.push_back(tgtLIR->offset); 69431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee cUnit->mappingTable.push_back(tgtLIR->dalvikOffset); 69531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee currentDalvikOffset = tgtLIR->dalvikOffset; 696e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 697e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 698e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 699e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 700e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Determine the offset of each literal field */ 70131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeeint assignLiteralOffset(CompilationUnit* cUnit, int offset) 702e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee{ 703e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee offset = assignLiteralOffsetCommon(cUnit->literalList, offset); 704e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee return offset; 705e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 706e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 70731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeeint assignSwitchTablesOffset(CompilationUnit* cUnit, int offset) 708e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee{ 709e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee GrowableListIterator iterator; 710e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee oatGrowableListIteratorInit(&cUnit->switchTables, &iterator); 711e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee while (true) { 712e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee SwitchTable *tabRec = (SwitchTable *) oatGrowableListIteratorNext( 713e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee &iterator); 714e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee if (tabRec == NULL) break; 715e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee tabRec->offset = offset; 716adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes if (tabRec->table[0] == Instruction::kSparseSwitchSignature) { 717e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee offset += tabRec->table[1] * (sizeof(int) * 2); 718e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } else { 719adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes DCHECK_EQ(static_cast<int>(tabRec->table[0]), static_cast<int>(Instruction::kPackedSwitchSignature)); 720e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee offset += tabRec->table[1] * sizeof(int); 721e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 722e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 723e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee return offset; 724e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 725e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 72631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeeint assignFillArrayDataOffset(CompilationUnit* cUnit, int offset) 727e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee{ 728e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee GrowableListIterator iterator; 729e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee oatGrowableListIteratorInit(&cUnit->fillArrayData, &iterator); 730e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee while (true) { 731e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee FillArrayData *tabRec = (FillArrayData *) oatGrowableListIteratorNext( 732e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee &iterator); 733e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee if (tabRec == NULL) break; 734e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee tabRec->offset = offset; 735e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee offset += tabRec->size; 736e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee // word align 737e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee offset = (offset + 3) & ~3; 738e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 739e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee return offset; 740e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 741e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 742e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* 743e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Walk the compilation unit and assign offsets to instructions 744e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * and literals and compute the total size of the compiled unit. 745e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee */ 746e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbeevoid oatAssignOffsets(CompilationUnit* cUnit) 747e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee{ 748e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee int offset = oatAssignInsnOffsets(cUnit); 749e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 750e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee /* Const values have to be word aligned */ 751e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee offset = (offset + 3) & ~3; 752e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 753e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee /* Set up offsets for literals */ 754e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee cUnit->dataOffset = offset; 755e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 756e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee offset = assignLiteralOffset(cUnit, offset); 757e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 758e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee offset = assignSwitchTablesOffset(cUnit, offset); 759e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 760e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee offset = assignFillArrayDataOffset(cUnit, offset); 761e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 762e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee cUnit->totalSize = offset; 763e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 764e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 765e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* 766e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Go over each instruction in the list and calculate the offset from the top 767e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * before sending them off to the assembler. If out-of-range branch distance is 768e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * seen rearrange the instructions a bit to correct it. 769e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee */ 770e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbeevoid oatAssembleLIR(CompilationUnit* cUnit) 771e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee{ 772e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee oatAssignOffsets(cUnit); 773e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee /* 774e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Assemble here. Note that we generate code with optimistic assumptions 775e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * and if found now to work, we'll have to redo the sequence and retry. 776e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee */ 777e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 778e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee while (true) { 779e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee AssemblerStatus res = oatAssembleInstructions(cUnit, 0); 780e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee if (res == kSuccess) { 781e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee break; 782e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } else { 783e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee cUnit->assemblerRetries++; 784e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee if (cUnit->assemblerRetries > MAX_ASSEMBLER_RETRIES) { 785e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee LOG(FATAL) << "Assembler error - too many retries"; 786e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 787e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee // Redo offsets and try again 788e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee oatAssignOffsets(cUnit); 789e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee cUnit->codeBuffer.clear(); 790e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 791e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 792e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 793e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee // Install literals 794e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee installLiteralPools(cUnit); 795e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 796e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee // Install switch tables 797e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee installSwitchTables(cUnit); 798e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 799e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee // Install fill array data 800e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee installFillArrayData(cUnit); 801e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 802e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee /* 803e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Create the mapping table 804e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee */ 805e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee createMappingTable(cUnit); 806e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 807e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 80831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 80931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Insert a kPseudoCaseLabel at the beginning of the Dalvik 81031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * offset vaddr. This label will be used to fix up the case 81131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * branch table during the assembly phase. Be sure to set 81231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * all resource flags on this to prevent code motion across 81331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * target boundaries. KeyVal is just there for debugging. 81431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 81531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeeLIR* insertCaseLabel(CompilationUnit* cUnit, int vaddr, int keyVal) 81631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 81731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee std::map<unsigned int, LIR*>::iterator it; 81831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee it = cUnit->boundaryMap.find(vaddr); 81931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (it == cUnit->boundaryMap.end()) { 82031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee LOG(FATAL) << "Error: didn't find vaddr 0x" << std::hex << vaddr; 82131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 82231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee LIR* newLabel = (LIR*)oatNew(cUnit, sizeof(LIR), true, kAllocLIR); 82331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee newLabel->dalvikOffset = vaddr; 82431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee newLabel->opcode = kPseudoCaseLabel; 82531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee newLabel->operands[0] = keyVal; 82631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee oatInsertLIRAfter(it->second, (LIR*)newLabel); 82731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee return newLabel; 82831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 82931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 83031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeevoid markPackedCaseLabels(CompilationUnit* cUnit, SwitchTable *tabRec) 83131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 83231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee const u2* table = tabRec->table; 83331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int baseVaddr = tabRec->vaddr; 83431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int *targets = (int*)&table[4]; 83531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int entries = table[1]; 83631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int lowKey = s4FromSwitchData(&table[2]); 83731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee for (int i = 0; i < entries; i++) { 83831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee tabRec->targets[i] = insertCaseLabel(cUnit, baseVaddr + targets[i], 83931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee i + lowKey); 84031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 84131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 84231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 84331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeevoid markSparseCaseLabels(CompilationUnit* cUnit, SwitchTable *tabRec) 84431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 84531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee const u2* table = tabRec->table; 84631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int baseVaddr = tabRec->vaddr; 84731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int entries = table[1]; 84831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int* keys = (int*)&table[2]; 84931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int* targets = &keys[entries]; 85031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee for (int i = 0; i < entries; i++) { 85131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee tabRec->targets[i] = insertCaseLabel(cUnit, baseVaddr + targets[i], 85231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee keys[i]); 85331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 85431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 85531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 85631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeevoid oatProcessSwitchTables(CompilationUnit* cUnit) 85731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 85831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee GrowableListIterator iterator; 85931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee oatGrowableListIteratorInit(&cUnit->switchTables, &iterator); 86031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee while (true) { 86131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee SwitchTable *tabRec = (SwitchTable *) oatGrowableListIteratorNext( 86231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee &iterator); 86331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee if (tabRec == NULL) break; 864adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes if (tabRec->table[0] == Instruction::kPackedSwitchSignature) { 86531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee markPackedCaseLabels(cUnit, tabRec); 866adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes } else if (tabRec->table[0] == Instruction::kSparseSwitchSignature) { 86731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee markSparseCaseLabels(cUnit, tabRec); 868adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes } else { 86931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee LOG(FATAL) << "Invalid switch table"; 87031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 87131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 87231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 87331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 87431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee//FIXME: Do we have endian issues here? 87531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 87631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeevoid dumpSparseSwitchTable(const u2* table) 87731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee /* 87831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Sparse switch data format: 87931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * ushort ident = 0x0200 magic value 88031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * ushort size number of entries in the table; > 0 88131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * int keys[size] keys, sorted low-to-high; 32-bit aligned 88231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * int targets[size] branch targets, relative to switch opcode 88331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * 88431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Total size is (2+size*4) 16-bit code units. 88531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 88631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 88731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee u2 ident = table[0]; 88831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int entries = table[1]; 88931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int* keys = (int*)&table[2]; 89031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int* targets = &keys[entries]; 89131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee LOG(INFO) << "Sparse switch table - ident:0x" << std::hex << ident << 89231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee ", entries: " << std::dec << entries; 89331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee for (int i = 0; i < entries; i++) { 89431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee LOG(INFO) << " Key[" << keys[i] << "] -> 0x" << std::hex << 89531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee targets[i]; 89631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 89731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 89831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 89931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeevoid dumpPackedSwitchTable(const u2* table) 90031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee /* 90131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Packed switch data format: 90231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * ushort ident = 0x0100 magic value 90331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * ushort size number of entries in the table 90431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * int first_key first (and lowest) switch case value 90531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * int targets[size] branch targets, relative to switch opcode 90631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * 90731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Total size is (4+size*2) 16-bit code units. 90831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 90931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee{ 91031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee u2 ident = table[0]; 91131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int* targets = (int*)&table[4]; 91231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int entries = table[1]; 91331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee int lowKey = s4FromSwitchData(&table[2]); 91431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee LOG(INFO) << "Packed switch table - ident:0x" << std::hex << ident << 91531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee ", entries: " << std::dec << entries << ", lowKey: " << lowKey; 91631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee for (int i = 0; i < entries; i++) { 91731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee LOG(INFO) << " Key[" << (i + lowKey) << "] -> 0x" << std::hex << 91831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee targets[i]; 91931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 92031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 921e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 922e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 923e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} // namespace art 924