codegen_util.cc revision 69dfe51b684dd9d510dbcb63295fe180f998efde
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 177940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/compiler_internals.h" 184f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h" 190c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "gc_map.h" 2092cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray#include "gc_map_builder.h" 2196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers#include "mapping_table.h" 228d3a117b374352a1853fae9b7306afeaaa9e3b91Ian Rogers#include "mir_to_lir-inl.h" 235816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko#include "dex/quick/dex_file_method_inliner.h" 245816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko#include "dex/quick/dex_file_to_method_inliner_map.h" 25c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "dex/verification_results.h" 262730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko#include "dex/verified_method.h" 270c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "verifier/dex_gc_map.h" 280c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "verifier/method_verifier.h" 292e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko#include "vmap_table.h" 300c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 31e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbeenamespace art { 32e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 3306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Markonamespace { 3406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 3506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko/* Dump a mapping table */ 3606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Markotemplate <typename It> 3706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Markovoid DumpMappingTable(const char* table_name, const char* descriptor, const char* name, 3806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko const Signature& signature, uint32_t size, It first) { 3906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (size != 0) { 40107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers std::string line(StringPrintf("\n %s %s%s_%s_table[%u] = {", table_name, 4106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko descriptor, name, signature.ToString().c_str(), size)); 4206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko std::replace(line.begin(), line.end(), ';', '_'); 4306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) << line; 4406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (uint32_t i = 0; i != size; ++i) { 4506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko line = StringPrintf(" {0x%05x, 0x%04x},", first.NativePcOffset(), first.DexPc()); 4606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++first; 4706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) << line; 4806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 4906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) <<" };\n\n"; 5006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 5106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko} 5206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 5306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko} // anonymous namespace 5406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 552ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::IsInexpensiveConstant(RegLocation rl_src) { 564ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee bool res = false; 574ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (rl_src.is_const) { 584ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (rl_src.wide) { 594ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (rl_src.fp) { 601fd3346740dfb7f47be9922312b68a4227fada96buzbee res = InexpensiveConstantDouble(mir_graph_->ConstantValueWide(rl_src)); 614ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } else { 621fd3346740dfb7f47be9922312b68a4227fada96buzbee res = InexpensiveConstantLong(mir_graph_->ConstantValueWide(rl_src)); 634ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 644ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } else { 654ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (rl_src.fp) { 661fd3346740dfb7f47be9922312b68a4227fada96buzbee res = InexpensiveConstantFloat(mir_graph_->ConstantValue(rl_src)); 674ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } else { 681fd3346740dfb7f47be9922312b68a4227fada96buzbee res = InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src)); 694ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 704ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 714ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 724ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return res; 734ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 744ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 752ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::MarkSafepointPC(LIR* inst) { 76b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK(!inst->flags.use_def_invalid); 778dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko inst->u.m.def_mask = &kEncodeAll; 781fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* safepoint_pc = NewLIR0(kPseudoSafepointPC); 798dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko DCHECK(safepoint_pc->u.m.def_mask->Equals(kEncodeAll)); 8002031b185b4653e6c72e21f7a51238b903f6d638buzbee} 8102031b185b4653e6c72e21f7a51238b903f6d638buzbee 823c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampevoid Mir2Lir::MarkSafepointPCAfter(LIR* after) { 833c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe DCHECK(!after->flags.use_def_invalid); 843c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe after->u.m.def_mask = &kEncodeAll; 853c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe // As NewLIR0 uses Append, we need to create the LIR by hand. 863c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe LIR* safepoint_pc = RawLIR(current_dalvik_offset_, kPseudoSafepointPC); 873c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe if (after->next == nullptr) { 883c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe DCHECK_EQ(after, last_lir_insn_); 893c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe AppendLIR(safepoint_pc); 903c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe } else { 913c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe InsertLIRAfter(after, safepoint_pc); 923c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe } 933c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe DCHECK(safepoint_pc->u.m.def_mask->Equals(kEncodeAll)); 943c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe} 953c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe 96252254b130067cd7a5071865e793966871ae0246buzbee/* Remove a LIR from the list. */ 97252254b130067cd7a5071865e793966871ae0246buzbeevoid Mir2Lir::UnlinkLIR(LIR* lir) { 98252254b130067cd7a5071865e793966871ae0246buzbee if (UNLIKELY(lir == first_lir_insn_)) { 99252254b130067cd7a5071865e793966871ae0246buzbee first_lir_insn_ = lir->next; 100252254b130067cd7a5071865e793966871ae0246buzbee if (lir->next != NULL) { 101252254b130067cd7a5071865e793966871ae0246buzbee lir->next->prev = NULL; 102252254b130067cd7a5071865e793966871ae0246buzbee } else { 103252254b130067cd7a5071865e793966871ae0246buzbee DCHECK(lir->next == NULL); 104252254b130067cd7a5071865e793966871ae0246buzbee DCHECK(lir == last_lir_insn_); 105252254b130067cd7a5071865e793966871ae0246buzbee last_lir_insn_ = NULL; 106252254b130067cd7a5071865e793966871ae0246buzbee } 107252254b130067cd7a5071865e793966871ae0246buzbee } else if (lir == last_lir_insn_) { 108252254b130067cd7a5071865e793966871ae0246buzbee last_lir_insn_ = lir->prev; 109252254b130067cd7a5071865e793966871ae0246buzbee lir->prev->next = NULL; 110252254b130067cd7a5071865e793966871ae0246buzbee } else if ((lir->prev != NULL) && (lir->next != NULL)) { 111252254b130067cd7a5071865e793966871ae0246buzbee lir->prev->next = lir->next; 112252254b130067cd7a5071865e793966871ae0246buzbee lir->next->prev = lir->prev; 113252254b130067cd7a5071865e793966871ae0246buzbee } 114252254b130067cd7a5071865e793966871ae0246buzbee} 115252254b130067cd7a5071865e793966871ae0246buzbee 116cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee/* Convert an instruction to a NOP */ 117df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstromvoid Mir2Lir::NopLIR(LIR* lir) { 118fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lir->flags.is_nop = true; 119252254b130067cd7a5071865e793966871ae0246buzbee if (!cu_->verbose) { 120252254b130067cd7a5071865e793966871ae0246buzbee UnlinkLIR(lir); 121252254b130067cd7a5071865e793966871ae0246buzbee } 122cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee} 123cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee 1242ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::SetMemRefType(LIR* lir, bool is_load, int mem_type) { 1251fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK(GetTargetInstFlags(lir->opcode) & (IS_LOAD | IS_STORE)); 126b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK(!lir->flags.use_def_invalid); 1278dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko // TODO: Avoid the extra Arena allocation! 1288dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko const ResourceMask** mask_ptr; 1298dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko ResourceMask mask; 130fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (is_load) { 131b48819db07f9a0992a72173380c24249d7fc648abuzbee mask_ptr = &lir->u.m.use_mask; 132a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 133b48819db07f9a0992a72173380c24249d7fc648abuzbee mask_ptr = &lir->u.m.def_mask; 134a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 1358dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko mask = **mask_ptr; 136a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Clear out the memref flags */ 1378dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko mask.ClearBits(kEncodeMem); 138a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* ..and then add back the one we need */ 139fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee switch (mem_type) { 1408dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko case ResourceMask::kLiteral: 141fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(is_load); 1428dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko mask.SetBit(ResourceMask::kLiteral); 143a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 1448dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko case ResourceMask::kDalvikReg: 1458dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko mask.SetBit(ResourceMask::kDalvikReg); 146a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 1478dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko case ResourceMask::kHeapRef: 1488dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko mask.SetBit(ResourceMask::kHeapRef); 149a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 1508dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko case ResourceMask::kMustNotAlias: 151a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Currently only loads can be marked as kMustNotAlias */ 1521fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK(!(GetTargetInstFlags(lir->opcode) & IS_STORE)); 1538dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko mask.SetBit(ResourceMask::kMustNotAlias); 154a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 155a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 156fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(FATAL) << "Oat: invalid memref kind - " << mem_type; 157a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 1588dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko *mask_ptr = mask_cache_.GetMask(mask); 15931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 16031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 16131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 162b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers * Mark load/store instructions that access Dalvik registers through the stack. 16331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 1641fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::AnnotateDalvikRegAccess(LIR* lir, int reg_id, bool is_load, 1652ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom bool is64bit) { 1668dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko DCHECK((is_load ? lir->u.m.use_mask : lir->u.m.def_mask)->Intersection(kEncodeMem).Equals( 1678dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko kEncodeDalvikReg)); 16831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 169a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 170fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * Store the Dalvik register id in alias_info. Mark the MSB if it is a 64-bit 171a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * access. 172a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 173b48819db07f9a0992a72173380c24249d7fc648abuzbee lir->flags.alias_info = ENCODE_ALIAS_INFO(reg_id, is64bit); 17431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 17531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 17631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 1775de3494e4297c0d480409da3fecee39173f1d4e1buzbee * Debugging macros 1785de3494e4297c0d480409da3fecee39173f1d4e1buzbee */ 1795de3494e4297c0d480409da3fecee39173f1d4e1buzbee#define DUMP_RESOURCE_MASK(X) 1805de3494e4297c0d480409da3fecee39173f1d4e1buzbee 1815de3494e4297c0d480409da3fecee39173f1d4e1buzbee/* Pretty-print a LIR instruction */ 1822ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpLIRInsn(LIR* lir, unsigned char* base_addr) { 183a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int offset = lir->offset; 184a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int dest = lir->operands[0]; 1851fd3346740dfb7f47be9922312b68a4227fada96buzbee const bool dump_nop = (cu_->enable_debug & (1 << kDebugShowNops)); 186a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 187a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Handle pseudo-ops individually, and all regular insns as a group */ 188a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee switch (lir->opcode) { 189a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoMethodEntry: 190a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- method entry " 1911fd3346740dfb7f47be9922312b68a4227fada96buzbee << PrettyMethod(cu_->method_idx, *cu_->dex_file); 192a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 193a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoMethodExit: 194a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- Method_Exit"; 195a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 196a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoBarrier: 197a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- BARRIER"; 198a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 199a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoEntryBlock: 200a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- entry offset: 0x" << std::hex << dest; 201a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 202a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoDalvikByteCodeBoundary: 2034ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (lir->operands[0] == 0) { 2040d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // NOTE: only used for debug listings. 2050d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee lir->operands[0] = WrapPointer(ArenaStrdup("No instruction string")); 2064ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 207a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- dalvik offset: 0x" << std::hex 2080b1191cfece83f6f8d4101575a06555a2d13387aBill Buzbee << lir->dalvik_offset << " @ " 2090b1191cfece83f6f8d4101575a06555a2d13387aBill Buzbee << reinterpret_cast<char*>(UnwrapPointer(lir->operands[0])); 210a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 211a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoExitBlock: 212a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "-------- exit offset: 0x" << std::hex << dest; 213a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 214a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoPseudoAlign4: 215fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << reinterpret_cast<uintptr_t>(base_addr) + offset << " (0x" << std::hex 216a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << offset << "): .align4"; 217a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 218a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoEHBlockLabel: 219a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "Exception_Handling:"; 220a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 221a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoTargetLabel: 222a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoNormalBlockLabel: 223cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "L" << reinterpret_cast<void*>(lir) << ":"; 224a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 225a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoThrowTarget: 226cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "LT" << reinterpret_cast<void*>(lir) << ":"; 227a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 228a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoIntrinsicRetry: 229cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "IR" << reinterpret_cast<void*>(lir) << ":"; 230a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 231a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoSuspendTarget: 232cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "LS" << reinterpret_cast<void*>(lir) << ":"; 233a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 2348320f3867c02bae9bef6cdab267820cb7b412781buzbee case kPseudoSafepointPC: 235fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << "LsafepointPC_0x" << std::hex << lir->offset << "_" << lir->dalvik_offset << ":"; 2368320f3867c02bae9bef6cdab267820cb7b412781buzbee break; 237a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee case kPseudoExportedPC: 238fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << "LexportedPC_0x" << std::hex << lir->offset << "_" << lir->dalvik_offset << ":"; 239a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee break; 240a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee case kPseudoCaseLabel: 241cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee LOG(INFO) << "LC" << reinterpret_cast<void*>(lir) << ": Case target 0x" 242a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << std::hex << lir->operands[0] << "|" << std::dec << 243a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee lir->operands[0]; 244a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 245a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee default: 246fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (lir->flags.is_nop && !dump_nop) { 247a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 248a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 2491fd3346740dfb7f47be9922312b68a4227fada96buzbee std::string op_name(BuildInsnString(GetTargetInstName(lir->opcode), 25002031b185b4653e6c72e21f7a51238b903f6d638buzbee lir, base_addr)); 2511fd3346740dfb7f47be9922312b68a4227fada96buzbee std::string op_operands(BuildInsnString(GetTargetInstFmt(lir->opcode), 25202031b185b4653e6c72e21f7a51238b903f6d638buzbee lir, base_addr)); 253107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers LOG(INFO) << StringPrintf("%5p: %-9s%s%s", 254107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers base_addr + offset, 255a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee op_name.c_str(), op_operands.c_str(), 256fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lir->flags.is_nop ? "(nop)" : ""); 257a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 258a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee break; 259a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 260a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 261b48819db07f9a0992a72173380c24249d7fc648abuzbee if (lir->u.m.use_mask && (!lir->flags.is_nop || dump_nop)) { 2628dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko DUMP_RESOURCE_MASK(DumpResourceMask(lir, *lir->u.m.use_mask, "use")); 263a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 264b48819db07f9a0992a72173380c24249d7fc648abuzbee if (lir->u.m.def_mask && (!lir->flags.is_nop || dump_nop)) { 2658dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko DUMP_RESOURCE_MASK(DumpResourceMask(lir, *lir->u.m.def_mask, "def")); 266a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 2675de3494e4297c0d480409da3fecee39173f1d4e1buzbee} 2685de3494e4297c0d480409da3fecee39173f1d4e1buzbee 2692ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpPromotionMap() { 270da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru int num_regs = cu_->num_dalvik_registers + mir_graph_->GetNumUsedCompilerTemps(); 271fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int i = 0; i < num_regs; i++) { 2721fd3346740dfb7f47be9922312b68a4227fada96buzbee PromotionMap v_reg_map = promotion_map_[i]; 273a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee std::string buf; 274fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (v_reg_map.fp_location == kLocPhysReg) { 275b5860fb459f1ed71f39d8a87b45bee6727d79fe8buzbee StringAppendF(&buf, " : s%d", RegStorage::RegNum(v_reg_map.fp_reg)); 276a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 2779c044ce5f76e9bfa17c4c1979e9f8c99ae100695buzbee 278a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee std::string buf3; 2791fd3346740dfb7f47be9922312b68a4227fada96buzbee if (i < cu_->num_dalvik_registers) { 280a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee StringAppendF(&buf3, "%02d", i); 2811fd3346740dfb7f47be9922312b68a4227fada96buzbee } else if (i == mir_graph_->GetMethodSReg()) { 282a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee buf3 = "Method*"; 283a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 2841fd3346740dfb7f47be9922312b68a4227fada96buzbee StringAppendF(&buf3, "ct%d", i - cu_->num_dalvik_registers); 2855de3494e4297c0d480409da3fecee39173f1d4e1buzbee } 286a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 287a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << StringPrintf("V[%s] -> %s%d%s", buf3.c_str(), 288fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee v_reg_map.core_location == kLocPhysReg ? 289fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee "r" : "SP+", v_reg_map.core_location == kLocPhysReg ? 2901fd3346740dfb7f47be9922312b68a4227fada96buzbee v_reg_map.core_reg : SRegOffset(i), 291a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee buf.c_str()); 292a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 2935de3494e4297c0d480409da3fecee39173f1d4e1buzbee} 2945de3494e4297c0d480409da3fecee39173f1d4e1buzbee 2957a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbeevoid Mir2Lir::UpdateLIROffsets() { 2967a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee // Only used for code listings. 2977a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee size_t offset = 0; 2987a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee for (LIR* lir = first_lir_insn_; lir != nullptr; lir = lir->next) { 2997a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee lir->offset = offset; 3007a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee if (!lir->flags.is_nop && !IsPseudoLirOp(lir->opcode)) { 3017a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee offset += GetInsnSize(lir); 3027a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee } else if (lir->opcode == kPseudoPseudoAlign4) { 3037a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee offset += (offset & 0x2); 3047a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee } 3057a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee } 3067a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee} 3077a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee 3085de3494e4297c0d480409da3fecee39173f1d4e1buzbee/* Dump instructions and constant pool contents */ 3092ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::CodegenDump() { 310a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "Dumping LIR insns for " 3111fd3346740dfb7f47be9922312b68a4227fada96buzbee << PrettyMethod(cu_->method_idx, *cu_->dex_file); 312fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR* lir_insn; 3131fd3346740dfb7f47be9922312b68a4227fada96buzbee int insns_size = cu_->code_item->insns_size_in_code_units_; 3141fd3346740dfb7f47be9922312b68a4227fada96buzbee 3151fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Regs (excluding ins) : " << cu_->num_regs; 3161fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Ins : " << cu_->num_ins; 3171fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Outs : " << cu_->num_outs; 3181fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "CoreSpills : " << num_core_spills_; 3191fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "FPSpills : " << num_fp_spills_; 320da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru LOG(INFO) << "CompilerTemps : " << mir_graph_->GetNumUsedCompilerTemps(); 3211fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Frame size : " << frame_size_; 3221fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "code size is " << total_size_ << 323fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee " bytes, Dalvik size is " << insns_size * 2; 324a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "expansion factor: " 3251fd3346740dfb7f47be9922312b68a4227fada96buzbee << static_cast<float>(total_size_) / static_cast<float>(insns_size * 2); 3261fd3346740dfb7f47be9922312b68a4227fada96buzbee DumpPromotionMap(); 3277a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee UpdateLIROffsets(); 3281fd3346740dfb7f47be9922312b68a4227fada96buzbee for (lir_insn = first_lir_insn_; lir_insn != NULL; lir_insn = lir_insn->next) { 3291fd3346740dfb7f47be9922312b68a4227fada96buzbee DumpLIRInsn(lir_insn, 0); 330a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 3311fd3346740dfb7f47be9922312b68a4227fada96buzbee for (lir_insn = literal_list_; lir_insn != NULL; lir_insn = lir_insn->next) { 332fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << StringPrintf("%x (%04x): .word (%#x)", lir_insn->offset, lir_insn->offset, 333fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lir_insn->operands[0]); 334a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 335a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 336a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee const DexFile::MethodId& method_id = 3371fd3346740dfb7f47be9922312b68a4227fada96buzbee cu_->dex_file->GetMethodId(cu_->method_idx); 338d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers const Signature signature = cu_->dex_file->GetMethodSignature(method_id); 339d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers const char* name = cu_->dex_file->GetMethodName(method_id); 340d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers const char* descriptor(cu_->dex_file->GetMethodDeclaringClassDescriptor(method_id)); 341a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee 342a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee // Dump mapping tables 34306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!encoded_mapping_table_.empty()) { 34406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko MappingTable table(&encoded_mapping_table_[0]); 34506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DumpMappingTable("PC2Dex_MappingTable", descriptor, name, signature, 34606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko table.PcToDexSize(), table.PcToDexBegin()); 34706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DumpMappingTable("Dex2PC_MappingTable", descriptor, name, signature, 34806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko table.DexToPcSize(), table.DexToPcBegin()); 34906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 3505de3494e4297c0d480409da3fecee39173f1d4e1buzbee} 3515de3494e4297c0d480409da3fecee39173f1d4e1buzbee 35231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 35331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Search the existing constants in the literal pool for an exact or close match 35431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * within specified delta (greater or equal to 0). 35531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 3562ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::ScanLiteralPool(LIR* data_target, int value, unsigned int delta) { 357fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_target) { 358fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if ((static_cast<unsigned>(value - data_target->operands[0])) <= delta) 359fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return data_target; 360fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_target = data_target->next; 361a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 362a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return NULL; 36331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 36431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 36531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* Search the existing constants in the literal pool for an exact wide match */ 3662ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::ScanLiteralPoolWide(LIR* data_target, int val_lo, int val_hi) { 367fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool lo_match = false; 368fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR* lo_target = NULL; 369fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_target) { 370fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (lo_match && (data_target->operands[0] == val_hi)) { 3714ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee // Record high word in case we need to expand this later. 3724ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee lo_target->operands[1] = val_hi; 373fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return lo_target; 37431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 375fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lo_match = false; 376fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (data_target->operands[0] == val_lo) { 377fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lo_match = true; 378fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee lo_target = data_target; 379a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 380fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_target = data_target->next; 381a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 382a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return NULL; 38331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 38431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 385a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko/* Search the existing constants in the literal pool for an exact method match */ 386a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir MarkoLIR* Mir2Lir::ScanLiteralPoolMethod(LIR* data_target, const MethodReference& method) { 387a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko while (data_target) { 388a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko if (static_cast<uint32_t>(data_target->operands[0]) == method.dex_method_index && 389a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko UnwrapPointer(data_target->operands[1]) == method.dex_file) { 390a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko return data_target; 391a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko } 392a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko data_target = data_target->next; 393a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko } 394a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko return nullptr; 395a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko} 396a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko 39731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 39831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * The following are building blocks to insert constants into the pool or 39931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * instruction streams. 40031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 40131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 4024ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee/* Add a 32-bit constant to the constant pool */ 4032ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::AddWordData(LIR* *constant_list_p, int value) { 404a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* Add the constant to the literal pool */ 405fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (constant_list_p) { 40683cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko LIR* new_value = static_cast<LIR*>(arena_->Alloc(sizeof(LIR), kArenaAllocData)); 407fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee new_value->operands[0] = value; 408fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee new_value->next = *constant_list_p; 409fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee *constant_list_p = new_value; 410b48819db07f9a0992a72173380c24249d7fc648abuzbee estimated_native_code_size_ += sizeof(value); 411fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return new_value; 412a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 413a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return NULL; 41431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 41531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 41631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* Add a 64-bit constant to the constant pool or mixed with code */ 4172ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::AddWideData(LIR* *constant_list_p, int val_lo, int val_hi) { 4181fd3346740dfb7f47be9922312b68a4227fada96buzbee AddWordData(constant_list_p, val_hi); 4191fd3346740dfb7f47be9922312b68a4227fada96buzbee return AddWordData(constant_list_p, val_lo); 42031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 42131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 4222da882315a61072664f7ce3c212307342e907207Andreas Gampestatic void Push32(std::vector<uint8_t>&buf, int data) { 423df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom buf.push_back(data & 0xff); 424df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom buf.push_back((data >> 8) & 0xff); 425df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom buf.push_back((data >> 16) & 0xff); 426df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom buf.push_back((data >> 24) & 0xff); 427e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 428e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 4292da882315a61072664f7ce3c212307342e907207Andreas Gampe// Push 8 bytes on 64-bit target systems; 4 on 32-bit target systems. 4302da882315a61072664f7ce3c212307342e907207Andreas Gampestatic void PushPointer(std::vector<uint8_t>&buf, const void* pointer, bool target64) { 4312da882315a61072664f7ce3c212307342e907207Andreas Gampe uint64_t data = reinterpret_cast<uintptr_t>(pointer); 4322da882315a61072664f7ce3c212307342e907207Andreas Gampe if (target64) { 4332da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(buf, data & 0xFFFFFFFF); 4342da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(buf, (data >> 32) & 0xFFFFFFFF); 4350d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee } else { 4362da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(buf, static_cast<uint32_t>(data)); 4370d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee } 4380d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee} 4390d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee 440aad94383fc41e8f8770f0b2144f766a2ffa772e7buzbeestatic void AlignBuffer(std::vector<uint8_t>&buf, size_t offset) { 441a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (buf.size() < offset) { 442a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee buf.push_back(0); 443a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 444e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 445e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 446e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the literal pool to the output stream */ 4472ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallLiteralPools() { 4481fd3346740dfb7f47be9922312b68a4227fada96buzbee AlignBuffer(code_buffer_, data_offset_); 4491fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* data_lir = literal_list_; 450fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_lir != NULL) { 4512da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(code_buffer_, data_lir->operands[0]); 452fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_lir = NEXT_LIR(data_lir); 453a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 454a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee // Push code and method literals, record offsets for the compiler to patch. 4551fd3346740dfb7f47be9922312b68a4227fada96buzbee data_lir = code_literal_list_; 456fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_lir != NULL) { 45749161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao uint32_t target_method_idx = data_lir->operands[0]; 45849161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao const DexFile* target_dex_file = 45949161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao reinterpret_cast<const DexFile*>(UnwrapPointer(data_lir->operands[1])); 4601fd3346740dfb7f47be9922312b68a4227fada96buzbee cu_->compiler_driver->AddCodePatch(cu_->dex_file, 4618b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->class_def_idx, 4628b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->method_idx, 4638b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->invoke_type, 46449161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao target_method_idx, 46549161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao target_dex_file, 46649161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao static_cast<InvokeType>(data_lir->operands[2]), 4678b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers code_buffer_.size()); 46849161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao const DexFile::MethodId& target_method_id = target_dex_file->GetMethodId(target_method_idx); 4690d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // unique value based on target to ensure code deduplication works 47049161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao PushPointer(code_buffer_, &target_method_id, cu_->target64); 471fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_lir = NEXT_LIR(data_lir); 472137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers } 4731fd3346740dfb7f47be9922312b68a4227fada96buzbee data_lir = method_literal_list_; 474fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee while (data_lir != NULL) { 47549161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao uint32_t target_method_idx = data_lir->operands[0]; 47649161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao const DexFile* target_dex_file = 47749161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao reinterpret_cast<const DexFile*>(UnwrapPointer(data_lir->operands[1])); 4781fd3346740dfb7f47be9922312b68a4227fada96buzbee cu_->compiler_driver->AddMethodPatch(cu_->dex_file, 4798b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->class_def_idx, 4808b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->method_idx, 4818b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers cu_->invoke_type, 48249161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao target_method_idx, 48349161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao target_dex_file, 48449161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao static_cast<InvokeType>(data_lir->operands[2]), 4858b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers code_buffer_.size()); 48649161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao const DexFile::MethodId& target_method_id = target_dex_file->GetMethodId(target_method_idx); 4870d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // unique value based on target to ensure code deduplication works 48849161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao PushPointer(code_buffer_, &target_method_id, cu_->target64); 489fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee data_lir = NEXT_LIR(data_lir); 490a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 491be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi // Push class literals. 492be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi data_lir = class_literal_list_; 493be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi while (data_lir != NULL) { 49449161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao uint32_t target_method_idx = data_lir->operands[0]; 495be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi cu_->compiler_driver->AddClassPatch(cu_->dex_file, 496be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi cu_->class_def_idx, 497be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi cu_->method_idx, 49849161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao target_method_idx, 499be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi code_buffer_.size()); 50049161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao const DexFile::TypeId& target_method_id = cu_->dex_file->GetTypeId(target_method_idx); 501be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi // unique value based on target to ensure code deduplication works 50249161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao PushPointer(code_buffer_, &target_method_id, cu_->target64); 503be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi data_lir = NEXT_LIR(data_lir); 504be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi } 505e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 506e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 507e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the switch tables to the output stream */ 5082ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallSwitchTables() { 509862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_); 510a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 511862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee Mir2Lir::SwitchTable* tab_rec = iterator.Next(); 512fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 5131fd3346740dfb7f47be9922312b68a4227fada96buzbee AlignBuffer(code_buffer_, tab_rec->offset); 514a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 515a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * For Arm, our reference point is the address of the bx 516a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * instruction that does the launch, so we have to subtract 517a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * the auto pc-advance. For other targets the reference point 518a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * is a label, so we can use the offset as-is. 519a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 520fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int bx_offset = INVALID_OFFSET; 5211fd3346740dfb7f47be9922312b68a4227fada96buzbee switch (cu_->instruction_set) { 522b046e16d8b8da318d6055f9308950131f1255e08buzbee case kThumb2: 523b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK(tab_rec->anchor->flags.fixup != kFixupNone); 524fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bx_offset = tab_rec->anchor->offset + 4; 525b046e16d8b8da318d6055f9308950131f1255e08buzbee break; 526b046e16d8b8da318d6055f9308950131f1255e08buzbee case kX86: 5276a58cb16d803c9a7b3a75ccac8be19dd9d4e520dDmitry Petrochenko case kX86_64: 528fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bx_offset = 0; 529b046e16d8b8da318d6055f9308950131f1255e08buzbee break; 530e45fb9e7976c8462b94a58ad60b006b0eacec49fMatteo Franchin case kArm64: 531b046e16d8b8da318d6055f9308950131f1255e08buzbee case kMips: 532fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bx_offset = tab_rec->anchor->offset; 533b046e16d8b8da318d6055f9308950131f1255e08buzbee break; 5341fd3346740dfb7f47be9922312b68a4227fada96buzbee default: LOG(FATAL) << "Unexpected instruction set: " << cu_->instruction_set; 535b046e16d8b8da318d6055f9308950131f1255e08buzbee } 5361fd3346740dfb7f47be9922312b68a4227fada96buzbee if (cu_->verbose) { 537fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << "Switch table for offset 0x" << std::hex << bx_offset; 538a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 539fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) { 5400d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* keys = reinterpret_cast<const int32_t*>(&(tab_rec->table[2])); 541fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int elems = 0; elems < tab_rec->table[1]; elems++) { 542fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int disp = tab_rec->targets[elems]->offset - bx_offset; 5431fd3346740dfb7f47be9922312b68a4227fada96buzbee if (cu_->verbose) { 544a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << " Case[" << elems << "] key: 0x" 545a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << std::hex << keys[elems] << ", disp: 0x" 546a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << std::hex << disp; 547e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 5482da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(code_buffer_, keys[elems]); 5492da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(code_buffer_, 550fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee tab_rec->targets[elems]->offset - bx_offset); 551a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 552a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 553fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ(static_cast<int>(tab_rec->table[0]), 554a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee static_cast<int>(Instruction::kPackedSwitchSignature)); 555fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int elems = 0; elems < tab_rec->table[1]; elems++) { 556fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int disp = tab_rec->targets[elems]->offset - bx_offset; 5571fd3346740dfb7f47be9922312b68a4227fada96buzbee if (cu_->verbose) { 558a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << " Case[" << elems << "] disp: 0x" 559a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << std::hex << disp; 560e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 5612da882315a61072664f7ce3c212307342e907207Andreas Gampe Push32(code_buffer_, tab_rec->targets[elems]->offset - bx_offset); 562a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 563e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 564a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 565e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 566e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 567e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the fill array dta to the output stream */ 5682ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallFillArrayData() { 569862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<FillArrayData*>::Iterator iterator(&fill_array_data_); 570a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 571862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee Mir2Lir::FillArrayData *tab_rec = iterator.Next(); 572fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 5731fd3346740dfb7f47be9922312b68a4227fada96buzbee AlignBuffer(code_buffer_, tab_rec->offset); 574fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee for (int i = 0; i < (tab_rec->size + 1) / 2; i++) { 575df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom code_buffer_.push_back(tab_rec->table[i] & 0xFF); 576df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom code_buffer_.push_back((tab_rec->table[i] >> 8) & 0xFF); 577e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 578a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 579e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 580e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 5810d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeestatic int AssignLiteralOffsetCommon(LIR* lir, CodeOffset offset) { 58202c8cc6d1312a2b55533f02f6369dc7c94672f90Brian Carlstrom for (; lir != NULL; lir = lir->next) { 583a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee lir->offset = offset; 584a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee offset += 4; 585a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 586a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return offset; 587e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 588e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 589ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogersstatic int AssignLiteralPointerOffsetCommon(LIR* lir, CodeOffset offset, 590ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers unsigned int element_size) { 5910d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // Align to natural pointer size. 592660188264dee3c8f3510e2e24c11816c6b60f197Andreas Gampe offset = RoundUp(offset, element_size); 5930d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee for (; lir != NULL; lir = lir->next) { 5940d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee lir->offset = offset; 5950d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee offset += element_size; 5960d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee } 5970d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee return offset; 5980d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee} 5990d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee 6006459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee// Make sure we have a code address for every declared catch entry 6012ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::VerifyCatchEntries() { 60206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko MappingTable table(&encoded_mapping_table_[0]); 60306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko std::vector<uint32_t> dex_pcs; 60406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex_pcs.reserve(table.DexToPcSize()); 60506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (auto it = table.DexToPcBegin(), end = table.DexToPcEnd(); it != end; ++it) { 60606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex_pcs.push_back(it.DexPc()); 60706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 60806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko // Sort dex_pcs, so that we can quickly check it against the ordered mir_graph_->catches_. 60906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko std::sort(dex_pcs.begin(), dex_pcs.end()); 61006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 6116459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee bool success = true; 61206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko auto it = dex_pcs.begin(), end = dex_pcs.end(); 61306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (uint32_t dex_pc : mir_graph_->catches_) { 61406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko while (it != end && *it < dex_pc) { 61506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) << "Unexpected catch entry @ dex pc 0x" << std::hex << *it; 61606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++it; 6176459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee success = false; 6186459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee } 61906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (it == end || *it > dex_pc) { 62006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko LOG(INFO) << "Missing native PC for catch entry @ 0x" << std::hex << dex_pc; 6216459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee success = false; 62206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } else { 62306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++it; 6246459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee } 6256459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee } 6266459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee if (!success) { 6271fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Bad dex2pcMapping table in " << PrettyMethod(cu_->method_idx, *cu_->dex_file); 6281fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Entries @ decode: " << mir_graph_->catches_.size() << ", Entries in table: " 62906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko << table.DexToPcSize(); 6306459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee } 6316459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee return success; 6326459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee} 6336459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee 634311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 6352ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::CreateMappingTables() { 6361e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t pc2dex_data_size = 0u; 6371e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t pc2dex_entries = 0u; 6381e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t pc2dex_offset = 0u; 6391e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t pc2dex_dalvik_offset = 0u; 6401e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t dex2pc_data_size = 0u; 6411e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t dex2pc_entries = 0u; 6421e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t dex2pc_offset = 0u; 6431e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t dex2pc_dalvik_offset = 0u; 6441fd3346740dfb7f47be9922312b68a4227fada96buzbee for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) { 645fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) { 6461e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_entries += 1; 6471e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko DCHECK(pc2dex_offset <= tgt_lir->offset); 6481e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_data_size += UnsignedLeb128Size(tgt_lir->offset - pc2dex_offset); 6491e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_data_size += SignedLeb128Size(static_cast<int32_t>(tgt_lir->dalvik_offset) - 6501e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko static_cast<int32_t>(pc2dex_dalvik_offset)); 6511e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_offset = tgt_lir->offset; 6521e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_dalvik_offset = tgt_lir->dalvik_offset; 653a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee } 654fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) { 6551e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_entries += 1; 6561e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko DCHECK(dex2pc_offset <= tgt_lir->offset); 6571e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_data_size += UnsignedLeb128Size(tgt_lir->offset - dex2pc_offset); 6581e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_data_size += SignedLeb128Size(static_cast<int32_t>(tgt_lir->dalvik_offset) - 6591e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko static_cast<int32_t>(dex2pc_dalvik_offset)); 6601e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_offset = tgt_lir->offset; 6611e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko dex2pc_dalvik_offset = tgt_lir->dalvik_offset; 662e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 663a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 6641e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko 6651e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t total_entries = pc2dex_entries + dex2pc_entries; 6661e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t hdr_data_size = UnsignedLeb128Size(total_entries) + UnsignedLeb128Size(pc2dex_entries); 6671e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko uint32_t data_size = hdr_data_size + pc2dex_data_size + dex2pc_data_size; 66806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko encoded_mapping_table_.resize(data_size); 66906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint8_t* write_pos = &encoded_mapping_table_[0]; 67006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos = EncodeUnsignedLeb128(write_pos, total_entries); 67106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos = EncodeUnsignedLeb128(write_pos, pc2dex_entries); 67206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK_EQ(static_cast<size_t>(write_pos - &encoded_mapping_table_[0]), hdr_data_size); 67306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint8_t* write_pos2 = write_pos + pc2dex_data_size; 6741e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko 6751e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_offset = 0u; 6761e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko pc2dex_dalvik_offset = 0u; 67706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex2pc_offset = 0u; 67806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex2pc_dalvik_offset = 0u; 67906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) { 68006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) { 68106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK(pc2dex_offset <= tgt_lir->offset); 68206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos = EncodeUnsignedLeb128(write_pos, tgt_lir->offset - pc2dex_offset); 68306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos = EncodeSignedLeb128(write_pos, static_cast<int32_t>(tgt_lir->dalvik_offset) - 68406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko static_cast<int32_t>(pc2dex_dalvik_offset)); 68506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko pc2dex_offset = tgt_lir->offset; 68606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko pc2dex_dalvik_offset = tgt_lir->dalvik_offset; 68706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 68806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) { 68906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK(dex2pc_offset <= tgt_lir->offset); 69006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos2 = EncodeUnsignedLeb128(write_pos2, tgt_lir->offset - dex2pc_offset); 69106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko write_pos2 = EncodeSignedLeb128(write_pos2, static_cast<int32_t>(tgt_lir->dalvik_offset) - 69206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko static_cast<int32_t>(dex2pc_dalvik_offset)); 69306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex2pc_offset = tgt_lir->offset; 69406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko dex2pc_dalvik_offset = tgt_lir->dalvik_offset; 69506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 6961e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko } 69706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK_EQ(static_cast<size_t>(write_pos - &encoded_mapping_table_[0]), 69806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko hdr_data_size + pc2dex_data_size); 69906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK_EQ(static_cast<size_t>(write_pos2 - &encoded_mapping_table_[0]), data_size); 7001e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko 70196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers if (kIsDebugBuild) { 70206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK(VerifyCatchEntries()); 70306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko 70496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers // Verify the encoded table holds the expected data. 70506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko MappingTable table(&encoded_mapping_table_[0]); 70696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers CHECK_EQ(table.TotalSize(), total_entries); 70796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers CHECK_EQ(table.PcToDexSize(), pc2dex_entries); 7081e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko auto it = table.PcToDexBegin(); 7091e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko auto it2 = table.DexToPcBegin(); 71006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) { 71106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) { 71206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK_EQ(tgt_lir->offset, it.NativePcOffset()); 71306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK_EQ(tgt_lir->dalvik_offset, it.DexPc()); 71406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++it; 71506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 71606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) { 71706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK_EQ(tgt_lir->offset, it2.NativePcOffset()); 71806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK_EQ(tgt_lir->dalvik_offset, it2.DexPc()); 71906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko ++it2; 72006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko } 72196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers } 72206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko CHECK(it == table.PcToDexEnd()); 7231e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko CHECK(it2 == table.DexToPcEnd()); 724311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 725e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 726e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 7271fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::CreateNativeGcMap() { 72806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko DCHECK(!encoded_mapping_table_.empty()); 72906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko MappingTable mapping_table(&encoded_mapping_table_[0]); 7300c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers uint32_t max_native_offset = 0; 73106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (auto it = mapping_table.PcToDexBegin(), end = mapping_table.PcToDexEnd(); it != end; ++it) { 73206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint32_t native_offset = it.NativePcOffset(); 7330c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers if (native_offset > max_native_offset) { 7340c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers max_native_offset = native_offset; 7350c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 7360c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 73751c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom MethodReference method_ref(cu_->dex_file, cu_->method_idx); 7382730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko const std::vector<uint8_t>& gc_map_raw = 7392730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko mir_graph_->GetCurrentDexCompilationUnit()->GetVerifiedMethod()->GetDexGcMap(); 7402730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko verifier::DexPcToReferenceMap dex_gc_map(&(gc_map_raw)[0]); 7412730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko DCHECK_EQ(gc_map_raw.size(), dex_gc_map.RawSize()); 7420c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers // Compute native offset to references size. 74392cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray GcMapBuilder native_gc_map_builder(&native_gc_map_, 74492cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray mapping_table.PcToDexSize(), 74592cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray max_native_offset, dex_gc_map.RegWidth()); 7460c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 74706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko for (auto it = mapping_table.PcToDexBegin(), end = mapping_table.PcToDexEnd(); it != end; ++it) { 74806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint32_t native_offset = it.NativePcOffset(); 74906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko uint32_t dex_pc = it.DexPc(); 7500c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers const uint8_t* references = dex_gc_map.FindBitMap(dex_pc, false); 751f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison CHECK(references != NULL) << "Missing ref for dex pc 0x" << std::hex << dex_pc << 752f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison ": " << PrettyMethod(cu_->method_idx, *cu_->dex_file); 753a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee native_gc_map_builder.AddEntry(native_offset, references); 7540c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers } 7550c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers} 7560c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers 757e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Determine the offset of each literal field */ 7580d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignLiteralOffset(CodeOffset offset) { 7591fd3346740dfb7f47be9922312b68a4227fada96buzbee offset = AssignLiteralOffsetCommon(literal_list_, offset); 760ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers unsigned int ptr_size = GetInstructionSetPointerSize(cu_->instruction_set); 761ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers offset = AssignLiteralPointerOffsetCommon(code_literal_list_, offset, ptr_size); 762ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers offset = AssignLiteralPointerOffsetCommon(method_literal_list_, offset, ptr_size); 763ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers offset = AssignLiteralPointerOffsetCommon(class_literal_list_, offset, ptr_size); 764a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return offset; 765e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 766e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 7670d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignSwitchTablesOffset(CodeOffset offset) { 768862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_); 769a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 7700d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee Mir2Lir::SwitchTable* tab_rec = iterator.Next(); 771fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 772fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee tab_rec->offset = offset; 773fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) { 774fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee offset += tab_rec->table[1] * (sizeof(int) * 2); 775a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 776fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ(static_cast<int>(tab_rec->table[0]), 777a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee static_cast<int>(Instruction::kPackedSwitchSignature)); 778fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee offset += tab_rec->table[1] * sizeof(int); 779e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee } 780a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 781a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return offset; 782e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 783e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 7840d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignFillArrayDataOffset(CodeOffset offset) { 785862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<FillArrayData*>::Iterator iterator(&fill_array_data_); 786a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 787862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee Mir2Lir::FillArrayData *tab_rec = iterator.Next(); 788fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 789fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee tab_rec->offset = offset; 790fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee offset += tab_rec->size; 791a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee // word align 792660188264dee3c8f3510e2e24c11816c6b60f197Andreas Gampe offset = RoundUp(offset, 4); 793a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 794a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return offset; 795e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee} 796e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 79731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* 79831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Insert a kPseudoCaseLabel at the beginning of the Dalvik 799b48819db07f9a0992a72173380c24249d7fc648abuzbee * offset vaddr if pretty-printing, otherise use the standard block 800b48819db07f9a0992a72173380c24249d7fc648abuzbee * label. The selected label will be used to fix up the case 801252254b130067cd7a5071865e793966871ae0246buzbee * branch table during the assembly phase. All resource flags 802252254b130067cd7a5071865e793966871ae0246buzbee * are set to prevent code motion. KeyVal is just there for debugging. 80331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */ 8040d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeLIR* Mir2Lir::InsertCaseLabel(DexOffset vaddr, int keyVal) { 805252254b130067cd7a5071865e793966871ae0246buzbee LIR* boundary_lir = &block_label_list_[mir_graph_->FindBlock(vaddr)->id]; 806b48819db07f9a0992a72173380c24249d7fc648abuzbee LIR* res = boundary_lir; 807b48819db07f9a0992a72173380c24249d7fc648abuzbee if (cu_->verbose) { 808b48819db07f9a0992a72173380c24249d7fc648abuzbee // Only pay the expense if we're pretty-printing. 80983cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko LIR* new_label = static_cast<LIR*>(arena_->Alloc(sizeof(LIR), kArenaAllocLIR)); 810b48819db07f9a0992a72173380c24249d7fc648abuzbee new_label->dalvik_offset = vaddr; 811b48819db07f9a0992a72173380c24249d7fc648abuzbee new_label->opcode = kPseudoCaseLabel; 812b48819db07f9a0992a72173380c24249d7fc648abuzbee new_label->operands[0] = keyVal; 813b48819db07f9a0992a72173380c24249d7fc648abuzbee new_label->flags.fixup = kFixupLabel; 814b48819db07f9a0992a72173380c24249d7fc648abuzbee DCHECK(!new_label->flags.use_def_invalid); 8158dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko new_label->u.m.def_mask = &kEncodeAll; 816b48819db07f9a0992a72173380c24249d7fc648abuzbee InsertLIRAfter(boundary_lir, new_label); 817b48819db07f9a0992a72173380c24249d7fc648abuzbee res = new_label; 818b48819db07f9a0992a72173380c24249d7fc648abuzbee } 819b48819db07f9a0992a72173380c24249d7fc648abuzbee return res; 82031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 82131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 8220d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkPackedCaseLabels(Mir2Lir::SwitchTable* tab_rec) { 823fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee const uint16_t* table = tab_rec->table; 8240d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset base_vaddr = tab_rec->vaddr; 8250d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t *targets = reinterpret_cast<const int32_t*>(&table[4]); 826a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int entries = table[1]; 827fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int low_key = s4FromSwitchData(&table[2]); 828a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee for (int i = 0; i < entries; i++) { 8291fd3346740dfb7f47be9922312b68a4227fada96buzbee tab_rec->targets[i] = InsertCaseLabel(base_vaddr + targets[i], i + low_key); 830a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 83131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 83231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 8330d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkSparseCaseLabels(Mir2Lir::SwitchTable* tab_rec) { 834fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee const uint16_t* table = tab_rec->table; 8350d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset base_vaddr = tab_rec->vaddr; 836a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int entries = table[1]; 8370d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* keys = reinterpret_cast<const int32_t*>(&table[2]); 8380d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* targets = &keys[entries]; 839a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee for (int i = 0; i < entries; i++) { 8401fd3346740dfb7f47be9922312b68a4227fada96buzbee tab_rec->targets[i] = InsertCaseLabel(base_vaddr + targets[i], keys[i]); 841a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 84231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 84331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 8442ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::ProcessSwitchTables() { 845862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_); 846a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee while (true) { 847862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee Mir2Lir::SwitchTable *tab_rec = iterator.Next(); 848fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec == NULL) break; 849fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (tab_rec->table[0] == Instruction::kPackedSwitchSignature) { 8501fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkPackedCaseLabels(tab_rec); 851fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) { 8521fd3346740dfb7f47be9922312b68a4227fada96buzbee MarkSparseCaseLabels(tab_rec); 853a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 854a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(FATAL) << "Invalid switch table"; 85531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee } 856a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 85731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 85831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 8592ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpSparseSwitchTable(const uint16_t* table) { 860a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 861a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Sparse switch data format: 862a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * ushort ident = 0x0200 magic value 863a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * ushort size number of entries in the table; > 0 864a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * int keys[size] keys, sorted low-to-high; 32-bit aligned 865a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * int targets[size] branch targets, relative to switch opcode 866a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * 867a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Total size is (2+size*4) 16-bit code units. 868a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 869eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee uint16_t ident = table[0]; 870a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int entries = table[1]; 8710d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* keys = reinterpret_cast<const int32_t*>(&table[2]); 8720d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* targets = &keys[entries]; 873a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "Sparse switch table - ident:0x" << std::hex << ident 874a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << ", entries: " << std::dec << entries; 875a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee for (int i = 0; i < entries; i++) { 876a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << " Key[" << keys[i] << "] -> 0x" << std::hex << targets[i]; 877a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 87831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 87931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee 8802ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpPackedSwitchTable(const uint16_t* table) { 881a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* 882a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Packed switch data format: 883a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * ushort ident = 0x0100 magic value 884a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * ushort size number of entries in the table 885a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * int first_key first (and lowest) switch case value 886a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * int targets[size] branch targets, relative to switch opcode 887a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * 888a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee * Total size is (4+size*2) 16-bit code units. 889a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee */ 890eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee uint16_t ident = table[0]; 8910d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee const int32_t* targets = reinterpret_cast<const int32_t*>(&table[4]); 892a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int entries = table[1]; 893fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int low_key = s4FromSwitchData(&table[2]); 894a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee LOG(INFO) << "Packed switch table - ident:0x" << std::hex << ident 895fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee << ", entries: " << std::dec << entries << ", low_key: " << low_key; 896a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee for (int i = 0; i < entries; i++) { 897fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LOG(INFO) << " Key[" << (i + low_key) << "] -> 0x" << std::hex 898a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee << targets[i]; 899a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 90031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee} 901e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 902252254b130067cd7a5071865e793966871ae0246buzbee/* Set up special LIR to mark a Dalvik byte-code instruction start for pretty printing */ 9030d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkBoundary(DexOffset offset, const char* inst_str) { 9040d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // NOTE: only used for debug listings. 9050d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee NewLIR1(kPseudoDalvikByteCodeBoundary, WrapPointer(ArenaStrdup(inst_str))); 906d1643e41ef242ae656f667bf3c8b0324635cefd3buzbee} 907e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee 9082ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::EvaluateBranch(Instruction::Code opcode, int32_t src1, int32_t src2) { 909e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee bool is_taken; 910e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee switch (opcode) { 911e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_EQ: is_taken = (src1 == src2); break; 912e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_NE: is_taken = (src1 != src2); break; 913e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_LT: is_taken = (src1 < src2); break; 914e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_GE: is_taken = (src1 >= src2); break; 915e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_GT: is_taken = (src1 > src2); break; 916e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_LE: is_taken = (src1 <= src2); break; 917e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_EQZ: is_taken = (src1 == 0); break; 918e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_NEZ: is_taken = (src1 != 0); break; 919e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_LTZ: is_taken = (src1 < 0); break; 920e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_GEZ: is_taken = (src1 >= 0); break; 921e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_GTZ: is_taken = (src1 > 0); break; 922e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee case Instruction::IF_LEZ: is_taken = (src1 <= 0); break; 923e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee default: 924e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee LOG(FATAL) << "Unexpected opcode " << opcode; 925e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee is_taken = false; 926e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee } 927e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee return is_taken; 928e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee} 929e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee 9304ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee// Convert relation of src1/src2 to src2/src1 9311fd3346740dfb7f47be9922312b68a4227fada96buzbeeConditionCode Mir2Lir::FlipComparisonOrder(ConditionCode before) { 9324ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee ConditionCode res; 9334ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee switch (before) { 9344ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondEq: res = kCondEq; break; 9354ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondNe: res = kCondNe; break; 9364ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondLt: res = kCondGt; break; 9374ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondGt: res = kCondLt; break; 9384ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondLe: res = kCondGe; break; 9394ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee case kCondGe: res = kCondLe; break; 9404ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee default: 9414ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee res = static_cast<ConditionCode>(0); 9424ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee LOG(FATAL) << "Unexpected ccode " << before; 9434ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee } 9444ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return res; 9454ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 9464ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 947a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir MarkoConditionCode Mir2Lir::NegateComparison(ConditionCode before) { 948a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko ConditionCode res; 949a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko switch (before) { 950a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko case kCondEq: res = kCondNe; break; 951a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko case kCondNe: res = kCondEq; break; 952a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko case kCondLt: res = kCondGe; break; 953a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko case kCondGt: res = kCondLe; break; 954a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko case kCondLe: res = kCondGt; break; 955a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko case kCondGe: res = kCondLt; break; 956a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko default: 957a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko res = static_cast<ConditionCode>(0); 958a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko LOG(FATAL) << "Unexpected ccode " << before; 959a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko } 960a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko return res; 961a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko} 962a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko 963862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee// TODO: move to mir_to_lir.cc 964862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbeeMir2Lir::Mir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena) 9656282dc12440a2072dc06a616160027ff21bd895eIan Rogers : Backend(arena), 9666282dc12440a2072dc06a616160027ff21bd895eIan Rogers literal_list_(NULL), 9671fd3346740dfb7f47be9922312b68a4227fada96buzbee method_literal_list_(NULL), 968be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi class_literal_list_(NULL), 9691fd3346740dfb7f47be9922312b68a4227fada96buzbee code_literal_list_(NULL), 970b48819db07f9a0992a72173380c24249d7fc648abuzbee first_fixup_(NULL), 9711fd3346740dfb7f47be9922312b68a4227fada96buzbee cu_(cu), 9721fd3346740dfb7f47be9922312b68a4227fada96buzbee mir_graph_(mir_graph), 973862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee switch_tables_(arena, 4, kGrowableArraySwitchTables), 974862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee fill_array_data_(arena, 4, kGrowableArrayFillArrayData), 975bd663de599b16229085759366c56e2ed5a1dc7ecbuzbee tempreg_info_(arena, 20, kGrowableArrayMisc), 976091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee reginfo_map_(arena, RegStorage::kMaxRegs, kGrowableArrayMisc), 9770d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee pointer_storage_(arena, 128, kGrowableArrayMisc), 9781fd3346740dfb7f47be9922312b68a4227fada96buzbee data_offset_(0), 9791fd3346740dfb7f47be9922312b68a4227fada96buzbee total_size_(0), 9801fd3346740dfb7f47be9922312b68a4227fada96buzbee block_label_list_(NULL), 981d69835d841cb7663faaa2f1996e73e8c0b3f6d76buzbee promotion_map_(NULL), 982862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee current_dalvik_offset_(0), 983b48819db07f9a0992a72173380c24249d7fc648abuzbee estimated_native_code_size_(0), 984862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee reg_pool_(NULL), 9851fd3346740dfb7f47be9922312b68a4227fada96buzbee live_sreg_(0), 9861fd3346740dfb7f47be9922312b68a4227fada96buzbee num_core_spills_(0), 9871fd3346740dfb7f47be9922312b68a4227fada96buzbee num_fp_spills_(0), 9881fd3346740dfb7f47be9922312b68a4227fada96buzbee frame_size_(0), 9891fd3346740dfb7f47be9922312b68a4227fada96buzbee core_spill_mask_(0), 9901fd3346740dfb7f47be9922312b68a4227fada96buzbee fp_spill_mask_(0), 9911fd3346740dfb7f47be9922312b68a4227fada96buzbee first_lir_insn_(NULL), 992bcec6fba95ee7974d3f7b81c3c02e7eb3ca3df00Dave Allison last_lir_insn_(NULL), 9938dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko slow_paths_(arena, 32, kGrowableArraySlowPaths), 9948dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko mem_ref_type_(ResourceMask::kHeapRef), 9958dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko mask_cache_(arena) { 9960d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // Reserve pointer id 0 for NULL. 9970d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee size_t null_idx = WrapPointer(NULL); 9980d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK_EQ(null_idx, 0U); 9991fd3346740dfb7f47be9922312b68a4227fada96buzbee} 10001fd3346740dfb7f47be9922312b68a4227fada96buzbee 10011fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::Materialize() { 1002a61f49539a59b610e557b5513695295639496750buzbee cu_->NewTimingSplit("RegisterAllocation"); 10031fd3346740dfb7f47be9922312b68a4227fada96buzbee CompilerInitializeRegAlloc(); // Needs to happen after SSA naming 10041fd3346740dfb7f47be9922312b68a4227fada96buzbee 10051fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Allocate Registers using simple local allocation scheme */ 10061fd3346740dfb7f47be9922312b68a4227fada96buzbee SimpleRegAlloc(); 10071fd3346740dfb7f47be9922312b68a4227fada96buzbee 10083bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru /* First try the custom light codegen for special cases. */ 10095816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko DCHECK(cu_->compiler_driver->GetMethodInlinerMap() != nullptr); 10103bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru bool special_worked = cu_->compiler_driver->GetMethodInlinerMap()->GetMethodInliner(cu_->dex_file) 10115816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko ->GenSpecial(this, cu_->method_idx); 10121fd3346740dfb7f47be9922312b68a4227fada96buzbee 10133bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru /* Take normal path for converting MIR to LIR only if the special codegen did not succeed. */ 10143bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru if (special_worked == false) { 10151fd3346740dfb7f47be9922312b68a4227fada96buzbee MethodMIR2LIR(); 10161fd3346740dfb7f47be9922312b68a4227fada96buzbee } 10171fd3346740dfb7f47be9922312b68a4227fada96buzbee 10181fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Method is not empty */ 10191fd3346740dfb7f47be9922312b68a4227fada96buzbee if (first_lir_insn_) { 10201fd3346740dfb7f47be9922312b68a4227fada96buzbee // mark the targets of switch statement case labels 10211fd3346740dfb7f47be9922312b68a4227fada96buzbee ProcessSwitchTables(); 10221fd3346740dfb7f47be9922312b68a4227fada96buzbee 10231fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Convert LIR into machine code. */ 10241fd3346740dfb7f47be9922312b68a4227fada96buzbee AssembleLIR(); 10251fd3346740dfb7f47be9922312b68a4227fada96buzbee 1026b01bf15d18f9b08d77e7a3c6e2897af0e02bf8cabuzbee if ((cu_->enable_debug & (1 << kDebugCodegenDump)) != 0) { 10271fd3346740dfb7f47be9922312b68a4227fada96buzbee CodegenDump(); 10281fd3346740dfb7f47be9922312b68a4227fada96buzbee } 10291fd3346740dfb7f47be9922312b68a4227fada96buzbee } 10301fd3346740dfb7f47be9922312b68a4227fada96buzbee} 10311fd3346740dfb7f47be9922312b68a4227fada96buzbee 10321fd3346740dfb7f47be9922312b68a4227fada96buzbeeCompiledMethod* Mir2Lir::GetCompiledMethod() { 10332e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko // Combine vmap tables - core regs, then fp regs - into vmap_table. 10342e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko Leb128EncodingVector vmap_encoder; 10351fd3346740dfb7f47be9922312b68a4227fada96buzbee if (frame_size_ > 0) { 10362e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko // Prefix the encoded data with its size. 10372e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko size_t size = core_vmap_table_.size() + 1 /* marker */ + fp_vmap_table_.size(); 10382e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko vmap_encoder.Reserve(size + 1u); // All values are likely to be one byte in ULEB128 (<128). 10392e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko vmap_encoder.PushBackUnsigned(size); 10402e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko // Core regs may have been inserted out of order - sort first. 10412e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko std::sort(core_vmap_table_.begin(), core_vmap_table_.end()); 10422e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko for (size_t i = 0 ; i < core_vmap_table_.size(); ++i) { 10432e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko // Copy, stripping out the phys register sort key. 10442e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko vmap_encoder.PushBackUnsigned( 10452e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko ~(-1 << VREG_NUM_WIDTH) & (core_vmap_table_[i] + VmapTable::kEntryAdjustment)); 10462e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko } 10472e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko // Push a marker to take place of lr. 10482e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko vmap_encoder.PushBackUnsigned(VmapTable::kAdjustedFpMarker); 1049c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov if (cu_->instruction_set == kThumb2) { 1050c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov // fp regs already sorted. 1051c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov for (uint32_t i = 0; i < fp_vmap_table_.size(); i++) { 1052c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov vmap_encoder.PushBackUnsigned(fp_vmap_table_[i] + VmapTable::kEntryAdjustment); 1053c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov } 1054c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov } else { 1055c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov // For other platforms regs may have been inserted out of order - sort first. 1056c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov std::sort(fp_vmap_table_.begin(), fp_vmap_table_.end()); 1057c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov for (size_t i = 0 ; i < fp_vmap_table_.size(); ++i) { 1058c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov // Copy, stripping out the phys register sort key. 1059c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov vmap_encoder.PushBackUnsigned( 1060c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov ~(-1 << VREG_NUM_WIDTH) & (fp_vmap_table_[i] + VmapTable::kEntryAdjustment)); 1061c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov } 10622e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko } 10631fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 10648194963098247be6bca9cc4a54dbfa65c73e8cccVladimir Marko DCHECK_EQ(POPCOUNT(core_spill_mask_), 0); 10658194963098247be6bca9cc4a54dbfa65c73e8cccVladimir Marko DCHECK_EQ(POPCOUNT(fp_spill_mask_), 0); 10662e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko DCHECK_EQ(core_vmap_table_.size(), 0u); 10672e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko DCHECK_EQ(fp_vmap_table_.size(), 0u); 10682e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko vmap_encoder.PushBackUnsigned(0u); // Size is 0. 10691fd3346740dfb7f47be9922312b68a4227fada96buzbee } 1070ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 1071700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<std::vector<uint8_t>> cfi_info(ReturnCallFrameInformation()); 10721fd3346740dfb7f47be9922312b68a4227fada96buzbee CompiledMethod* result = 107372d32629303f8f39362a4099481f48646aed042fIan Rogers new CompiledMethod(cu_->compiler_driver, cu_->instruction_set, code_buffer_, frame_size_, 107406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko core_spill_mask_, fp_spill_mask_, encoded_mapping_table_, 1075d6ed642458c8820e1beca72f3d7b5f0be4a4b64bDave Allison vmap_encoder.GetData(), native_gc_map_, cfi_info.get()); 10761fd3346740dfb7f47be9922312b68a4227fada96buzbee return result; 10771fd3346740dfb7f47be9922312b68a4227fada96buzbee} 10781fd3346740dfb7f47be9922312b68a4227fada96buzbee 1079da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusorusize_t Mir2Lir::GetMaxPossibleCompilerTemps() const { 1080da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // Chose a reasonably small value in order to contain stack growth. 1081da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // Backends that are smarter about spill region can return larger values. 1082da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru const size_t max_compiler_temps = 10; 1083da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru return max_compiler_temps; 1084da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru} 1085da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru 1086da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusorusize_t Mir2Lir::GetNumBytesForCompilerTempSpillRegion() { 1087da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // By default assume that the Mir2Lir will need one slot for each temporary. 1088da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // If the backend can better determine temps that have non-overlapping ranges and 1089da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru // temps that do not need spilled, it can actually provide a small region. 1090da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru return (mir_graph_->GetNumUsedCompilerTemps() * sizeof(uint32_t)); 1091da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru} 1092da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru 10931fd3346740dfb7f47be9922312b68a4227fada96buzbeeint Mir2Lir::ComputeFrameSize() { 10941fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Figure out the frame size */ 1095f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko uint32_t size = num_core_spills_ * GetBytesPerGprSpillLocation(cu_->instruction_set) 1096f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko + num_fp_spills_ * GetBytesPerFprSpillLocation(cu_->instruction_set) 1097f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko + sizeof(uint32_t) // Filler. 1098f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko + (cu_->num_regs + cu_->num_outs) * sizeof(uint32_t) 1099f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko + GetNumBytesForCompilerTempSpillRegion(); 11001fd3346740dfb7f47be9922312b68a4227fada96buzbee /* Align and set */ 1101660188264dee3c8f3510e2e24c11816c6b60f197Andreas Gampe return RoundUp(size, kStackAlignment); 11021fd3346740dfb7f47be9922312b68a4227fada96buzbee} 11031fd3346740dfb7f47be9922312b68a4227fada96buzbee 11041fd3346740dfb7f47be9922312b68a4227fada96buzbee/* 11051fd3346740dfb7f47be9922312b68a4227fada96buzbee * Append an LIR instruction to the LIR list maintained by a compilation 11061fd3346740dfb7f47be9922312b68a4227fada96buzbee * unit 11071fd3346740dfb7f47be9922312b68a4227fada96buzbee */ 11082ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::AppendLIR(LIR* lir) { 11091fd3346740dfb7f47be9922312b68a4227fada96buzbee if (first_lir_insn_ == NULL) { 11101fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK(last_lir_insn_ == NULL); 11111fd3346740dfb7f47be9922312b68a4227fada96buzbee last_lir_insn_ = first_lir_insn_ = lir; 11121fd3346740dfb7f47be9922312b68a4227fada96buzbee lir->prev = lir->next = NULL; 11131fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 11141fd3346740dfb7f47be9922312b68a4227fada96buzbee last_lir_insn_->next = lir; 11151fd3346740dfb7f47be9922312b68a4227fada96buzbee lir->prev = last_lir_insn_; 11161fd3346740dfb7f47be9922312b68a4227fada96buzbee lir->next = NULL; 11171fd3346740dfb7f47be9922312b68a4227fada96buzbee last_lir_insn_ = lir; 11181fd3346740dfb7f47be9922312b68a4227fada96buzbee } 11191fd3346740dfb7f47be9922312b68a4227fada96buzbee} 11201fd3346740dfb7f47be9922312b68a4227fada96buzbee 11211fd3346740dfb7f47be9922312b68a4227fada96buzbee/* 11221fd3346740dfb7f47be9922312b68a4227fada96buzbee * Insert an LIR instruction before the current instruction, which cannot be the 11231fd3346740dfb7f47be9922312b68a4227fada96buzbee * first instruction. 11241fd3346740dfb7f47be9922312b68a4227fada96buzbee * 11251fd3346740dfb7f47be9922312b68a4227fada96buzbee * prev_lir <-> new_lir <-> current_lir 11261fd3346740dfb7f47be9922312b68a4227fada96buzbee */ 11272ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InsertLIRBefore(LIR* current_lir, LIR* new_lir) { 11281fd3346740dfb7f47be9922312b68a4227fada96buzbee DCHECK(current_lir->prev != NULL); 11291fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR *prev_lir = current_lir->prev; 11301fd3346740dfb7f47be9922312b68a4227fada96buzbee 11311fd3346740dfb7f47be9922312b68a4227fada96buzbee prev_lir->next = new_lir; 11321fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->prev = prev_lir; 11331fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->next = current_lir; 11341fd3346740dfb7f47be9922312b68a4227fada96buzbee current_lir->prev = new_lir; 11351fd3346740dfb7f47be9922312b68a4227fada96buzbee} 11361fd3346740dfb7f47be9922312b68a4227fada96buzbee 11371fd3346740dfb7f47be9922312b68a4227fada96buzbee/* 11381fd3346740dfb7f47be9922312b68a4227fada96buzbee * Insert an LIR instruction after the current instruction, which cannot be the 11393c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe * last instruction. 11401fd3346740dfb7f47be9922312b68a4227fada96buzbee * 11411fd3346740dfb7f47be9922312b68a4227fada96buzbee * current_lir -> new_lir -> old_next 11421fd3346740dfb7f47be9922312b68a4227fada96buzbee */ 11432ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InsertLIRAfter(LIR* current_lir, LIR* new_lir) { 11441fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->prev = current_lir; 11451fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->next = current_lir->next; 11461fd3346740dfb7f47be9922312b68a4227fada96buzbee current_lir->next = new_lir; 11471fd3346740dfb7f47be9922312b68a4227fada96buzbee new_lir->next->prev = new_lir; 11481fd3346740dfb7f47be9922312b68a4227fada96buzbee} 11491fd3346740dfb7f47be9922312b68a4227fada96buzbee 11504708dcd68eebf1173aef1097dad8ab13466059aaMark Mendellbool Mir2Lir::IsPowerOfTwo(uint64_t x) { 11514708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell return (x & (x - 1)) == 0; 11524708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell} 11534708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell 11544708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell// Returns the index of the lowest set bit in 'x'. 11554708dcd68eebf1173aef1097dad8ab13466059aaMark Mendellint32_t Mir2Lir::LowestSetBit(uint64_t x) { 11564708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell int bit_posn = 0; 11574708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell while ((x & 0xf) == 0) { 11584708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell bit_posn += 4; 11594708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell x >>= 4; 11604708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell } 11614708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell while ((x & 1) == 0) { 11624708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell bit_posn++; 11634708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell x >>= 1; 11644708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell } 11654708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell return bit_posn; 11664708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell} 11674708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell 11684708dcd68eebf1173aef1097dad8ab13466059aaMark Mendellbool Mir2Lir::BadOverlap(RegLocation rl_src, RegLocation rl_dest) { 11694708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell DCHECK(rl_src.wide); 11704708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell DCHECK(rl_dest.wide); 11714708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell return (abs(mir_graph_->SRegToVReg(rl_src.s_reg_low) - mir_graph_->SRegToVReg(rl_dest.s_reg_low)) == 1); 11724708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell} 11734708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell 11742700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR *Mir2Lir::OpCmpMemImmBranch(ConditionCode cond, RegStorage temp_reg, RegStorage base_reg, 117569dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison int offset, int check_value, LIR* target, LIR** compare) { 1176766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell // Handle this for architectures that can't compare to memory. 117769dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison LIR* inst = Load32Disp(base_reg, offset, temp_reg); 117869dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison if (compare != nullptr) { 117969dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison *compare = inst; 118069dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison } 1181766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell LIR* branch = OpCmpImmBranch(cond, temp_reg, check_value, target); 1182766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell return branch; 1183766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell} 1184766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell 1185bcec6fba95ee7974d3f7b81c3c02e7eb3ca3df00Dave Allisonvoid Mir2Lir::AddSlowPath(LIRSlowPath* slowpath) { 1186bcec6fba95ee7974d3f7b81c3c02e7eb3ca3df00Dave Allison slow_paths_.Insert(slowpath); 1187bcec6fba95ee7974d3f7b81c3c02e7eb3ca3df00Dave Allison} 118855d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell 118949161cef10a308aedada18e9aa742498d6e6c8c7Jeff Haovoid Mir2Lir::LoadCodeAddress(const MethodReference& target_method, InvokeType type, 119049161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao SpecialTargetRegister symbolic_reg) { 1191a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko LIR* data_target = ScanLiteralPoolMethod(code_literal_list_, target_method); 119255d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell if (data_target == NULL) { 1193a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko data_target = AddWordData(&code_literal_list_, target_method.dex_method_index); 119449161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao data_target->operands[1] = WrapPointer(const_cast<DexFile*>(target_method.dex_file)); 1195a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko // NOTE: The invoke type doesn't contribute to the literal identity. In fact, we can have 1196a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko // the same method invoked with kVirtual, kSuper and kInterface but the class linker will 1197a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko // resolve these invokes to the same method, so we don't care which one we record here. 119849161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao data_target->operands[2] = type; 119955d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell } 1200a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu // Loads a code pointer. Code from oat file can be mapped anywhere. 1201a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu LIR* load_pc_rel = OpPcRelLoad(TargetPtrReg(symbolic_reg), data_target); 120255d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell AppendLIR(load_pc_rel); 120355d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell DCHECK_NE(cu_->instruction_set, kMips) << reinterpret_cast<void*>(data_target); 120455d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell} 120555d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell 120649161cef10a308aedada18e9aa742498d6e6c8c7Jeff Haovoid Mir2Lir::LoadMethodAddress(const MethodReference& target_method, InvokeType type, 120749161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao SpecialTargetRegister symbolic_reg) { 1208a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko LIR* data_target = ScanLiteralPoolMethod(method_literal_list_, target_method); 120955d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell if (data_target == NULL) { 1210a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko data_target = AddWordData(&method_literal_list_, target_method.dex_method_index); 121149161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao data_target->operands[1] = WrapPointer(const_cast<DexFile*>(target_method.dex_file)); 1212a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko // NOTE: The invoke type doesn't contribute to the literal identity. In fact, we can have 1213a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko // the same method invoked with kVirtual, kSuper and kInterface but the class linker will 1214a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko // resolve these invokes to the same method, so we don't care which one we record here. 121549161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao data_target->operands[2] = type; 121655d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell } 1217a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu // Loads an ArtMethod pointer, which is a reference as it lives in the heap. 1218ccc60264229ac96d798528d2cb7dbbdd0deca993Andreas Gampe LIR* load_pc_rel = OpPcRelLoad(TargetReg(symbolic_reg, kRef), data_target); 121955d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell AppendLIR(load_pc_rel); 122055d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell DCHECK_NE(cu_->instruction_set, kMips) << reinterpret_cast<void*>(data_target); 122155d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell} 122255d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell 122355d0eac918321e0525f6e6491f36a80977e0d416Mark Mendellvoid Mir2Lir::LoadClassType(uint32_t type_idx, SpecialTargetRegister symbolic_reg) { 122455d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell // Use the literal pool and a PC-relative load from a data word. 122555d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell LIR* data_target = ScanLiteralPool(class_literal_list_, type_idx, 0); 122655d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell if (data_target == nullptr) { 122755d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell data_target = AddWordData(&class_literal_list_, type_idx); 122855d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell } 1229a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu // Loads a Class pointer, which is a reference as it lives in the heap. 1230ccc60264229ac96d798528d2cb7dbbdd0deca993Andreas Gampe LIR* load_pc_rel = OpPcRelLoad(TargetReg(symbolic_reg, kRef), data_target); 123155d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell AppendLIR(load_pc_rel); 123255d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell} 123355d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell 1234ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendellstd::vector<uint8_t>* Mir2Lir::ReturnCallFrameInformation() { 1235ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Default case is to do nothing. 1236ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell return nullptr; 1237ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell} 1238ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 12392700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeRegLocation Mir2Lir::NarrowRegLoc(RegLocation loc) { 1240091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (loc.location == kLocPhysReg) { 124185089dd28a39dd20f42ac258398b2a08668f9ef1buzbee DCHECK(!loc.reg.Is32Bit()); 1242091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (loc.reg.IsPair()) { 124385089dd28a39dd20f42ac258398b2a08668f9ef1buzbee RegisterInfo* info_lo = GetRegInfo(loc.reg.GetLow()); 124485089dd28a39dd20f42ac258398b2a08668f9ef1buzbee RegisterInfo* info_hi = GetRegInfo(loc.reg.GetHigh()); 124585089dd28a39dd20f42ac258398b2a08668f9ef1buzbee info_lo->SetIsWide(false); 124685089dd28a39dd20f42ac258398b2a08668f9ef1buzbee info_hi->SetIsWide(false); 124785089dd28a39dd20f42ac258398b2a08668f9ef1buzbee loc.reg = info_lo->GetReg(); 1248091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee } else { 124985089dd28a39dd20f42ac258398b2a08668f9ef1buzbee RegisterInfo* info = GetRegInfo(loc.reg); 125085089dd28a39dd20f42ac258398b2a08668f9ef1buzbee RegisterInfo* info_new = info->FindMatchingView(RegisterInfo::k32SoloStorageMask); 125185089dd28a39dd20f42ac258398b2a08668f9ef1buzbee DCHECK(info_new != nullptr); 125285089dd28a39dd20f42ac258398b2a08668f9ef1buzbee if (info->IsLive() && (info->SReg() == loc.s_reg_low)) { 125385089dd28a39dd20f42ac258398b2a08668f9ef1buzbee info->MarkDead(); 125485089dd28a39dd20f42ac258398b2a08668f9ef1buzbee info_new->MarkLive(loc.s_reg_low); 125585089dd28a39dd20f42ac258398b2a08668f9ef1buzbee } 125685089dd28a39dd20f42ac258398b2a08668f9ef1buzbee loc.reg = info_new->GetReg(); 1257091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee } 125885089dd28a39dd20f42ac258398b2a08668f9ef1buzbee DCHECK(loc.reg.Valid()); 12592700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee } 126085089dd28a39dd20f42ac258398b2a08668f9ef1buzbee loc.wide = false; 12612700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return loc; 12622700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee} 12632700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee 1264d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendellvoid Mir2Lir::GenMachineSpecificExtendedMethodMIR(BasicBlock* bb, MIR* mir) { 1265d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell LOG(FATAL) << "Unknown MIR opcode not supported on this architecture"; 1266d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell} 1267d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell 12687934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom} // namespace art 1269