codegen_util.cc revision d69835d841cb7663faaa2f1996e73e8c0b3f6d76
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"
2096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers#include "mapping_table.h"
218d3a117b374352a1853fae9b7306afeaaa9e3b91Ian Rogers#include "mir_to_lir-inl.h"
225816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko#include "dex/quick/dex_file_method_inliner.h"
235816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko#include "dex/quick/dex_file_to_method_inliner_map.h"
24c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "dex/verification_results.h"
252730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko#include "dex/verified_method.h"
260c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "verifier/dex_gc_map.h"
270c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "verifier/method_verifier.h"
280c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
29e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbeenamespace art {
30e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
3106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Markonamespace {
3206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko
3306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko/* Dump a mapping table */
3406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Markotemplate <typename It>
3506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Markovoid DumpMappingTable(const char* table_name, const char* descriptor, const char* name,
3606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko                      const Signature& signature, uint32_t size, It first) {
3706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  if (size != 0) {
38107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers    std::string line(StringPrintf("\n  %s %s%s_%s_table[%u] = {", table_name,
3906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko                     descriptor, name, signature.ToString().c_str(), size));
4006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    std::replace(line.begin(), line.end(), ';', '_');
4106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    LOG(INFO) << line;
4206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    for (uint32_t i = 0; i != size; ++i) {
4306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      line = StringPrintf("    {0x%05x, 0x%04x},", first.NativePcOffset(), first.DexPc());
4406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      ++first;
4506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      LOG(INFO) << line;
4606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    }
4706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    LOG(INFO) <<"  };\n\n";
4806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  }
4906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko}
5006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko
5106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko}  // anonymous namespace
5206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko
532ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::IsInexpensiveConstant(RegLocation rl_src) {
544ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  bool res = false;
554ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  if (rl_src.is_const) {
564ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    if (rl_src.wide) {
574ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      if (rl_src.fp) {
581fd3346740dfb7f47be9922312b68a4227fada96buzbee         res = InexpensiveConstantDouble(mir_graph_->ConstantValueWide(rl_src));
594ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      } else {
601fd3346740dfb7f47be9922312b68a4227fada96buzbee         res = InexpensiveConstantLong(mir_graph_->ConstantValueWide(rl_src));
614ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      }
624ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    } else {
634ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      if (rl_src.fp) {
641fd3346740dfb7f47be9922312b68a4227fada96buzbee         res = InexpensiveConstantFloat(mir_graph_->ConstantValue(rl_src));
654ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      } else {
661fd3346740dfb7f47be9922312b68a4227fada96buzbee         res = InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src));
674ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      }
684ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    }
694ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  }
704ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  return res;
714ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee}
724ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee
732ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::MarkSafepointPC(LIR* inst) {
74b48819db07f9a0992a72173380c24249d7fc648abuzbee  DCHECK(!inst->flags.use_def_invalid);
75b48819db07f9a0992a72173380c24249d7fc648abuzbee  inst->u.m.def_mask = ENCODE_ALL;
761fd3346740dfb7f47be9922312b68a4227fada96buzbee  LIR* safepoint_pc = NewLIR0(kPseudoSafepointPC);
77b48819db07f9a0992a72173380c24249d7fc648abuzbee  DCHECK_EQ(safepoint_pc->u.m.def_mask, ENCODE_ALL);
7802031b185b4653e6c72e21f7a51238b903f6d638buzbee}
7902031b185b4653e6c72e21f7a51238b903f6d638buzbee
809b297bfc588c7d38efd12a6f38cd2710fc513ee3Ian Rogersbool Mir2Lir::FastInstance(uint32_t field_idx, bool is_put, int* field_offset, bool* is_volatile) {
811fd3346740dfb7f47be9922312b68a4227fada96buzbee  return cu_->compiler_driver->ComputeInstanceFieldInfo(
829b297bfc588c7d38efd12a6f38cd2710fc513ee3Ian Rogers      field_idx, mir_graph_->GetCurrentDexCompilationUnit(), is_put, field_offset, is_volatile);
8302031b185b4653e6c72e21f7a51238b903f6d638buzbee}
8402031b185b4653e6c72e21f7a51238b903f6d638buzbee
85252254b130067cd7a5071865e793966871ae0246buzbee/* Remove a LIR from the list. */
86252254b130067cd7a5071865e793966871ae0246buzbeevoid Mir2Lir::UnlinkLIR(LIR* lir) {
87252254b130067cd7a5071865e793966871ae0246buzbee  if (UNLIKELY(lir == first_lir_insn_)) {
88252254b130067cd7a5071865e793966871ae0246buzbee    first_lir_insn_ = lir->next;
89252254b130067cd7a5071865e793966871ae0246buzbee    if (lir->next != NULL) {
90252254b130067cd7a5071865e793966871ae0246buzbee      lir->next->prev = NULL;
91252254b130067cd7a5071865e793966871ae0246buzbee    } else {
92252254b130067cd7a5071865e793966871ae0246buzbee      DCHECK(lir->next == NULL);
93252254b130067cd7a5071865e793966871ae0246buzbee      DCHECK(lir == last_lir_insn_);
94252254b130067cd7a5071865e793966871ae0246buzbee      last_lir_insn_ = NULL;
95252254b130067cd7a5071865e793966871ae0246buzbee    }
96252254b130067cd7a5071865e793966871ae0246buzbee  } else if (lir == last_lir_insn_) {
97252254b130067cd7a5071865e793966871ae0246buzbee    last_lir_insn_ = lir->prev;
98252254b130067cd7a5071865e793966871ae0246buzbee    lir->prev->next = NULL;
99252254b130067cd7a5071865e793966871ae0246buzbee  } else if ((lir->prev != NULL) && (lir->next != NULL)) {
100252254b130067cd7a5071865e793966871ae0246buzbee    lir->prev->next = lir->next;
101252254b130067cd7a5071865e793966871ae0246buzbee    lir->next->prev = lir->prev;
102252254b130067cd7a5071865e793966871ae0246buzbee  }
103252254b130067cd7a5071865e793966871ae0246buzbee}
104252254b130067cd7a5071865e793966871ae0246buzbee
105cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee/* Convert an instruction to a NOP */
106df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstromvoid Mir2Lir::NopLIR(LIR* lir) {
107fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  lir->flags.is_nop = true;
108252254b130067cd7a5071865e793966871ae0246buzbee  if (!cu_->verbose) {
109252254b130067cd7a5071865e793966871ae0246buzbee    UnlinkLIR(lir);
110252254b130067cd7a5071865e793966871ae0246buzbee  }
111cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee}
112cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee
1132ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::SetMemRefType(LIR* lir, bool is_load, int mem_type) {
114fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  uint64_t *mask_ptr;
115f69863b3039fc621ff4250e262d2a024d5e79ec8Brian Carlstrom  uint64_t mask = ENCODE_MEM;
1161fd3346740dfb7f47be9922312b68a4227fada96buzbee  DCHECK(GetTargetInstFlags(lir->opcode) & (IS_LOAD | IS_STORE));
117b48819db07f9a0992a72173380c24249d7fc648abuzbee  DCHECK(!lir->flags.use_def_invalid);
118fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (is_load) {
119b48819db07f9a0992a72173380c24249d7fc648abuzbee    mask_ptr = &lir->u.m.use_mask;
120a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
121b48819db07f9a0992a72173380c24249d7fc648abuzbee    mask_ptr = &lir->u.m.def_mask;
122a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
123a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* Clear out the memref flags */
124fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  *mask_ptr &= ~mask;
125a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* ..and then add back the one we need */
126fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  switch (mem_type) {
127a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kLiteral:
128fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      DCHECK(is_load);
129fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      *mask_ptr |= ENCODE_LITERAL;
130a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
131a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kDalvikReg:
132fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      *mask_ptr |= ENCODE_DALVIK_REG;
133a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
134a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kHeapRef:
135fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      *mask_ptr |= ENCODE_HEAP_REF;
136a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
137a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kMustNotAlias:
138a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      /* Currently only loads can be marked as kMustNotAlias */
1391fd3346740dfb7f47be9922312b68a4227fada96buzbee      DCHECK(!(GetTargetInstFlags(lir->opcode) & IS_STORE));
140fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      *mask_ptr |= ENCODE_MUST_NOT_ALIAS;
141a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
142a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    default:
143fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      LOG(FATAL) << "Oat: invalid memref kind - " << mem_type;
144a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
14531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
14631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
14731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/*
148b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers * Mark load/store instructions that access Dalvik registers through the stack.
14931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */
1501fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::AnnotateDalvikRegAccess(LIR* lir, int reg_id, bool is_load,
1512ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom                                      bool is64bit) {
1521fd3346740dfb7f47be9922312b68a4227fada96buzbee  SetMemRefType(lir, is_load, kDalvikReg);
15331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
154a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /*
155fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee   * Store the Dalvik register id in alias_info. Mark the MSB if it is a 64-bit
156a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * access.
157a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   */
158b48819db07f9a0992a72173380c24249d7fc648abuzbee  lir->flags.alias_info = ENCODE_ALIAS_INFO(reg_id, is64bit);
15931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
16031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
16131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/*
1625de3494e4297c0d480409da3fecee39173f1d4e1buzbee * Debugging macros
1635de3494e4297c0d480409da3fecee39173f1d4e1buzbee */
1645de3494e4297c0d480409da3fecee39173f1d4e1buzbee#define DUMP_RESOURCE_MASK(X)
1655de3494e4297c0d480409da3fecee39173f1d4e1buzbee
1665de3494e4297c0d480409da3fecee39173f1d4e1buzbee/* Pretty-print a LIR instruction */
1672ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpLIRInsn(LIR* lir, unsigned char* base_addr) {
168a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int offset = lir->offset;
169a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int dest = lir->operands[0];
1701fd3346740dfb7f47be9922312b68a4227fada96buzbee  const bool dump_nop = (cu_->enable_debug & (1 << kDebugShowNops));
171a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
172a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* Handle pseudo-ops individually, and all regular insns as a group */
173a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  switch (lir->opcode) {
174a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoMethodEntry:
175a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "-------- method entry "
1761fd3346740dfb7f47be9922312b68a4227fada96buzbee                << PrettyMethod(cu_->method_idx, *cu_->dex_file);
177a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
178a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoMethodExit:
179a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "-------- Method_Exit";
180a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
181a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoBarrier:
182a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "-------- BARRIER";
183a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
184a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoEntryBlock:
185a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "-------- entry offset: 0x" << std::hex << dest;
186a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
187a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoDalvikByteCodeBoundary:
1884ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      if (lir->operands[0] == 0) {
1890d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee         // NOTE: only used for debug listings.
1900d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee         lir->operands[0] = WrapPointer(ArenaStrdup("No instruction string"));
1914ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      }
192a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "-------- dalvik offset: 0x" << std::hex
1930b1191cfece83f6f8d4101575a06555a2d13387aBill Buzbee                << lir->dalvik_offset << " @ "
1940b1191cfece83f6f8d4101575a06555a2d13387aBill Buzbee                << reinterpret_cast<char*>(UnwrapPointer(lir->operands[0]));
195a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
196a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoExitBlock:
197a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "-------- exit offset: 0x" << std::hex << dest;
198a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
199a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoPseudoAlign4:
200fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      LOG(INFO) << reinterpret_cast<uintptr_t>(base_addr) + offset << " (0x" << std::hex
201a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                << offset << "): .align4";
202a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
203a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoEHBlockLabel:
204a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "Exception_Handling:";
205a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
206a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoTargetLabel:
207a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoNormalBlockLabel:
208cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee      LOG(INFO) << "L" << reinterpret_cast<void*>(lir) << ":";
209a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
210a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoThrowTarget:
211cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee      LOG(INFO) << "LT" << reinterpret_cast<void*>(lir) << ":";
212a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
213a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoIntrinsicRetry:
214cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee      LOG(INFO) << "IR" << reinterpret_cast<void*>(lir) << ":";
215a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
216a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoSuspendTarget:
217cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee      LOG(INFO) << "LS" << reinterpret_cast<void*>(lir) << ":";
218a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
2198320f3867c02bae9bef6cdab267820cb7b412781buzbee    case kPseudoSafepointPC:
220fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      LOG(INFO) << "LsafepointPC_0x" << std::hex << lir->offset << "_" << lir->dalvik_offset << ":";
2218320f3867c02bae9bef6cdab267820cb7b412781buzbee      break;
222a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee    case kPseudoExportedPC:
223fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      LOG(INFO) << "LexportedPC_0x" << std::hex << lir->offset << "_" << lir->dalvik_offset << ":";
224a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee      break;
225a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoCaseLabel:
226cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee      LOG(INFO) << "LC" << reinterpret_cast<void*>(lir) << ": Case target 0x"
227a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                << std::hex << lir->operands[0] << "|" << std::dec <<
228a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee        lir->operands[0];
229a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
230a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    default:
231fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      if (lir->flags.is_nop && !dump_nop) {
232a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee        break;
233a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      } else {
2341fd3346740dfb7f47be9922312b68a4227fada96buzbee        std::string op_name(BuildInsnString(GetTargetInstName(lir->opcode),
23502031b185b4653e6c72e21f7a51238b903f6d638buzbee                                               lir, base_addr));
2361fd3346740dfb7f47be9922312b68a4227fada96buzbee        std::string op_operands(BuildInsnString(GetTargetInstFmt(lir->opcode),
23702031b185b4653e6c72e21f7a51238b903f6d638buzbee                                                    lir, base_addr));
238107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers        LOG(INFO) << StringPrintf("%5p: %-9s%s%s",
239107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers                                  base_addr + offset,
240a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                                  op_name.c_str(), op_operands.c_str(),
241fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                                  lir->flags.is_nop ? "(nop)" : "");
242a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
243a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
244a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
245a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
246b48819db07f9a0992a72173380c24249d7fc648abuzbee  if (lir->u.m.use_mask && (!lir->flags.is_nop || dump_nop)) {
247b48819db07f9a0992a72173380c24249d7fc648abuzbee    DUMP_RESOURCE_MASK(DumpResourceMask(lir, lir->u.m.use_mask, "use"));
248a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
249b48819db07f9a0992a72173380c24249d7fc648abuzbee  if (lir->u.m.def_mask && (!lir->flags.is_nop || dump_nop)) {
250b48819db07f9a0992a72173380c24249d7fc648abuzbee    DUMP_RESOURCE_MASK(DumpResourceMask(lir, lir->u.m.def_mask, "def"));
251a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
2525de3494e4297c0d480409da3fecee39173f1d4e1buzbee}
2535de3494e4297c0d480409da3fecee39173f1d4e1buzbee
2542ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpPromotionMap() {
255da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  int num_regs = cu_->num_dalvik_registers + mir_graph_->GetNumUsedCompilerTemps();
256fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  for (int i = 0; i < num_regs; i++) {
2571fd3346740dfb7f47be9922312b68a4227fada96buzbee    PromotionMap v_reg_map = promotion_map_[i];
258a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    std::string buf;
259fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (v_reg_map.fp_location == kLocPhysReg) {
2601fd3346740dfb7f47be9922312b68a4227fada96buzbee      StringAppendF(&buf, " : s%d", v_reg_map.FpReg & FpRegMask());
261a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    }
2629c044ce5f76e9bfa17c4c1979e9f8c99ae100695buzbee
263a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    std::string buf3;
2641fd3346740dfb7f47be9922312b68a4227fada96buzbee    if (i < cu_->num_dalvik_registers) {
265a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      StringAppendF(&buf3, "%02d", i);
2661fd3346740dfb7f47be9922312b68a4227fada96buzbee    } else if (i == mir_graph_->GetMethodSReg()) {
267a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      buf3 = "Method*";
268a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    } else {
2691fd3346740dfb7f47be9922312b68a4227fada96buzbee      StringAppendF(&buf3, "ct%d", i - cu_->num_dalvik_registers);
2705de3494e4297c0d480409da3fecee39173f1d4e1buzbee    }
271a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
272a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    LOG(INFO) << StringPrintf("V[%s] -> %s%d%s", buf3.c_str(),
273fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                              v_reg_map.core_location == kLocPhysReg ?
274fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                              "r" : "SP+", v_reg_map.core_location == kLocPhysReg ?
2751fd3346740dfb7f47be9922312b68a4227fada96buzbee                              v_reg_map.core_reg : SRegOffset(i),
276a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                              buf.c_str());
277a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
2785de3494e4297c0d480409da3fecee39173f1d4e1buzbee}
2795de3494e4297c0d480409da3fecee39173f1d4e1buzbee
2805de3494e4297c0d480409da3fecee39173f1d4e1buzbee/* Dump instructions and constant pool contents */
2812ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::CodegenDump() {
282a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  LOG(INFO) << "Dumping LIR insns for "
2831fd3346740dfb7f47be9922312b68a4227fada96buzbee            << PrettyMethod(cu_->method_idx, *cu_->dex_file);
284fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LIR* lir_insn;
2851fd3346740dfb7f47be9922312b68a4227fada96buzbee  int insns_size = cu_->code_item->insns_size_in_code_units_;
2861fd3346740dfb7f47be9922312b68a4227fada96buzbee
2871fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "Regs (excluding ins) : " << cu_->num_regs;
2881fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "Ins          : " << cu_->num_ins;
2891fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "Outs         : " << cu_->num_outs;
2901fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "CoreSpills       : " << num_core_spills_;
2911fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "FPSpills       : " << num_fp_spills_;
292da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  LOG(INFO) << "CompilerTemps    : " << mir_graph_->GetNumUsedCompilerTemps();
2931fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "Frame size       : " << frame_size_;
2941fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "code size is " << total_size_ <<
295fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    " bytes, Dalvik size is " << insns_size * 2;
296a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  LOG(INFO) << "expansion factor: "
2971fd3346740dfb7f47be9922312b68a4227fada96buzbee            << static_cast<float>(total_size_) / static_cast<float>(insns_size * 2);
2981fd3346740dfb7f47be9922312b68a4227fada96buzbee  DumpPromotionMap();
2991fd3346740dfb7f47be9922312b68a4227fada96buzbee  for (lir_insn = first_lir_insn_; lir_insn != NULL; lir_insn = lir_insn->next) {
3001fd3346740dfb7f47be9922312b68a4227fada96buzbee    DumpLIRInsn(lir_insn, 0);
301a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
3021fd3346740dfb7f47be9922312b68a4227fada96buzbee  for (lir_insn = literal_list_; lir_insn != NULL; lir_insn = lir_insn->next) {
303fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    LOG(INFO) << StringPrintf("%x (%04x): .word (%#x)", lir_insn->offset, lir_insn->offset,
304fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                              lir_insn->operands[0]);
305a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
306a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
307a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  const DexFile::MethodId& method_id =
3081fd3346740dfb7f47be9922312b68a4227fada96buzbee      cu_->dex_file->GetMethodId(cu_->method_idx);
309d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers  const Signature signature = cu_->dex_file->GetMethodSignature(method_id);
310d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers  const char* name = cu_->dex_file->GetMethodName(method_id);
311d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers  const char* descriptor(cu_->dex_file->GetMethodDeclaringClassDescriptor(method_id));
312a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
313a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee  // Dump mapping tables
31406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  if (!encoded_mapping_table_.empty()) {
31506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    MappingTable table(&encoded_mapping_table_[0]);
31606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    DumpMappingTable("PC2Dex_MappingTable", descriptor, name, signature,
31706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko                     table.PcToDexSize(), table.PcToDexBegin());
31806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    DumpMappingTable("Dex2PC_MappingTable", descriptor, name, signature,
31906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko                     table.DexToPcSize(), table.DexToPcBegin());
32006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  }
3215de3494e4297c0d480409da3fecee39173f1d4e1buzbee}
3225de3494e4297c0d480409da3fecee39173f1d4e1buzbee
32331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/*
32431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Search the existing constants in the literal pool for an exact or close match
32531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * within specified delta (greater or equal to 0).
32631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */
3272ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::ScanLiteralPool(LIR* data_target, int value, unsigned int delta) {
328fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  while (data_target) {
329fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if ((static_cast<unsigned>(value - data_target->operands[0])) <= delta)
330fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      return data_target;
331fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    data_target = data_target->next;
332a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
333a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return NULL;
33431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
33531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
33631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* Search the existing constants in the literal pool for an exact wide match */
3372ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::ScanLiteralPoolWide(LIR* data_target, int val_lo, int val_hi) {
338fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  bool lo_match = false;
339fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LIR* lo_target = NULL;
340fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  while (data_target) {
341fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (lo_match && (data_target->operands[0] == val_hi)) {
3424ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      // Record high word in case we need to expand this later.
3434ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      lo_target->operands[1] = val_hi;
344fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      return lo_target;
34531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee    }
346fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    lo_match = false;
347fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (data_target->operands[0] == val_lo) {
348fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      lo_match = true;
349fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      lo_target = data_target;
350a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    }
351fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    data_target = data_target->next;
352a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
353a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return NULL;
35431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
35531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
35631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/*
35731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * The following are building blocks to insert constants into the pool or
35831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * instruction streams.
35931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */
36031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
3614ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee/* Add a 32-bit constant to the constant pool */
3622ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::AddWordData(LIR* *constant_list_p, int value) {
363a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* Add the constant to the literal pool */
364fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (constant_list_p) {
365f6c4b3ba3825de1dbb3e747a68b809c6cc8eb4dbMathieu Chartier    LIR* new_value = static_cast<LIR*>(arena_->Alloc(sizeof(LIR), ArenaAllocator::kAllocData));
366fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    new_value->operands[0] = value;
367fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    new_value->next = *constant_list_p;
368fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    *constant_list_p = new_value;
369b48819db07f9a0992a72173380c24249d7fc648abuzbee    estimated_native_code_size_ += sizeof(value);
370fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    return new_value;
371a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
372a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return NULL;
37331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
37431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
37531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* Add a 64-bit constant to the constant pool or mixed with code */
3762ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::AddWideData(LIR* *constant_list_p, int val_lo, int val_hi) {
3771fd3346740dfb7f47be9922312b68a4227fada96buzbee  AddWordData(constant_list_p, val_hi);
3781fd3346740dfb7f47be9922312b68a4227fada96buzbee  return AddWordData(constant_list_p, val_lo);
37931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
38031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
381aad94383fc41e8f8770f0b2144f766a2ffa772e7buzbeestatic void PushWord(std::vector<uint8_t>&buf, int data) {
382df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom  buf.push_back(data & 0xff);
383df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom  buf.push_back((data >> 8) & 0xff);
384df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom  buf.push_back((data >> 16) & 0xff);
385df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom  buf.push_back((data >> 24) & 0xff);
386e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
387e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
3880d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee// Push 8 bytes on 64-bit systems; 4 on 32-bit systems.
3890d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeestatic void PushPointer(std::vector<uint8_t>&buf, void const* pointer) {
3900d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  uintptr_t data = reinterpret_cast<uintptr_t>(pointer);
3910d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  if (sizeof(void*) == sizeof(uint64_t)) {
3920d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    PushWord(buf, (data >> (sizeof(void*) * 4)) & 0xFFFFFFFF);
3930d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    PushWord(buf, data & 0xFFFFFFFF);
3940d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  } else {
3950d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    PushWord(buf, data);
3960d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  }
3970d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee}
3980d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee
399aad94383fc41e8f8770f0b2144f766a2ffa772e7buzbeestatic void AlignBuffer(std::vector<uint8_t>&buf, size_t offset) {
400a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  while (buf.size() < offset) {
401a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    buf.push_back(0);
402a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
403e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
404e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
405e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the literal pool to the output stream */
4062ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallLiteralPools() {
4071fd3346740dfb7f47be9922312b68a4227fada96buzbee  AlignBuffer(code_buffer_, data_offset_);
4081fd3346740dfb7f47be9922312b68a4227fada96buzbee  LIR* data_lir = literal_list_;
409fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  while (data_lir != NULL) {
4101fd3346740dfb7f47be9922312b68a4227fada96buzbee    PushWord(code_buffer_, data_lir->operands[0]);
411fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    data_lir = NEXT_LIR(data_lir);
412a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
413a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  // Push code and method literals, record offsets for the compiler to patch.
4141fd3346740dfb7f47be9922312b68a4227fada96buzbee  data_lir = code_literal_list_;
415fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  while (data_lir != NULL) {
416fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    uint32_t target = data_lir->operands[0];
4171fd3346740dfb7f47be9922312b68a4227fada96buzbee    cu_->compiler_driver->AddCodePatch(cu_->dex_file,
4188b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                       cu_->class_def_idx,
4198b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                       cu_->method_idx,
4208b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                       cu_->invoke_type,
4218b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                       target,
4228b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                       static_cast<InvokeType>(data_lir->operands[1]),
4238b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                       code_buffer_.size());
4241fd3346740dfb7f47be9922312b68a4227fada96buzbee    const DexFile::MethodId& id = cu_->dex_file->GetMethodId(target);
4250d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    // unique value based on target to ensure code deduplication works
4260d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    PushPointer(code_buffer_, &id);
427fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    data_lir = NEXT_LIR(data_lir);
428137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers  }
4291fd3346740dfb7f47be9922312b68a4227fada96buzbee  data_lir = method_literal_list_;
430fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  while (data_lir != NULL) {
431fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    uint32_t target = data_lir->operands[0];
4321fd3346740dfb7f47be9922312b68a4227fada96buzbee    cu_->compiler_driver->AddMethodPatch(cu_->dex_file,
4338b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                         cu_->class_def_idx,
4348b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                         cu_->method_idx,
4358b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                         cu_->invoke_type,
4368b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                         target,
4378b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                         static_cast<InvokeType>(data_lir->operands[1]),
4388b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                         code_buffer_.size());
4391fd3346740dfb7f47be9922312b68a4227fada96buzbee    const DexFile::MethodId& id = cu_->dex_file->GetMethodId(target);
4400d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    // unique value based on target to ensure code deduplication works
4410d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    PushPointer(code_buffer_, &id);
442fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    data_lir = NEXT_LIR(data_lir);
443a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
444be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi  // Push class literals.
445be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi  data_lir = class_literal_list_;
446be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi  while (data_lir != NULL) {
447be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi    uint32_t target = data_lir->operands[0];
448be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi    cu_->compiler_driver->AddClassPatch(cu_->dex_file,
449be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi                                        cu_->class_def_idx,
450be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi                                        cu_->method_idx,
451be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi                                        target,
452be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi                                        code_buffer_.size());
453be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi    const DexFile::TypeId& id = cu_->dex_file->GetTypeId(target);
454be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi    // unique value based on target to ensure code deduplication works
455be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi    PushPointer(code_buffer_, &id);
456be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi    data_lir = NEXT_LIR(data_lir);
457be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi  }
458e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
459e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
460e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the switch tables to the output stream */
4612ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallSwitchTables() {
462862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_);
463a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  while (true) {
464862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    Mir2Lir::SwitchTable* tab_rec = iterator.Next();
465fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec == NULL) break;
4661fd3346740dfb7f47be9922312b68a4227fada96buzbee    AlignBuffer(code_buffer_, tab_rec->offset);
467a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    /*
468a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     * For Arm, our reference point is the address of the bx
469a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     * instruction that does the launch, so we have to subtract
470a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     * the auto pc-advance.  For other targets the reference point
471a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     * is a label, so we can use the offset as-is.
472a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     */
473fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    int bx_offset = INVALID_OFFSET;
4741fd3346740dfb7f47be9922312b68a4227fada96buzbee    switch (cu_->instruction_set) {
475b046e16d8b8da318d6055f9308950131f1255e08buzbee      case kThumb2:
476b48819db07f9a0992a72173380c24249d7fc648abuzbee        DCHECK(tab_rec->anchor->flags.fixup != kFixupNone);
477fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        bx_offset = tab_rec->anchor->offset + 4;
478b046e16d8b8da318d6055f9308950131f1255e08buzbee        break;
479b046e16d8b8da318d6055f9308950131f1255e08buzbee      case kX86:
480fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        bx_offset = 0;
481b046e16d8b8da318d6055f9308950131f1255e08buzbee        break;
482b046e16d8b8da318d6055f9308950131f1255e08buzbee      case kMips:
483fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        bx_offset = tab_rec->anchor->offset;
484b046e16d8b8da318d6055f9308950131f1255e08buzbee        break;
4851fd3346740dfb7f47be9922312b68a4227fada96buzbee      default: LOG(FATAL) << "Unexpected instruction set: " << cu_->instruction_set;
486b046e16d8b8da318d6055f9308950131f1255e08buzbee    }
4871fd3346740dfb7f47be9922312b68a4227fada96buzbee    if (cu_->verbose) {
488fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      LOG(INFO) << "Switch table for offset 0x" << std::hex << bx_offset;
489a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    }
490fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) {
4910d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee      const int32_t* keys = reinterpret_cast<const int32_t*>(&(tab_rec->table[2]));
492fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      for (int elems = 0; elems < tab_rec->table[1]; elems++) {
493fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        int disp = tab_rec->targets[elems]->offset - bx_offset;
4941fd3346740dfb7f47be9922312b68a4227fada96buzbee        if (cu_->verbose) {
495a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee          LOG(INFO) << "  Case[" << elems << "] key: 0x"
496a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                    << std::hex << keys[elems] << ", disp: 0x"
497a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                    << std::hex << disp;
498e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee        }
4991fd3346740dfb7f47be9922312b68a4227fada96buzbee        PushWord(code_buffer_, keys[elems]);
5001fd3346740dfb7f47be9922312b68a4227fada96buzbee        PushWord(code_buffer_,
501fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee          tab_rec->targets[elems]->offset - bx_offset);
502a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
503a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    } else {
504fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      DCHECK_EQ(static_cast<int>(tab_rec->table[0]),
505a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                static_cast<int>(Instruction::kPackedSwitchSignature));
506fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      for (int elems = 0; elems < tab_rec->table[1]; elems++) {
507fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        int disp = tab_rec->targets[elems]->offset - bx_offset;
5081fd3346740dfb7f47be9922312b68a4227fada96buzbee        if (cu_->verbose) {
509a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee          LOG(INFO) << "  Case[" << elems << "] disp: 0x"
510a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                    << std::hex << disp;
511e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee        }
5121fd3346740dfb7f47be9922312b68a4227fada96buzbee        PushWord(code_buffer_, tab_rec->targets[elems]->offset - bx_offset);
513a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
514e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee    }
515a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
516e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
517e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
518e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the fill array dta to the output stream */
5192ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallFillArrayData() {
520862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<FillArrayData*>::Iterator iterator(&fill_array_data_);
521a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  while (true) {
522862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    Mir2Lir::FillArrayData *tab_rec = iterator.Next();
523fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec == NULL) break;
5241fd3346740dfb7f47be9922312b68a4227fada96buzbee    AlignBuffer(code_buffer_, tab_rec->offset);
525fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    for (int i = 0; i < (tab_rec->size + 1) / 2; i++) {
526df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom      code_buffer_.push_back(tab_rec->table[i] & 0xFF);
527df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom      code_buffer_.push_back((tab_rec->table[i] >> 8) & 0xFF);
528e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee    }
529a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
530e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
531e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
5320d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeestatic int AssignLiteralOffsetCommon(LIR* lir, CodeOffset offset) {
53302c8cc6d1312a2b55533f02f6369dc7c94672f90Brian Carlstrom  for (; lir != NULL; lir = lir->next) {
534a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    lir->offset = offset;
535a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    offset += 4;
536a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
537a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return offset;
538e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
539e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
5400d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeestatic int AssignLiteralPointerOffsetCommon(LIR* lir, CodeOffset offset) {
5410d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  unsigned int element_size = sizeof(void*);
5420d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  // Align to natural pointer size.
5430d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  offset = (offset + (element_size - 1)) & ~(element_size - 1);
5440d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  for (; lir != NULL; lir = lir->next) {
5450d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    lir->offset = offset;
5460d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    offset += element_size;
5470d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  }
5480d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  return offset;
5490d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee}
5500d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee
5516459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee// Make sure we have a code address for every declared catch entry
5522ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::VerifyCatchEntries() {
55306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  MappingTable table(&encoded_mapping_table_[0]);
55406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  std::vector<uint32_t> dex_pcs;
55506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  dex_pcs.reserve(table.DexToPcSize());
55606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  for (auto it = table.DexToPcBegin(), end = table.DexToPcEnd(); it != end; ++it) {
55706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    dex_pcs.push_back(it.DexPc());
55806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  }
55906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  // Sort dex_pcs, so that we can quickly check it against the ordered mir_graph_->catches_.
56006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  std::sort(dex_pcs.begin(), dex_pcs.end());
56106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko
5626459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee  bool success = true;
56306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  auto it = dex_pcs.begin(), end = dex_pcs.end();
56406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  for (uint32_t dex_pc : mir_graph_->catches_) {
56506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    while (it != end && *it < dex_pc) {
56606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      LOG(INFO) << "Unexpected catch entry @ dex pc 0x" << std::hex << *it;
56706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      ++it;
5686459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee      success = false;
5696459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee    }
57006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    if (it == end || *it > dex_pc) {
57106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      LOG(INFO) << "Missing native PC for catch entry @ 0x" << std::hex << dex_pc;
5726459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee      success = false;
57306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    } else {
57406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      ++it;
5756459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee    }
5766459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee  }
5776459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee  if (!success) {
5781fd3346740dfb7f47be9922312b68a4227fada96buzbee    LOG(INFO) << "Bad dex2pcMapping table in " << PrettyMethod(cu_->method_idx, *cu_->dex_file);
5791fd3346740dfb7f47be9922312b68a4227fada96buzbee    LOG(INFO) << "Entries @ decode: " << mir_graph_->catches_.size() << ", Entries in table: "
58006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko              << table.DexToPcSize();
5816459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee  }
5826459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee  return success;
5836459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee}
5846459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee
585311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
5862ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::CreateMappingTables() {
5871e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t pc2dex_data_size = 0u;
5881e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t pc2dex_entries = 0u;
5891e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t pc2dex_offset = 0u;
5901e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t pc2dex_dalvik_offset = 0u;
5911e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t dex2pc_data_size = 0u;
5921e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t dex2pc_entries = 0u;
5931e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t dex2pc_offset = 0u;
5941e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t dex2pc_dalvik_offset = 0u;
5951fd3346740dfb7f47be9922312b68a4227fada96buzbee  for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) {
596fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) {
5971e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      pc2dex_entries += 1;
5981e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      DCHECK(pc2dex_offset <= tgt_lir->offset);
5991e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      pc2dex_data_size += UnsignedLeb128Size(tgt_lir->offset - pc2dex_offset);
6001e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      pc2dex_data_size += SignedLeb128Size(static_cast<int32_t>(tgt_lir->dalvik_offset) -
6011e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko                                           static_cast<int32_t>(pc2dex_dalvik_offset));
6021e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      pc2dex_offset = tgt_lir->offset;
6031e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      pc2dex_dalvik_offset = tgt_lir->dalvik_offset;
604a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee    }
605fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) {
6061e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      dex2pc_entries += 1;
6071e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      DCHECK(dex2pc_offset <= tgt_lir->offset);
6081e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      dex2pc_data_size += UnsignedLeb128Size(tgt_lir->offset - dex2pc_offset);
6091e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      dex2pc_data_size += SignedLeb128Size(static_cast<int32_t>(tgt_lir->dalvik_offset) -
6101e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko                                           static_cast<int32_t>(dex2pc_dalvik_offset));
6111e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      dex2pc_offset = tgt_lir->offset;
6121e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      dex2pc_dalvik_offset = tgt_lir->dalvik_offset;
613e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee    }
614a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
6151e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko
6161e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t total_entries = pc2dex_entries + dex2pc_entries;
6171e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t hdr_data_size = UnsignedLeb128Size(total_entries) + UnsignedLeb128Size(pc2dex_entries);
6181e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t data_size = hdr_data_size + pc2dex_data_size + dex2pc_data_size;
61906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  encoded_mapping_table_.resize(data_size);
62006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  uint8_t* write_pos = &encoded_mapping_table_[0];
62106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  write_pos = EncodeUnsignedLeb128(write_pos, total_entries);
62206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  write_pos = EncodeUnsignedLeb128(write_pos, pc2dex_entries);
62306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  DCHECK_EQ(static_cast<size_t>(write_pos - &encoded_mapping_table_[0]), hdr_data_size);
62406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  uint8_t* write_pos2 = write_pos + pc2dex_data_size;
6251e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko
6261e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  pc2dex_offset = 0u;
6271e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  pc2dex_dalvik_offset = 0u;
62806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  dex2pc_offset = 0u;
62906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  dex2pc_dalvik_offset = 0u;
63006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) {
63106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) {
63206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      DCHECK(pc2dex_offset <= tgt_lir->offset);
63306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      write_pos = EncodeUnsignedLeb128(write_pos, tgt_lir->offset - pc2dex_offset);
63406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      write_pos = EncodeSignedLeb128(write_pos, static_cast<int32_t>(tgt_lir->dalvik_offset) -
63506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko                                     static_cast<int32_t>(pc2dex_dalvik_offset));
63606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      pc2dex_offset = tgt_lir->offset;
63706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      pc2dex_dalvik_offset = tgt_lir->dalvik_offset;
63806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    }
63906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) {
64006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      DCHECK(dex2pc_offset <= tgt_lir->offset);
64106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      write_pos2 = EncodeUnsignedLeb128(write_pos2, tgt_lir->offset - dex2pc_offset);
64206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      write_pos2 = EncodeSignedLeb128(write_pos2, static_cast<int32_t>(tgt_lir->dalvik_offset) -
64306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko                                      static_cast<int32_t>(dex2pc_dalvik_offset));
64406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      dex2pc_offset = tgt_lir->offset;
64506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      dex2pc_dalvik_offset = tgt_lir->dalvik_offset;
64606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    }
6471e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  }
64806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  DCHECK_EQ(static_cast<size_t>(write_pos - &encoded_mapping_table_[0]),
64906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko            hdr_data_size + pc2dex_data_size);
65006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  DCHECK_EQ(static_cast<size_t>(write_pos2 - &encoded_mapping_table_[0]), data_size);
6511e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko
65296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  if (kIsDebugBuild) {
65306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    CHECK(VerifyCatchEntries());
65406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko
65596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    // Verify the encoded table holds the expected data.
65606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    MappingTable table(&encoded_mapping_table_[0]);
65796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    CHECK_EQ(table.TotalSize(), total_entries);
65896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    CHECK_EQ(table.PcToDexSize(), pc2dex_entries);
6591e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko    auto it = table.PcToDexBegin();
6601e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko    auto it2 = table.DexToPcBegin();
66106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) {
66206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) {
66306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko        CHECK_EQ(tgt_lir->offset, it.NativePcOffset());
66406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko        CHECK_EQ(tgt_lir->dalvik_offset, it.DexPc());
66506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko        ++it;
66606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      }
66706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) {
66806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko        CHECK_EQ(tgt_lir->offset, it2.NativePcOffset());
66906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko        CHECK_EQ(tgt_lir->dalvik_offset, it2.DexPc());
67006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko        ++it2;
67106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      }
67296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    }
67306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    CHECK(it == table.PcToDexEnd());
6741e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko    CHECK(it2 == table.DexToPcEnd());
675311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  }
676e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
677e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
6780c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogersclass NativePcToReferenceMapBuilder {
6790c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers public:
6800c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  NativePcToReferenceMapBuilder(std::vector<uint8_t>* table,
6810c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers                                size_t entries, uint32_t max_native_offset,
6820c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers                                size_t references_width) : entries_(entries),
6830c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers                                references_width_(references_width), in_use_(entries),
6840c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers                                table_(table) {
6850c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    // Compute width in bytes needed to hold max_native_offset.
6860c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    native_offset_width_ = 0;
6870c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    while (max_native_offset != 0) {
6880c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers      native_offset_width_++;
6890c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers      max_native_offset >>= 8;
6900c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    }
6910c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    // Resize table and set up header.
6920c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    table->resize((EntryWidth() * entries) + sizeof(uint32_t));
693000d724207b4ff32fcbc9744da76d2f594675eedIan Rogers    CHECK_LT(native_offset_width_, 1U << 3);
694000d724207b4ff32fcbc9744da76d2f594675eedIan Rogers    (*table)[0] = native_offset_width_ & 7;
695000d724207b4ff32fcbc9744da76d2f594675eedIan Rogers    CHECK_LT(references_width_, 1U << 13);
696000d724207b4ff32fcbc9744da76d2f594675eedIan Rogers    (*table)[0] |= (references_width_ << 3) & 0xFF;
697000d724207b4ff32fcbc9744da76d2f594675eedIan Rogers    (*table)[1] = (references_width_ >> 5) & 0xFF;
6980c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    CHECK_LT(entries, 1U << 16);
6990c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    (*table)[2] = entries & 0xFF;
7000c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    (*table)[3] = (entries >> 8) & 0xFF;
7010c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
7020c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
7030c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  void AddEntry(uint32_t native_offset, const uint8_t* references) {
7040c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    size_t table_index = TableIndex(native_offset);
7050c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    while (in_use_[table_index]) {
7060c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers      table_index = (table_index + 1) % entries_;
7070c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    }
7080c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    in_use_[table_index] = true;
7090d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    SetCodeOffset(table_index, native_offset);
7100d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    DCHECK_EQ(native_offset, GetCodeOffset(table_index));
7110c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    SetReferences(table_index, references);
7120c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
7130c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
7140c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers private:
7150c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  size_t TableIndex(uint32_t native_offset) {
7160c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    return NativePcOffsetToReferenceMap::Hash(native_offset) % entries_;
7170c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
7180c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
7190d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  uint32_t GetCodeOffset(size_t table_index) {
7200c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    uint32_t native_offset = 0;
7210c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    size_t table_offset = (table_index * EntryWidth()) + sizeof(uint32_t);
7220c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    for (size_t i = 0; i < native_offset_width_; i++) {
7230c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers      native_offset |= (*table_)[table_offset + i] << (i * 8);
7240c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    }
7250c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    return native_offset;
7260c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
7270c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
7280d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  void SetCodeOffset(size_t table_index, uint32_t native_offset) {
7290c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    size_t table_offset = (table_index * EntryWidth()) + sizeof(uint32_t);
7300c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    for (size_t i = 0; i < native_offset_width_; i++) {
7310c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers      (*table_)[table_offset + i] = (native_offset >> (i * 8)) & 0xFF;
7320c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    }
7330c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
7340c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
7350c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  void SetReferences(size_t table_index, const uint8_t* references) {
7360c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    size_t table_offset = (table_index * EntryWidth()) + sizeof(uint32_t);
7370c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    memcpy(&(*table_)[table_offset + native_offset_width_], references, references_width_);
7380c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
7390c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
7400c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  size_t EntryWidth() const {
7410c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    return native_offset_width_ + references_width_;
7420c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
7430c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
7440c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  // Number of entries in the table.
7450c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  const size_t entries_;
7460c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  // Number of bytes used to encode the reference bitmap.
7470c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  const size_t references_width_;
7480c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  // Number of bytes used to encode a native offset.
7490c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  size_t native_offset_width_;
7500c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  // Entries that are in use.
7510c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  std::vector<bool> in_use_;
7520c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  // The table we're building.
7530c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  std::vector<uint8_t>* const table_;
7540c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers};
7550c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
7561fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::CreateNativeGcMap() {
75706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  DCHECK(!encoded_mapping_table_.empty());
75806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  MappingTable mapping_table(&encoded_mapping_table_[0]);
7590c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  uint32_t max_native_offset = 0;
76006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  for (auto it = mapping_table.PcToDexBegin(), end = mapping_table.PcToDexEnd(); it != end; ++it) {
76106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    uint32_t native_offset = it.NativePcOffset();
7620c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    if (native_offset > max_native_offset) {
7630c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers      max_native_offset = native_offset;
7640c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    }
7650c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
76651c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom  MethodReference method_ref(cu_->dex_file, cu_->method_idx);
7672730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko  const std::vector<uint8_t>& gc_map_raw =
7682730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko      mir_graph_->GetCurrentDexCompilationUnit()->GetVerifiedMethod()->GetDexGcMap();
7692730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko  verifier::DexPcToReferenceMap dex_gc_map(&(gc_map_raw)[0]);
7702730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko  DCHECK_EQ(gc_map_raw.size(), dex_gc_map.RawSize());
7710c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  // Compute native offset to references size.
7721fd3346740dfb7f47be9922312b68a4227fada96buzbee  NativePcToReferenceMapBuilder native_gc_map_builder(&native_gc_map_,
77306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko                                                      mapping_table.PcToDexSize(),
77406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko                                                      max_native_offset, dex_gc_map.RegWidth());
7750c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
77606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  for (auto it = mapping_table.PcToDexBegin(), end = mapping_table.PcToDexEnd(); it != end; ++it) {
77706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    uint32_t native_offset = it.NativePcOffset();
77806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    uint32_t dex_pc = it.DexPc();
7790c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    const uint8_t* references = dex_gc_map.FindBitMap(dex_pc, false);
780a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee    CHECK(references != NULL) << "Missing ref for dex pc 0x" << std::hex << dex_pc;
781a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee    native_gc_map_builder.AddEntry(native_offset, references);
7820c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
7830c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers}
7840c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
785e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Determine the offset of each literal field */
7860d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignLiteralOffset(CodeOffset offset) {
7871fd3346740dfb7f47be9922312b68a4227fada96buzbee  offset = AssignLiteralOffsetCommon(literal_list_, offset);
7880d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  offset = AssignLiteralPointerOffsetCommon(code_literal_list_, offset);
7890d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  offset = AssignLiteralPointerOffsetCommon(method_literal_list_, offset);
790be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi  offset = AssignLiteralPointerOffsetCommon(class_literal_list_, offset);
791a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return offset;
792e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
793e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
7940d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignSwitchTablesOffset(CodeOffset offset) {
795862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_);
796a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  while (true) {
7970d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    Mir2Lir::SwitchTable* tab_rec = iterator.Next();
798fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec == NULL) break;
799fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    tab_rec->offset = offset;
800fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) {
801fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      offset += tab_rec->table[1] * (sizeof(int) * 2);
802a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    } else {
803fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      DCHECK_EQ(static_cast<int>(tab_rec->table[0]),
804a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                static_cast<int>(Instruction::kPackedSwitchSignature));
805fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      offset += tab_rec->table[1] * sizeof(int);
806e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee    }
807a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
808a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return offset;
809e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
810e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
8110d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignFillArrayDataOffset(CodeOffset offset) {
812862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<FillArrayData*>::Iterator iterator(&fill_array_data_);
813a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  while (true) {
814862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    Mir2Lir::FillArrayData *tab_rec = iterator.Next();
815fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec == NULL) break;
816fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    tab_rec->offset = offset;
817fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    offset += tab_rec->size;
818a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    // word align
819a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    offset = (offset + 3) & ~3;
820a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    }
821a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return offset;
822e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
823e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
82431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/*
82531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Insert a kPseudoCaseLabel at the beginning of the Dalvik
826b48819db07f9a0992a72173380c24249d7fc648abuzbee * offset vaddr if pretty-printing, otherise use the standard block
827b48819db07f9a0992a72173380c24249d7fc648abuzbee * label.  The selected label will be used to fix up the case
828252254b130067cd7a5071865e793966871ae0246buzbee * branch table during the assembly phase.  All resource flags
829252254b130067cd7a5071865e793966871ae0246buzbee * are set to prevent code motion.  KeyVal is just there for debugging.
83031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */
8310d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeLIR* Mir2Lir::InsertCaseLabel(DexOffset vaddr, int keyVal) {
832252254b130067cd7a5071865e793966871ae0246buzbee  LIR* boundary_lir = &block_label_list_[mir_graph_->FindBlock(vaddr)->id];
833b48819db07f9a0992a72173380c24249d7fc648abuzbee  LIR* res = boundary_lir;
834b48819db07f9a0992a72173380c24249d7fc648abuzbee  if (cu_->verbose) {
835b48819db07f9a0992a72173380c24249d7fc648abuzbee    // Only pay the expense if we're pretty-printing.
836b48819db07f9a0992a72173380c24249d7fc648abuzbee    LIR* new_label = static_cast<LIR*>(arena_->Alloc(sizeof(LIR), ArenaAllocator::kAllocLIR));
837b48819db07f9a0992a72173380c24249d7fc648abuzbee    new_label->dalvik_offset = vaddr;
838b48819db07f9a0992a72173380c24249d7fc648abuzbee    new_label->opcode = kPseudoCaseLabel;
839b48819db07f9a0992a72173380c24249d7fc648abuzbee    new_label->operands[0] = keyVal;
840b48819db07f9a0992a72173380c24249d7fc648abuzbee    new_label->flags.fixup = kFixupLabel;
841b48819db07f9a0992a72173380c24249d7fc648abuzbee    DCHECK(!new_label->flags.use_def_invalid);
842b48819db07f9a0992a72173380c24249d7fc648abuzbee    new_label->u.m.def_mask = ENCODE_ALL;
843b48819db07f9a0992a72173380c24249d7fc648abuzbee    InsertLIRAfter(boundary_lir, new_label);
844b48819db07f9a0992a72173380c24249d7fc648abuzbee    res = new_label;
845b48819db07f9a0992a72173380c24249d7fc648abuzbee  }
846b48819db07f9a0992a72173380c24249d7fc648abuzbee  return res;
84731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
84831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
8490d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkPackedCaseLabels(Mir2Lir::SwitchTable* tab_rec) {
850fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  const uint16_t* table = tab_rec->table;
8510d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  DexOffset base_vaddr = tab_rec->vaddr;
8520d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  const int32_t *targets = reinterpret_cast<const int32_t*>(&table[4]);
853a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int entries = table[1];
854fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int low_key = s4FromSwitchData(&table[2]);
855a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  for (int i = 0; i < entries; i++) {
8561fd3346740dfb7f47be9922312b68a4227fada96buzbee    tab_rec->targets[i] = InsertCaseLabel(base_vaddr + targets[i], i + low_key);
857a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
85831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
85931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
8600d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkSparseCaseLabels(Mir2Lir::SwitchTable* tab_rec) {
861fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  const uint16_t* table = tab_rec->table;
8620d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  DexOffset base_vaddr = tab_rec->vaddr;
863a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int entries = table[1];
8640d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  const int32_t* keys = reinterpret_cast<const int32_t*>(&table[2]);
8650d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  const int32_t* targets = &keys[entries];
866a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  for (int i = 0; i < entries; i++) {
8671fd3346740dfb7f47be9922312b68a4227fada96buzbee    tab_rec->targets[i] = InsertCaseLabel(base_vaddr + targets[i], keys[i]);
868a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
86931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
87031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
8712ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::ProcessSwitchTables() {
872862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_);
873a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  while (true) {
874862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    Mir2Lir::SwitchTable *tab_rec = iterator.Next();
875fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec == NULL) break;
876fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec->table[0] == Instruction::kPackedSwitchSignature) {
8771fd3346740dfb7f47be9922312b68a4227fada96buzbee      MarkPackedCaseLabels(tab_rec);
878fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    } else if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) {
8791fd3346740dfb7f47be9922312b68a4227fada96buzbee      MarkSparseCaseLabels(tab_rec);
880a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    } else {
881a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(FATAL) << "Invalid switch table";
88231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee    }
883a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
88431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
88531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
8862ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpSparseSwitchTable(const uint16_t* table) {
887a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /*
888a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * Sparse switch data format:
889a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  ushort ident = 0x0200   magic value
890a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  ushort size       number of entries in the table; > 0
891a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  int keys[size]      keys, sorted low-to-high; 32-bit aligned
892a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  int targets[size]     branch targets, relative to switch opcode
893a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *
894a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * Total size is (2+size*4) 16-bit code units.
895a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   */
896eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee  uint16_t ident = table[0];
897a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int entries = table[1];
8980d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  const int32_t* keys = reinterpret_cast<const int32_t*>(&table[2]);
8990d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  const int32_t* targets = &keys[entries];
900a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  LOG(INFO) <<  "Sparse switch table - ident:0x" << std::hex << ident
901a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee            << ", entries: " << std::dec << entries;
902a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  for (int i = 0; i < entries; i++) {
903a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    LOG(INFO) << "  Key[" << keys[i] << "] -> 0x" << std::hex << targets[i];
904a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
90531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
90631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
9072ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpPackedSwitchTable(const uint16_t* table) {
908a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /*
909a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * Packed switch data format:
910a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  ushort ident = 0x0100   magic value
911a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  ushort size       number of entries in the table
912a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  int first_key       first (and lowest) switch case value
913a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  int targets[size]     branch targets, relative to switch opcode
914a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *
915a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * Total size is (4+size*2) 16-bit code units.
916a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   */
917eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee  uint16_t ident = table[0];
9180d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  const int32_t* targets = reinterpret_cast<const int32_t*>(&table[4]);
919a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int entries = table[1];
920fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int low_key = s4FromSwitchData(&table[2]);
921a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  LOG(INFO) << "Packed switch table - ident:0x" << std::hex << ident
922fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee            << ", entries: " << std::dec << entries << ", low_key: " << low_key;
923a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  for (int i = 0; i < entries; i++) {
924fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    LOG(INFO) << "  Key[" << (i + low_key) << "] -> 0x" << std::hex
925a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee              << targets[i];
926a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
92731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
928e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
929252254b130067cd7a5071865e793966871ae0246buzbee/* Set up special LIR to mark a Dalvik byte-code instruction start for pretty printing */
9300d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkBoundary(DexOffset offset, const char* inst_str) {
9310d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  // NOTE: only used for debug listings.
9320d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  NewLIR1(kPseudoDalvikByteCodeBoundary, WrapPointer(ArenaStrdup(inst_str)));
933d1643e41ef242ae656f667bf3c8b0324635cefd3buzbee}
934e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
9352ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::EvaluateBranch(Instruction::Code opcode, int32_t src1, int32_t src2) {
936e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee  bool is_taken;
937e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee  switch (opcode) {
938e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_EQ: is_taken = (src1 == src2); break;
939e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_NE: is_taken = (src1 != src2); break;
940e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_LT: is_taken = (src1 < src2); break;
941e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_GE: is_taken = (src1 >= src2); break;
942e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_GT: is_taken = (src1 > src2); break;
943e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_LE: is_taken = (src1 <= src2); break;
944e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_EQZ: is_taken = (src1 == 0); break;
945e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_NEZ: is_taken = (src1 != 0); break;
946e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_LTZ: is_taken = (src1 < 0); break;
947e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_GEZ: is_taken = (src1 >= 0); break;
948e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_GTZ: is_taken = (src1 > 0); break;
949e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_LEZ: is_taken = (src1 <= 0); break;
950e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    default:
951e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee      LOG(FATAL) << "Unexpected opcode " << opcode;
952e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee      is_taken = false;
953e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee  }
954e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee  return is_taken;
955e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee}
956e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee
9574ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee// Convert relation of src1/src2 to src2/src1
9581fd3346740dfb7f47be9922312b68a4227fada96buzbeeConditionCode Mir2Lir::FlipComparisonOrder(ConditionCode before) {
9594ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  ConditionCode res;
9604ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  switch (before) {
9614ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    case kCondEq: res = kCondEq; break;
9624ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    case kCondNe: res = kCondNe; break;
9634ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    case kCondLt: res = kCondGt; break;
9644ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    case kCondGt: res = kCondLt; break;
9654ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    case kCondLe: res = kCondGe; break;
9664ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    case kCondGe: res = kCondLe; break;
9674ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    default:
9684ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      res = static_cast<ConditionCode>(0);
9694ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      LOG(FATAL) << "Unexpected ccode " << before;
9704ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  }
9714ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  return res;
9724ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee}
9734ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee
974862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee// TODO: move to mir_to_lir.cc
975862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbeeMir2Lir::Mir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena)
9766282dc12440a2072dc06a616160027ff21bd895eIan Rogers    : Backend(arena),
9776282dc12440a2072dc06a616160027ff21bd895eIan Rogers      literal_list_(NULL),
9781fd3346740dfb7f47be9922312b68a4227fada96buzbee      method_literal_list_(NULL),
979be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi      class_literal_list_(NULL),
9801fd3346740dfb7f47be9922312b68a4227fada96buzbee      code_literal_list_(NULL),
981b48819db07f9a0992a72173380c24249d7fc648abuzbee      first_fixup_(NULL),
9821fd3346740dfb7f47be9922312b68a4227fada96buzbee      cu_(cu),
9831fd3346740dfb7f47be9922312b68a4227fada96buzbee      mir_graph_(mir_graph),
984862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      switch_tables_(arena, 4, kGrowableArraySwitchTables),
985862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      fill_array_data_(arena, 4, kGrowableArrayFillArrayData),
986862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      throw_launchpads_(arena, 2048, kGrowableArrayThrowLaunchPads),
987862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      suspend_launchpads_(arena, 4, kGrowableArraySuspendLaunchPads),
988862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      intrinsic_launchpads_(arena, 2048, kGrowableArrayMisc),
989bd663de599b16229085759366c56e2ed5a1dc7ecbuzbee      tempreg_info_(arena, 20, kGrowableArrayMisc),
990bd663de599b16229085759366c56e2ed5a1dc7ecbuzbee      reginfo_map_(arena, 64, kGrowableArrayMisc),
9910d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee      pointer_storage_(arena, 128, kGrowableArrayMisc),
9921fd3346740dfb7f47be9922312b68a4227fada96buzbee      data_offset_(0),
9931fd3346740dfb7f47be9922312b68a4227fada96buzbee      total_size_(0),
9941fd3346740dfb7f47be9922312b68a4227fada96buzbee      block_label_list_(NULL),
995d69835d841cb7663faaa2f1996e73e8c0b3f6d76buzbee      promotion_map_(NULL),
996862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      current_dalvik_offset_(0),
997b48819db07f9a0992a72173380c24249d7fc648abuzbee      estimated_native_code_size_(0),
998862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      reg_pool_(NULL),
9991fd3346740dfb7f47be9922312b68a4227fada96buzbee      live_sreg_(0),
10001fd3346740dfb7f47be9922312b68a4227fada96buzbee      num_core_spills_(0),
10011fd3346740dfb7f47be9922312b68a4227fada96buzbee      num_fp_spills_(0),
10021fd3346740dfb7f47be9922312b68a4227fada96buzbee      frame_size_(0),
10031fd3346740dfb7f47be9922312b68a4227fada96buzbee      core_spill_mask_(0),
10041fd3346740dfb7f47be9922312b68a4227fada96buzbee      fp_spill_mask_(0),
10051fd3346740dfb7f47be9922312b68a4227fada96buzbee      first_lir_insn_(NULL),
10065816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko      last_lir_insn_(NULL) {
10070d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  // Reserve pointer id 0 for NULL.
10080d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  size_t null_idx = WrapPointer(NULL);
10090d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  DCHECK_EQ(null_idx, 0U);
10101fd3346740dfb7f47be9922312b68a4227fada96buzbee}
10111fd3346740dfb7f47be9922312b68a4227fada96buzbee
10121fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::Materialize() {
1013a61f49539a59b610e557b5513695295639496750buzbee  cu_->NewTimingSplit("RegisterAllocation");
10141fd3346740dfb7f47be9922312b68a4227fada96buzbee  CompilerInitializeRegAlloc();  // Needs to happen after SSA naming
10151fd3346740dfb7f47be9922312b68a4227fada96buzbee
10161fd3346740dfb7f47be9922312b68a4227fada96buzbee  /* Allocate Registers using simple local allocation scheme */
10171fd3346740dfb7f47be9922312b68a4227fada96buzbee  SimpleRegAlloc();
10181fd3346740dfb7f47be9922312b68a4227fada96buzbee
10195816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko  /*
10205816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko   * Custom codegen for special cases.  If for any reason the
10215115473c81ec855a5646a5f755afb26aa7f2b1e9Vladimir Marko   * special codegen doesn't succeed, first_lir_insn_ will be
10225816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko   * set to NULL;
10235816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko   */
10245816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko  // TODO: Clean up GenSpecial() and return true only if special implementation is emitted.
10255816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko  // Currently, GenSpecial() returns IsSpecial() but doesn't check after SpecialMIR2LIR().
10265816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko  DCHECK(cu_->compiler_driver->GetMethodInlinerMap() != nullptr);
10275816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko  cu_->compiler_driver->GetMethodInlinerMap()->GetMethodInliner(cu_->dex_file)
10285816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko      ->GenSpecial(this, cu_->method_idx);
10291fd3346740dfb7f47be9922312b68a4227fada96buzbee
10301fd3346740dfb7f47be9922312b68a4227fada96buzbee  /* Convert MIR to LIR, etc. */
10311fd3346740dfb7f47be9922312b68a4227fada96buzbee  if (first_lir_insn_ == NULL) {
10321fd3346740dfb7f47be9922312b68a4227fada96buzbee    MethodMIR2LIR();
10331fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
10341fd3346740dfb7f47be9922312b68a4227fada96buzbee
10351fd3346740dfb7f47be9922312b68a4227fada96buzbee  /* Method is not empty */
10361fd3346740dfb7f47be9922312b68a4227fada96buzbee  if (first_lir_insn_) {
10371fd3346740dfb7f47be9922312b68a4227fada96buzbee    // mark the targets of switch statement case labels
10381fd3346740dfb7f47be9922312b68a4227fada96buzbee    ProcessSwitchTables();
10391fd3346740dfb7f47be9922312b68a4227fada96buzbee
10401fd3346740dfb7f47be9922312b68a4227fada96buzbee    /* Convert LIR into machine code. */
10411fd3346740dfb7f47be9922312b68a4227fada96buzbee    AssembleLIR();
10421fd3346740dfb7f47be9922312b68a4227fada96buzbee
10431fd3346740dfb7f47be9922312b68a4227fada96buzbee    if (cu_->verbose) {
10441fd3346740dfb7f47be9922312b68a4227fada96buzbee      CodegenDump();
10451fd3346740dfb7f47be9922312b68a4227fada96buzbee    }
10461fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
10471fd3346740dfb7f47be9922312b68a4227fada96buzbee}
10481fd3346740dfb7f47be9922312b68a4227fada96buzbee
10491fd3346740dfb7f47be9922312b68a4227fada96buzbeeCompiledMethod* Mir2Lir::GetCompiledMethod() {
10501fd3346740dfb7f47be9922312b68a4227fada96buzbee  // Combine vmap tables - core regs, then fp regs - into vmap_table
105196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  std::vector<uint16_t> raw_vmap_table;
10521fd3346740dfb7f47be9922312b68a4227fada96buzbee  // Core regs may have been inserted out of order - sort first
10531fd3346740dfb7f47be9922312b68a4227fada96buzbee  std::sort(core_vmap_table_.begin(), core_vmap_table_.end());
1054193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  for (size_t i = 0 ; i < core_vmap_table_.size(); ++i) {
10551fd3346740dfb7f47be9922312b68a4227fada96buzbee    // Copy, stripping out the phys register sort key
105696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    raw_vmap_table.push_back(~(-1 << VREG_NUM_WIDTH) & core_vmap_table_[i]);
10571fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
10581fd3346740dfb7f47be9922312b68a4227fada96buzbee  // If we have a frame, push a marker to take place of lr
10591fd3346740dfb7f47be9922312b68a4227fada96buzbee  if (frame_size_ > 0) {
106096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    raw_vmap_table.push_back(INVALID_VREG);
10611fd3346740dfb7f47be9922312b68a4227fada96buzbee  } else {
10621fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK_EQ(__builtin_popcount(core_spill_mask_), 0);
10631fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK_EQ(__builtin_popcount(fp_spill_mask_), 0);
10641fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
10651fd3346740dfb7f47be9922312b68a4227fada96buzbee  // Combine vmap tables - core regs, then fp regs. fp regs already sorted
10661fd3346740dfb7f47be9922312b68a4227fada96buzbee  for (uint32_t i = 0; i < fp_vmap_table_.size(); i++) {
106796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    raw_vmap_table.push_back(fp_vmap_table_[i]);
106896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  }
10691e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  Leb128EncodingVector vmap_encoder;
107096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  // Prefix the encoded data with its size.
10711e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  vmap_encoder.PushBackUnsigned(raw_vmap_table.size());
1072193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier  for (uint16_t cur : raw_vmap_table) {
10731e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko    vmap_encoder.PushBackUnsigned(cur);
10741fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
10751fd3346740dfb7f47be9922312b68a4227fada96buzbee  CompiledMethod* result =
1076193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier      new CompiledMethod(*cu_->compiler_driver, cu_->instruction_set, code_buffer_, frame_size_,
107706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko                         core_spill_mask_, fp_spill_mask_, encoded_mapping_table_,
1078193bad9b9cfd10642043fa2ebbfc68bd5f9ede4bMathieu Chartier                         vmap_encoder.GetData(), native_gc_map_);
10791fd3346740dfb7f47be9922312b68a4227fada96buzbee  return result;
10801fd3346740dfb7f47be9922312b68a4227fada96buzbee}
10811fd3346740dfb7f47be9922312b68a4227fada96buzbee
1082da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusorusize_t Mir2Lir::GetMaxPossibleCompilerTemps() const {
1083da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  // Chose a reasonably small value in order to contain stack growth.
1084da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  // Backends that are smarter about spill region can return larger values.
1085da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  const size_t max_compiler_temps = 10;
1086da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  return max_compiler_temps;
1087da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru}
1088da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru
1089da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusorusize_t Mir2Lir::GetNumBytesForCompilerTempSpillRegion() {
1090da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  // By default assume that the Mir2Lir will need one slot for each temporary.
1091da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  // If the backend can better determine temps that have non-overlapping ranges and
1092da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  // temps that do not need spilled, it can actually provide a small region.
1093da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  return (mir_graph_->GetNumUsedCompilerTemps() * sizeof(uint32_t));
1094da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru}
1095da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru
10961fd3346740dfb7f47be9922312b68a4227fada96buzbeeint Mir2Lir::ComputeFrameSize() {
10971fd3346740dfb7f47be9922312b68a4227fada96buzbee  /* Figure out the frame size */
10981fd3346740dfb7f47be9922312b68a4227fada96buzbee  static const uint32_t kAlignMask = kStackAlignment - 1;
1099da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  uint32_t size = ((num_core_spills_ + num_fp_spills_ +
1100da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru                   1 /* filler word */ + cu_->num_regs + cu_->num_outs)
1101da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru                   * sizeof(uint32_t)) +
1102da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru                   GetNumBytesForCompilerTempSpillRegion();
11031fd3346740dfb7f47be9922312b68a4227fada96buzbee  /* Align and set */
11041fd3346740dfb7f47be9922312b68a4227fada96buzbee  return (size + kAlignMask) & ~(kAlignMask);
11051fd3346740dfb7f47be9922312b68a4227fada96buzbee}
11061fd3346740dfb7f47be9922312b68a4227fada96buzbee
11071fd3346740dfb7f47be9922312b68a4227fada96buzbee/*
11081fd3346740dfb7f47be9922312b68a4227fada96buzbee * Append an LIR instruction to the LIR list maintained by a compilation
11091fd3346740dfb7f47be9922312b68a4227fada96buzbee * unit
11101fd3346740dfb7f47be9922312b68a4227fada96buzbee */
11112ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::AppendLIR(LIR* lir) {
11121fd3346740dfb7f47be9922312b68a4227fada96buzbee  if (first_lir_insn_ == NULL) {
11131fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK(last_lir_insn_ == NULL);
11141fd3346740dfb7f47be9922312b68a4227fada96buzbee    last_lir_insn_ = first_lir_insn_ = lir;
11151fd3346740dfb7f47be9922312b68a4227fada96buzbee    lir->prev = lir->next = NULL;
11161fd3346740dfb7f47be9922312b68a4227fada96buzbee  } else {
11171fd3346740dfb7f47be9922312b68a4227fada96buzbee    last_lir_insn_->next = lir;
11181fd3346740dfb7f47be9922312b68a4227fada96buzbee    lir->prev = last_lir_insn_;
11191fd3346740dfb7f47be9922312b68a4227fada96buzbee    lir->next = NULL;
11201fd3346740dfb7f47be9922312b68a4227fada96buzbee    last_lir_insn_ = lir;
11211fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
11221fd3346740dfb7f47be9922312b68a4227fada96buzbee}
11231fd3346740dfb7f47be9922312b68a4227fada96buzbee
11241fd3346740dfb7f47be9922312b68a4227fada96buzbee/*
11251fd3346740dfb7f47be9922312b68a4227fada96buzbee * Insert an LIR instruction before the current instruction, which cannot be the
11261fd3346740dfb7f47be9922312b68a4227fada96buzbee * first instruction.
11271fd3346740dfb7f47be9922312b68a4227fada96buzbee *
11281fd3346740dfb7f47be9922312b68a4227fada96buzbee * prev_lir <-> new_lir <-> current_lir
11291fd3346740dfb7f47be9922312b68a4227fada96buzbee */
11302ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InsertLIRBefore(LIR* current_lir, LIR* new_lir) {
11311fd3346740dfb7f47be9922312b68a4227fada96buzbee  DCHECK(current_lir->prev != NULL);
11321fd3346740dfb7f47be9922312b68a4227fada96buzbee  LIR *prev_lir = current_lir->prev;
11331fd3346740dfb7f47be9922312b68a4227fada96buzbee
11341fd3346740dfb7f47be9922312b68a4227fada96buzbee  prev_lir->next = new_lir;
11351fd3346740dfb7f47be9922312b68a4227fada96buzbee  new_lir->prev = prev_lir;
11361fd3346740dfb7f47be9922312b68a4227fada96buzbee  new_lir->next = current_lir;
11371fd3346740dfb7f47be9922312b68a4227fada96buzbee  current_lir->prev = new_lir;
11381fd3346740dfb7f47be9922312b68a4227fada96buzbee}
11391fd3346740dfb7f47be9922312b68a4227fada96buzbee
11401fd3346740dfb7f47be9922312b68a4227fada96buzbee/*
11411fd3346740dfb7f47be9922312b68a4227fada96buzbee * Insert an LIR instruction after the current instruction, which cannot be the
11421fd3346740dfb7f47be9922312b68a4227fada96buzbee * first instruction.
11431fd3346740dfb7f47be9922312b68a4227fada96buzbee *
11441fd3346740dfb7f47be9922312b68a4227fada96buzbee * current_lir -> new_lir -> old_next
11451fd3346740dfb7f47be9922312b68a4227fada96buzbee */
11462ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InsertLIRAfter(LIR* current_lir, LIR* new_lir) {
11471fd3346740dfb7f47be9922312b68a4227fada96buzbee  new_lir->prev = current_lir;
11481fd3346740dfb7f47be9922312b68a4227fada96buzbee  new_lir->next = current_lir->next;
11491fd3346740dfb7f47be9922312b68a4227fada96buzbee  current_lir->next = new_lir;
11501fd3346740dfb7f47be9922312b68a4227fada96buzbee  new_lir->next->prev = new_lir;
11511fd3346740dfb7f47be9922312b68a4227fada96buzbee}
11521fd3346740dfb7f47be9922312b68a4227fada96buzbee
11534708dcd68eebf1173aef1097dad8ab13466059aaMark Mendellbool Mir2Lir::IsPowerOfTwo(uint64_t x) {
11544708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  return (x & (x - 1)) == 0;
11554708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell}
11564708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell
11574708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell// Returns the index of the lowest set bit in 'x'.
11584708dcd68eebf1173aef1097dad8ab13466059aaMark Mendellint32_t Mir2Lir::LowestSetBit(uint64_t x) {
11594708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  int bit_posn = 0;
11604708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  while ((x & 0xf) == 0) {
11614708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell    bit_posn += 4;
11624708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell    x >>= 4;
11634708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  }
11644708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  while ((x & 1) == 0) {
11654708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell    bit_posn++;
11664708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell    x >>= 1;
11674708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  }
11684708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  return bit_posn;
11694708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell}
11704708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell
11714708dcd68eebf1173aef1097dad8ab13466059aaMark Mendellbool Mir2Lir::BadOverlap(RegLocation rl_src, RegLocation rl_dest) {
11724708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  DCHECK(rl_src.wide);
11734708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  DCHECK(rl_dest.wide);
11744708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  return (abs(mir_graph_->SRegToVReg(rl_src.s_reg_low) - mir_graph_->SRegToVReg(rl_dest.s_reg_low)) == 1);
11754708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell}
11764708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell
1177766e9295d2c34cd1846d81610c9045b5d5093dddMark MendellLIR *Mir2Lir::OpCmpMemImmBranch(ConditionCode cond, int temp_reg, int base_reg,
1178766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell                                int offset, int check_value, LIR* target) {
1179766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell  // Handle this for architectures that can't compare to memory.
1180766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell  LoadWordDisp(base_reg, offset, temp_reg);
1181766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell  LIR* branch = OpCmpImmBranch(cond, temp_reg, check_value, target);
1182766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell  return branch;
1183766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell}
1184766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell
11857934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom}  // namespace art
1186