1e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/*
2e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Copyright (C) 2011 The Android Open Source Project
3e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee *
4e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Licensed under the Apache License, Version 2.0 (the "License");
5e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * you may not use this file except in compliance with the License.
6e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * You may obtain a copy of the License at
7e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee *
8e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee *      http://www.apache.org/licenses/LICENSE-2.0
9e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee *
10e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Unless required by applicable law or agreed to in writing, software
11e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * distributed under the License is distributed on an "AS IS" BASIS,
12e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * See the License for the specific language governing permissions and
14e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * limitations under the License.
15e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee */
16e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
177940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/compiler_internals.h"
184f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h"
190c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "gc_map.h"
2092cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray#include "gc_map_builder.h"
2196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers#include "mapping_table.h"
228d3a117b374352a1853fae9b7306afeaaa9e3b91Ian Rogers#include "mir_to_lir-inl.h"
235816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko#include "dex/quick/dex_file_method_inliner.h"
245816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko#include "dex/quick/dex_file_to_method_inliner_map.h"
25c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "dex/verification_results.h"
262730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko#include "dex/verified_method.h"
270c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "verifier/dex_gc_map.h"
280c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers#include "verifier/method_verifier.h"
292e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko#include "vmap_table.h"
300c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
31e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbeenamespace art {
32e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
3306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Markonamespace {
3406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko
3506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko/* Dump a mapping table */
3606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Markotemplate <typename It>
3706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Markovoid DumpMappingTable(const char* table_name, const char* descriptor, const char* name,
3806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko                      const Signature& signature, uint32_t size, It first) {
3906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  if (size != 0) {
40107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers    std::string line(StringPrintf("\n  %s %s%s_%s_table[%u] = {", table_name,
4106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko                     descriptor, name, signature.ToString().c_str(), size));
4206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    std::replace(line.begin(), line.end(), ';', '_');
4306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    LOG(INFO) << line;
4406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    for (uint32_t i = 0; i != size; ++i) {
4506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      line = StringPrintf("    {0x%05x, 0x%04x},", first.NativePcOffset(), first.DexPc());
4606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      ++first;
4706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      LOG(INFO) << line;
4806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    }
4906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    LOG(INFO) <<"  };\n\n";
5006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  }
5106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko}
5206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko
5306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko}  // anonymous namespace
5406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko
552ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::IsInexpensiveConstant(RegLocation rl_src) {
564ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  bool res = false;
574ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  if (rl_src.is_const) {
584ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    if (rl_src.wide) {
59ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe      // For wide registers, check whether we're the high partner. In that case we need to switch
60ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe      // to the lower one for the correct value.
61ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe      if (rl_src.high_word) {
62ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe        rl_src.high_word = false;
63ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe        rl_src.s_reg_low--;
64ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe        rl_src.orig_sreg--;
65ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe      }
664ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      if (rl_src.fp) {
67ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe        res = InexpensiveConstantDouble(mir_graph_->ConstantValueWide(rl_src));
684ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      } else {
69ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe        res = InexpensiveConstantLong(mir_graph_->ConstantValueWide(rl_src));
704ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      }
714ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    } else {
724ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      if (rl_src.fp) {
73ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe        res = InexpensiveConstantFloat(mir_graph_->ConstantValue(rl_src));
744ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      } else {
75ade731854d18839823e57fb2d3d67238c5467d15Andreas Gampe        res = InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src));
764ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      }
774ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    }
784ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  }
794ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  return res;
804ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee}
814ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee
822ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::MarkSafepointPC(LIR* inst) {
83b48819db07f9a0992a72173380c24249d7fc648abuzbee  DCHECK(!inst->flags.use_def_invalid);
848dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko  inst->u.m.def_mask = &kEncodeAll;
851fd3346740dfb7f47be9922312b68a4227fada96buzbee  LIR* safepoint_pc = NewLIR0(kPseudoSafepointPC);
868dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko  DCHECK(safepoint_pc->u.m.def_mask->Equals(kEncodeAll));
8702031b185b4653e6c72e21f7a51238b903f6d638buzbee}
8802031b185b4653e6c72e21f7a51238b903f6d638buzbee
893c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampevoid Mir2Lir::MarkSafepointPCAfter(LIR* after) {
903c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe  DCHECK(!after->flags.use_def_invalid);
913c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe  after->u.m.def_mask = &kEncodeAll;
923c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe  // As NewLIR0 uses Append, we need to create the LIR by hand.
933c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe  LIR* safepoint_pc = RawLIR(current_dalvik_offset_, kPseudoSafepointPC);
943c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe  if (after->next == nullptr) {
953c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe    DCHECK_EQ(after, last_lir_insn_);
963c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe    AppendLIR(safepoint_pc);
973c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe  } else {
983c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe    InsertLIRAfter(after, safepoint_pc);
993c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe  }
1003c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe  DCHECK(safepoint_pc->u.m.def_mask->Equals(kEncodeAll));
1013c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe}
1023c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe
103252254b130067cd7a5071865e793966871ae0246buzbee/* Remove a LIR from the list. */
104252254b130067cd7a5071865e793966871ae0246buzbeevoid Mir2Lir::UnlinkLIR(LIR* lir) {
105252254b130067cd7a5071865e793966871ae0246buzbee  if (UNLIKELY(lir == first_lir_insn_)) {
106252254b130067cd7a5071865e793966871ae0246buzbee    first_lir_insn_ = lir->next;
107252254b130067cd7a5071865e793966871ae0246buzbee    if (lir->next != NULL) {
108252254b130067cd7a5071865e793966871ae0246buzbee      lir->next->prev = NULL;
109252254b130067cd7a5071865e793966871ae0246buzbee    } else {
110252254b130067cd7a5071865e793966871ae0246buzbee      DCHECK(lir->next == NULL);
111252254b130067cd7a5071865e793966871ae0246buzbee      DCHECK(lir == last_lir_insn_);
112252254b130067cd7a5071865e793966871ae0246buzbee      last_lir_insn_ = NULL;
113252254b130067cd7a5071865e793966871ae0246buzbee    }
114252254b130067cd7a5071865e793966871ae0246buzbee  } else if (lir == last_lir_insn_) {
115252254b130067cd7a5071865e793966871ae0246buzbee    last_lir_insn_ = lir->prev;
116252254b130067cd7a5071865e793966871ae0246buzbee    lir->prev->next = NULL;
117252254b130067cd7a5071865e793966871ae0246buzbee  } else if ((lir->prev != NULL) && (lir->next != NULL)) {
118252254b130067cd7a5071865e793966871ae0246buzbee    lir->prev->next = lir->next;
119252254b130067cd7a5071865e793966871ae0246buzbee    lir->next->prev = lir->prev;
120252254b130067cd7a5071865e793966871ae0246buzbee  }
121252254b130067cd7a5071865e793966871ae0246buzbee}
122252254b130067cd7a5071865e793966871ae0246buzbee
123cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee/* Convert an instruction to a NOP */
124df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstromvoid Mir2Lir::NopLIR(LIR* lir) {
125fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  lir->flags.is_nop = true;
126252254b130067cd7a5071865e793966871ae0246buzbee  if (!cu_->verbose) {
127252254b130067cd7a5071865e793966871ae0246buzbee    UnlinkLIR(lir);
128252254b130067cd7a5071865e793966871ae0246buzbee  }
129cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee}
130cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee
1312ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::SetMemRefType(LIR* lir, bool is_load, int mem_type) {
1321fd3346740dfb7f47be9922312b68a4227fada96buzbee  DCHECK(GetTargetInstFlags(lir->opcode) & (IS_LOAD | IS_STORE));
133b48819db07f9a0992a72173380c24249d7fc648abuzbee  DCHECK(!lir->flags.use_def_invalid);
1348dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko  // TODO: Avoid the extra Arena allocation!
1358dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko  const ResourceMask** mask_ptr;
1368dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko  ResourceMask mask;
137fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (is_load) {
138b48819db07f9a0992a72173380c24249d7fc648abuzbee    mask_ptr = &lir->u.m.use_mask;
139a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
140b48819db07f9a0992a72173380c24249d7fc648abuzbee    mask_ptr = &lir->u.m.def_mask;
141a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
1428dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko  mask = **mask_ptr;
143a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* Clear out the memref flags */
1448dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko  mask.ClearBits(kEncodeMem);
145a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* ..and then add back the one we need */
146fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  switch (mem_type) {
1478dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    case ResourceMask::kLiteral:
148fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      DCHECK(is_load);
1498dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko      mask.SetBit(ResourceMask::kLiteral);
150a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
1518dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    case ResourceMask::kDalvikReg:
1528dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko      mask.SetBit(ResourceMask::kDalvikReg);
153a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
1548dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    case ResourceMask::kHeapRef:
1558dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko      mask.SetBit(ResourceMask::kHeapRef);
156a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
1578dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    case ResourceMask::kMustNotAlias:
158a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      /* Currently only loads can be marked as kMustNotAlias */
1591fd3346740dfb7f47be9922312b68a4227fada96buzbee      DCHECK(!(GetTargetInstFlags(lir->opcode) & IS_STORE));
1608dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko      mask.SetBit(ResourceMask::kMustNotAlias);
161a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
162a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    default:
163fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      LOG(FATAL) << "Oat: invalid memref kind - " << mem_type;
164a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
1658dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko  *mask_ptr = mask_cache_.GetMask(mask);
16631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
16731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
16831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/*
169b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers * Mark load/store instructions that access Dalvik registers through the stack.
17031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */
1711fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::AnnotateDalvikRegAccess(LIR* lir, int reg_id, bool is_load,
1722ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom                                      bool is64bit) {
1738dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko  DCHECK((is_load ? lir->u.m.use_mask : lir->u.m.def_mask)->Intersection(kEncodeMem).Equals(
1748dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko      kEncodeDalvikReg));
17531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
176a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /*
177fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee   * Store the Dalvik register id in alias_info. Mark the MSB if it is a 64-bit
178a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * access.
179a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   */
180b48819db07f9a0992a72173380c24249d7fc648abuzbee  lir->flags.alias_info = ENCODE_ALIAS_INFO(reg_id, is64bit);
18131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
18231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
18331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/*
1845de3494e4297c0d480409da3fecee39173f1d4e1buzbee * Debugging macros
1855de3494e4297c0d480409da3fecee39173f1d4e1buzbee */
1865de3494e4297c0d480409da3fecee39173f1d4e1buzbee#define DUMP_RESOURCE_MASK(X)
1875de3494e4297c0d480409da3fecee39173f1d4e1buzbee
1885de3494e4297c0d480409da3fecee39173f1d4e1buzbee/* Pretty-print a LIR instruction */
1892ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpLIRInsn(LIR* lir, unsigned char* base_addr) {
190a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int offset = lir->offset;
191a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int dest = lir->operands[0];
1921fd3346740dfb7f47be9922312b68a4227fada96buzbee  const bool dump_nop = (cu_->enable_debug & (1 << kDebugShowNops));
193a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
194a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* Handle pseudo-ops individually, and all regular insns as a group */
195a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  switch (lir->opcode) {
196a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoMethodEntry:
197a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "-------- method entry "
1981fd3346740dfb7f47be9922312b68a4227fada96buzbee                << PrettyMethod(cu_->method_idx, *cu_->dex_file);
199a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
200a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoMethodExit:
201a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "-------- Method_Exit";
202a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
203a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoBarrier:
204a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "-------- BARRIER";
205a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
206a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoEntryBlock:
207a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "-------- entry offset: 0x" << std::hex << dest;
208a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
209a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoDalvikByteCodeBoundary:
2104ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      if (lir->operands[0] == 0) {
2110d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee         // NOTE: only used for debug listings.
2120d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee         lir->operands[0] = WrapPointer(ArenaStrdup("No instruction string"));
2134ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      }
214a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "-------- dalvik offset: 0x" << std::hex
2150b1191cfece83f6f8d4101575a06555a2d13387aBill Buzbee                << lir->dalvik_offset << " @ "
2160b1191cfece83f6f8d4101575a06555a2d13387aBill Buzbee                << reinterpret_cast<char*>(UnwrapPointer(lir->operands[0]));
217a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
218a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoExitBlock:
219a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "-------- exit offset: 0x" << std::hex << dest;
220a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
221a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoPseudoAlign4:
222fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      LOG(INFO) << reinterpret_cast<uintptr_t>(base_addr) + offset << " (0x" << std::hex
223a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                << offset << "): .align4";
224a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
225a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoEHBlockLabel:
226a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(INFO) << "Exception_Handling:";
227a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
228a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoTargetLabel:
229a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoNormalBlockLabel:
230cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee      LOG(INFO) << "L" << reinterpret_cast<void*>(lir) << ":";
231a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
232a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoThrowTarget:
233cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee      LOG(INFO) << "LT" << reinterpret_cast<void*>(lir) << ":";
234a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
235a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoIntrinsicRetry:
236cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee      LOG(INFO) << "IR" << reinterpret_cast<void*>(lir) << ":";
237a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
238a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoSuspendTarget:
239cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee      LOG(INFO) << "LS" << reinterpret_cast<void*>(lir) << ":";
240a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
2418320f3867c02bae9bef6cdab267820cb7b412781buzbee    case kPseudoSafepointPC:
242fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      LOG(INFO) << "LsafepointPC_0x" << std::hex << lir->offset << "_" << lir->dalvik_offset << ":";
2438320f3867c02bae9bef6cdab267820cb7b412781buzbee      break;
244a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee    case kPseudoExportedPC:
245fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      LOG(INFO) << "LexportedPC_0x" << std::hex << lir->offset << "_" << lir->dalvik_offset << ":";
246a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee      break;
247a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kPseudoCaseLabel:
248cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee      LOG(INFO) << "LC" << reinterpret_cast<void*>(lir) << ": Case target 0x"
249a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                << std::hex << lir->operands[0] << "|" << std::dec <<
250a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee        lir->operands[0];
251a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
252a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    default:
253fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      if (lir->flags.is_nop && !dump_nop) {
254a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee        break;
255a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      } else {
2561fd3346740dfb7f47be9922312b68a4227fada96buzbee        std::string op_name(BuildInsnString(GetTargetInstName(lir->opcode),
25702031b185b4653e6c72e21f7a51238b903f6d638buzbee                                               lir, base_addr));
2581fd3346740dfb7f47be9922312b68a4227fada96buzbee        std::string op_operands(BuildInsnString(GetTargetInstFmt(lir->opcode),
25902031b185b4653e6c72e21f7a51238b903f6d638buzbee                                                    lir, base_addr));
260107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers        LOG(INFO) << StringPrintf("%5p: %-9s%s%s",
261107c31e598b649a8bb8d959d6a0377937e63e624Ian Rogers                                  base_addr + offset,
262a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                                  op_name.c_str(), op_operands.c_str(),
263fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                                  lir->flags.is_nop ? "(nop)" : "");
264a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
265a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
266a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
267a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
268b48819db07f9a0992a72173380c24249d7fc648abuzbee  if (lir->u.m.use_mask && (!lir->flags.is_nop || dump_nop)) {
2698dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    DUMP_RESOURCE_MASK(DumpResourceMask(lir, *lir->u.m.use_mask, "use"));
270a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
271b48819db07f9a0992a72173380c24249d7fc648abuzbee  if (lir->u.m.def_mask && (!lir->flags.is_nop || dump_nop)) {
2728dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    DUMP_RESOURCE_MASK(DumpResourceMask(lir, *lir->u.m.def_mask, "def"));
273a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
2745de3494e4297c0d480409da3fecee39173f1d4e1buzbee}
2755de3494e4297c0d480409da3fecee39173f1d4e1buzbee
2762ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpPromotionMap() {
277da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  int num_regs = cu_->num_dalvik_registers + mir_graph_->GetNumUsedCompilerTemps();
278fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  for (int i = 0; i < num_regs; i++) {
2791fd3346740dfb7f47be9922312b68a4227fada96buzbee    PromotionMap v_reg_map = promotion_map_[i];
280a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    std::string buf;
281fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (v_reg_map.fp_location == kLocPhysReg) {
282b5860fb459f1ed71f39d8a87b45bee6727d79fe8buzbee      StringAppendF(&buf, " : s%d", RegStorage::RegNum(v_reg_map.fp_reg));
283a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    }
2849c044ce5f76e9bfa17c4c1979e9f8c99ae100695buzbee
285a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    std::string buf3;
2861fd3346740dfb7f47be9922312b68a4227fada96buzbee    if (i < cu_->num_dalvik_registers) {
287a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      StringAppendF(&buf3, "%02d", i);
2881fd3346740dfb7f47be9922312b68a4227fada96buzbee    } else if (i == mir_graph_->GetMethodSReg()) {
289a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      buf3 = "Method*";
290a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    } else {
2911fd3346740dfb7f47be9922312b68a4227fada96buzbee      StringAppendF(&buf3, "ct%d", i - cu_->num_dalvik_registers);
2925de3494e4297c0d480409da3fecee39173f1d4e1buzbee    }
293a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
294a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    LOG(INFO) << StringPrintf("V[%s] -> %s%d%s", buf3.c_str(),
295fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                              v_reg_map.core_location == kLocPhysReg ?
296fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                              "r" : "SP+", v_reg_map.core_location == kLocPhysReg ?
2971fd3346740dfb7f47be9922312b68a4227fada96buzbee                              v_reg_map.core_reg : SRegOffset(i),
298a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                              buf.c_str());
299a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
3005de3494e4297c0d480409da3fecee39173f1d4e1buzbee}
3015de3494e4297c0d480409da3fecee39173f1d4e1buzbee
3027a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbeevoid Mir2Lir::UpdateLIROffsets() {
3037a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee  // Only used for code listings.
3047a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee  size_t offset = 0;
3057a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee  for (LIR* lir = first_lir_insn_; lir != nullptr; lir = lir->next) {
3067a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee    lir->offset = offset;
3077a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee    if (!lir->flags.is_nop && !IsPseudoLirOp(lir->opcode)) {
3087a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee      offset += GetInsnSize(lir);
3097a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee    } else if (lir->opcode == kPseudoPseudoAlign4) {
3107a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee      offset += (offset & 0x2);
3117a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee    }
3127a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee  }
3137a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee}
3147a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee
3155de3494e4297c0d480409da3fecee39173f1d4e1buzbee/* Dump instructions and constant pool contents */
3162ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::CodegenDump() {
317a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  LOG(INFO) << "Dumping LIR insns for "
3181fd3346740dfb7f47be9922312b68a4227fada96buzbee            << PrettyMethod(cu_->method_idx, *cu_->dex_file);
319fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LIR* lir_insn;
3201fd3346740dfb7f47be9922312b68a4227fada96buzbee  int insns_size = cu_->code_item->insns_size_in_code_units_;
3211fd3346740dfb7f47be9922312b68a4227fada96buzbee
3221fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "Regs (excluding ins) : " << cu_->num_regs;
3231fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "Ins          : " << cu_->num_ins;
3241fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "Outs         : " << cu_->num_outs;
3251fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "CoreSpills       : " << num_core_spills_;
3261fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "FPSpills       : " << num_fp_spills_;
327da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  LOG(INFO) << "CompilerTemps    : " << mir_graph_->GetNumUsedCompilerTemps();
3281fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "Frame size       : " << frame_size_;
3291fd3346740dfb7f47be9922312b68a4227fada96buzbee  LOG(INFO) << "code size is " << total_size_ <<
330fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    " bytes, Dalvik size is " << insns_size * 2;
331a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  LOG(INFO) << "expansion factor: "
3321fd3346740dfb7f47be9922312b68a4227fada96buzbee            << static_cast<float>(total_size_) / static_cast<float>(insns_size * 2);
3331fd3346740dfb7f47be9922312b68a4227fada96buzbee  DumpPromotionMap();
3347a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee  UpdateLIROffsets();
3351fd3346740dfb7f47be9922312b68a4227fada96buzbee  for (lir_insn = first_lir_insn_; lir_insn != NULL; lir_insn = lir_insn->next) {
3361fd3346740dfb7f47be9922312b68a4227fada96buzbee    DumpLIRInsn(lir_insn, 0);
337a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
3381fd3346740dfb7f47be9922312b68a4227fada96buzbee  for (lir_insn = literal_list_; lir_insn != NULL; lir_insn = lir_insn->next) {
339fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    LOG(INFO) << StringPrintf("%x (%04x): .word (%#x)", lir_insn->offset, lir_insn->offset,
340fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                              lir_insn->operands[0]);
341a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
342a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
343a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  const DexFile::MethodId& method_id =
3441fd3346740dfb7f47be9922312b68a4227fada96buzbee      cu_->dex_file->GetMethodId(cu_->method_idx);
345d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers  const Signature signature = cu_->dex_file->GetMethodSignature(method_id);
346d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers  const char* name = cu_->dex_file->GetMethodName(method_id);
347d91d6d6a80748f277fd938a412211e5af28913b1Ian Rogers  const char* descriptor(cu_->dex_file->GetMethodDeclaringClassDescriptor(method_id));
348a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
349a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee  // Dump mapping tables
35006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  if (!encoded_mapping_table_.empty()) {
35106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    MappingTable table(&encoded_mapping_table_[0]);
35206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    DumpMappingTable("PC2Dex_MappingTable", descriptor, name, signature,
35306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko                     table.PcToDexSize(), table.PcToDexBegin());
35406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    DumpMappingTable("Dex2PC_MappingTable", descriptor, name, signature,
35506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko                     table.DexToPcSize(), table.DexToPcBegin());
35606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  }
3575de3494e4297c0d480409da3fecee39173f1d4e1buzbee}
3585de3494e4297c0d480409da3fecee39173f1d4e1buzbee
35931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/*
36031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Search the existing constants in the literal pool for an exact or close match
36131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * within specified delta (greater or equal to 0).
36231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */
3632ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::ScanLiteralPool(LIR* data_target, int value, unsigned int delta) {
364fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  while (data_target) {
365fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if ((static_cast<unsigned>(value - data_target->operands[0])) <= delta)
366fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      return data_target;
367fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    data_target = data_target->next;
368a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
369a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return NULL;
37031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
37131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
37231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* Search the existing constants in the literal pool for an exact wide match */
3732ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::ScanLiteralPoolWide(LIR* data_target, int val_lo, int val_hi) {
374fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  bool lo_match = false;
375fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  LIR* lo_target = NULL;
376fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  while (data_target) {
377fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (lo_match && (data_target->operands[0] == val_hi)) {
3784ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      // Record high word in case we need to expand this later.
3794ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      lo_target->operands[1] = val_hi;
380fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      return lo_target;
38131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee    }
382fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    lo_match = false;
383fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (data_target->operands[0] == val_lo) {
384fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      lo_match = true;
385fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      lo_target = data_target;
386a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    }
387fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    data_target = data_target->next;
388a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
389a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return NULL;
39031a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
39131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
392a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko/* Search the existing constants in the literal pool for an exact method match */
393a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir MarkoLIR* Mir2Lir::ScanLiteralPoolMethod(LIR* data_target, const MethodReference& method) {
394a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko  while (data_target) {
395a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko    if (static_cast<uint32_t>(data_target->operands[0]) == method.dex_method_index &&
396a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko        UnwrapPointer(data_target->operands[1]) == method.dex_file) {
397a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko      return data_target;
398a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko    }
399a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko    data_target = data_target->next;
400a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko  }
401a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko  return nullptr;
402a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko}
403a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko
40431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/*
40531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * The following are building blocks to insert constants into the pool or
40631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * instruction streams.
40731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */
40831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
4094ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee/* Add a 32-bit constant to the constant pool */
4102ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::AddWordData(LIR* *constant_list_p, int value) {
411a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* Add the constant to the literal pool */
412fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (constant_list_p) {
41383cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko    LIR* new_value = static_cast<LIR*>(arena_->Alloc(sizeof(LIR), kArenaAllocData));
414fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    new_value->operands[0] = value;
415fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    new_value->next = *constant_list_p;
416fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    *constant_list_p = new_value;
417b48819db07f9a0992a72173380c24249d7fc648abuzbee    estimated_native_code_size_ += sizeof(value);
418fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    return new_value;
419a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
420a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return NULL;
42131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
42231a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
42331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/* Add a 64-bit constant to the constant pool or mixed with code */
4242ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* Mir2Lir::AddWideData(LIR* *constant_list_p, int val_lo, int val_hi) {
4251fd3346740dfb7f47be9922312b68a4227fada96buzbee  AddWordData(constant_list_p, val_hi);
4261fd3346740dfb7f47be9922312b68a4227fada96buzbee  return AddWordData(constant_list_p, val_lo);
42731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
42831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
4292da882315a61072664f7ce3c212307342e907207Andreas Gampestatic void Push32(std::vector<uint8_t>&buf, int data) {
430df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom  buf.push_back(data & 0xff);
431df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom  buf.push_back((data >> 8) & 0xff);
432df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom  buf.push_back((data >> 16) & 0xff);
433df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom  buf.push_back((data >> 24) & 0xff);
434e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
435e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
4362da882315a61072664f7ce3c212307342e907207Andreas Gampe// Push 8 bytes on 64-bit target systems; 4 on 32-bit target systems.
4372da882315a61072664f7ce3c212307342e907207Andreas Gampestatic void PushPointer(std::vector<uint8_t>&buf, const void* pointer, bool target64) {
4382da882315a61072664f7ce3c212307342e907207Andreas Gampe  uint64_t data = reinterpret_cast<uintptr_t>(pointer);
4392da882315a61072664f7ce3c212307342e907207Andreas Gampe  if (target64) {
4402da882315a61072664f7ce3c212307342e907207Andreas Gampe    Push32(buf, data & 0xFFFFFFFF);
4412da882315a61072664f7ce3c212307342e907207Andreas Gampe    Push32(buf, (data >> 32) & 0xFFFFFFFF);
4420d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  } else {
4432da882315a61072664f7ce3c212307342e907207Andreas Gampe    Push32(buf, static_cast<uint32_t>(data));
4440d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  }
4450d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee}
4460d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee
447aad94383fc41e8f8770f0b2144f766a2ffa772e7buzbeestatic void AlignBuffer(std::vector<uint8_t>&buf, size_t offset) {
448a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  while (buf.size() < offset) {
449a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    buf.push_back(0);
450a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
451e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
452e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
453e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the literal pool to the output stream */
4542ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallLiteralPools() {
4551fd3346740dfb7f47be9922312b68a4227fada96buzbee  AlignBuffer(code_buffer_, data_offset_);
4561fd3346740dfb7f47be9922312b68a4227fada96buzbee  LIR* data_lir = literal_list_;
457fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  while (data_lir != NULL) {
4582da882315a61072664f7ce3c212307342e907207Andreas Gampe    Push32(code_buffer_, data_lir->operands[0]);
459fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    data_lir = NEXT_LIR(data_lir);
460a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
461a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  // Push code and method literals, record offsets for the compiler to patch.
4621fd3346740dfb7f47be9922312b68a4227fada96buzbee  data_lir = code_literal_list_;
463fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  while (data_lir != NULL) {
46449161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao    uint32_t target_method_idx = data_lir->operands[0];
46549161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao    const DexFile* target_dex_file =
46649161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao        reinterpret_cast<const DexFile*>(UnwrapPointer(data_lir->operands[1]));
4671fd3346740dfb7f47be9922312b68a4227fada96buzbee    cu_->compiler_driver->AddCodePatch(cu_->dex_file,
4688b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                       cu_->class_def_idx,
4698b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                       cu_->method_idx,
4708b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                       cu_->invoke_type,
47149161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao                                       target_method_idx,
47249161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao                                       target_dex_file,
47349161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao                                       static_cast<InvokeType>(data_lir->operands[2]),
4748b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                       code_buffer_.size());
47549161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao    const DexFile::MethodId& target_method_id = target_dex_file->GetMethodId(target_method_idx);
4760d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    // unique value based on target to ensure code deduplication works
47749161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao    PushPointer(code_buffer_, &target_method_id, cu_->target64);
478fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    data_lir = NEXT_LIR(data_lir);
479137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers  }
4801fd3346740dfb7f47be9922312b68a4227fada96buzbee  data_lir = method_literal_list_;
481fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  while (data_lir != NULL) {
48249161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao    uint32_t target_method_idx = data_lir->operands[0];
48349161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao    const DexFile* target_dex_file =
48449161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao        reinterpret_cast<const DexFile*>(UnwrapPointer(data_lir->operands[1]));
4851fd3346740dfb7f47be9922312b68a4227fada96buzbee    cu_->compiler_driver->AddMethodPatch(cu_->dex_file,
4868b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                         cu_->class_def_idx,
4878b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                         cu_->method_idx,
4888b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                         cu_->invoke_type,
48949161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao                                         target_method_idx,
49049161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao                                         target_dex_file,
49149161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao                                         static_cast<InvokeType>(data_lir->operands[2]),
4928b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers                                         code_buffer_.size());
49349161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao    const DexFile::MethodId& target_method_id = target_dex_file->GetMethodId(target_method_idx);
4940d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    // unique value based on target to ensure code deduplication works
49549161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao    PushPointer(code_buffer_, &target_method_id, cu_->target64);
496fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    data_lir = NEXT_LIR(data_lir);
497a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
498be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi  // Push class literals.
499be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi  data_lir = class_literal_list_;
500be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi  while (data_lir != NULL) {
50149161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao    uint32_t target_method_idx = data_lir->operands[0];
502be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi    cu_->compiler_driver->AddClassPatch(cu_->dex_file,
503be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi                                        cu_->class_def_idx,
504be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi                                        cu_->method_idx,
50549161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao                                        target_method_idx,
506be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi                                        code_buffer_.size());
50749161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao    const DexFile::TypeId& target_method_id = cu_->dex_file->GetTypeId(target_method_idx);
508be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi    // unique value based on target to ensure code deduplication works
50949161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao    PushPointer(code_buffer_, &target_method_id, cu_->target64);
510be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi    data_lir = NEXT_LIR(data_lir);
511be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi  }
512807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier  // Push the string literals.
513807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier  data_lir = string_literal_list_;
514807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier  while (data_lir != nullptr) {
515807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier    uint32_t string_idx = data_lir->operands[0];
516807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier    cu_->compiler_driver->AddStringPatch(cu_->dex_file,
517807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier                                         cu_->class_def_idx,
518807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier                                         cu_->method_idx,
519807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier                                         string_idx,
520807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier                                         code_buffer_.size());
521807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier    const auto& target_string_id = cu_->dex_file->GetStringId(string_idx);
522807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier    // unique value based on target to ensure code deduplication works
523807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier    PushPointer(code_buffer_, &target_string_id, cu_->target64);
524807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier    data_lir = NEXT_LIR(data_lir);
525807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier  }
526e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
527e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
528e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the switch tables to the output stream */
5292ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallSwitchTables() {
530862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_);
531a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  while (true) {
532862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    Mir2Lir::SwitchTable* tab_rec = iterator.Next();
533fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec == NULL) break;
5341fd3346740dfb7f47be9922312b68a4227fada96buzbee    AlignBuffer(code_buffer_, tab_rec->offset);
535a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    /*
536a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     * For Arm, our reference point is the address of the bx
537a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     * instruction that does the launch, so we have to subtract
538a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     * the auto pc-advance.  For other targets the reference point
539a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     * is a label, so we can use the offset as-is.
540a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     */
541fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    int bx_offset = INVALID_OFFSET;
5421fd3346740dfb7f47be9922312b68a4227fada96buzbee    switch (cu_->instruction_set) {
543b046e16d8b8da318d6055f9308950131f1255e08buzbee      case kThumb2:
544b48819db07f9a0992a72173380c24249d7fc648abuzbee        DCHECK(tab_rec->anchor->flags.fixup != kFixupNone);
545fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        bx_offset = tab_rec->anchor->offset + 4;
546b046e16d8b8da318d6055f9308950131f1255e08buzbee        break;
547b046e16d8b8da318d6055f9308950131f1255e08buzbee      case kX86:
5486a58cb16d803c9a7b3a75ccac8be19dd9d4e520dDmitry Petrochenko      case kX86_64:
549fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        bx_offset = 0;
550b046e16d8b8da318d6055f9308950131f1255e08buzbee        break;
551e45fb9e7976c8462b94a58ad60b006b0eacec49fMatteo Franchin      case kArm64:
552b046e16d8b8da318d6055f9308950131f1255e08buzbee      case kMips:
553fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        bx_offset = tab_rec->anchor->offset;
554b046e16d8b8da318d6055f9308950131f1255e08buzbee        break;
5551fd3346740dfb7f47be9922312b68a4227fada96buzbee      default: LOG(FATAL) << "Unexpected instruction set: " << cu_->instruction_set;
556b046e16d8b8da318d6055f9308950131f1255e08buzbee    }
5571fd3346740dfb7f47be9922312b68a4227fada96buzbee    if (cu_->verbose) {
558fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      LOG(INFO) << "Switch table for offset 0x" << std::hex << bx_offset;
559a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    }
560fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) {
5610d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee      const int32_t* keys = reinterpret_cast<const int32_t*>(&(tab_rec->table[2]));
562fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      for (int elems = 0; elems < tab_rec->table[1]; elems++) {
563fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        int disp = tab_rec->targets[elems]->offset - bx_offset;
5641fd3346740dfb7f47be9922312b68a4227fada96buzbee        if (cu_->verbose) {
565a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee          LOG(INFO) << "  Case[" << elems << "] key: 0x"
566a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                    << std::hex << keys[elems] << ", disp: 0x"
567a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                    << std::hex << disp;
568e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee        }
5692da882315a61072664f7ce3c212307342e907207Andreas Gampe        Push32(code_buffer_, keys[elems]);
5702da882315a61072664f7ce3c212307342e907207Andreas Gampe        Push32(code_buffer_,
571fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee          tab_rec->targets[elems]->offset - bx_offset);
572a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
573a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    } else {
574fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      DCHECK_EQ(static_cast<int>(tab_rec->table[0]),
575a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                static_cast<int>(Instruction::kPackedSwitchSignature));
576fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      for (int elems = 0; elems < tab_rec->table[1]; elems++) {
577fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        int disp = tab_rec->targets[elems]->offset - bx_offset;
5781fd3346740dfb7f47be9922312b68a4227fada96buzbee        if (cu_->verbose) {
579a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee          LOG(INFO) << "  Case[" << elems << "] disp: 0x"
580a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                    << std::hex << disp;
581e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee        }
5822da882315a61072664f7ce3c212307342e907207Andreas Gampe        Push32(code_buffer_, tab_rec->targets[elems]->offset - bx_offset);
583a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
584e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee    }
585a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
586e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
587e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
588e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Write the fill array dta to the output stream */
5892ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InstallFillArrayData() {
590862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<FillArrayData*>::Iterator iterator(&fill_array_data_);
591a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  while (true) {
592862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    Mir2Lir::FillArrayData *tab_rec = iterator.Next();
593fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec == NULL) break;
5941fd3346740dfb7f47be9922312b68a4227fada96buzbee    AlignBuffer(code_buffer_, tab_rec->offset);
595fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    for (int i = 0; i < (tab_rec->size + 1) / 2; i++) {
596df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom      code_buffer_.push_back(tab_rec->table[i] & 0xFF);
597df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom      code_buffer_.push_back((tab_rec->table[i] >> 8) & 0xFF);
598e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee    }
599a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
600e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
601e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
6020d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeestatic int AssignLiteralOffsetCommon(LIR* lir, CodeOffset offset) {
60302c8cc6d1312a2b55533f02f6369dc7c94672f90Brian Carlstrom  for (; lir != NULL; lir = lir->next) {
604a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    lir->offset = offset;
605a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    offset += 4;
606a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
607a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return offset;
608e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
609e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
610ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogersstatic int AssignLiteralPointerOffsetCommon(LIR* lir, CodeOffset offset,
611ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers                                            unsigned int element_size) {
6120d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  // Align to natural pointer size.
613660188264dee3c8f3510e2e24c11816c6b60f197Andreas Gampe  offset = RoundUp(offset, element_size);
6140d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  for (; lir != NULL; lir = lir->next) {
6150d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    lir->offset = offset;
6160d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    offset += element_size;
6170d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  }
6180d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  return offset;
6190d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee}
6200d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee
6216459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee// Make sure we have a code address for every declared catch entry
6222ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::VerifyCatchEntries() {
62306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  MappingTable table(&encoded_mapping_table_[0]);
62406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  std::vector<uint32_t> dex_pcs;
62506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  dex_pcs.reserve(table.DexToPcSize());
62606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  for (auto it = table.DexToPcBegin(), end = table.DexToPcEnd(); it != end; ++it) {
62706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    dex_pcs.push_back(it.DexPc());
62806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  }
62906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  // Sort dex_pcs, so that we can quickly check it against the ordered mir_graph_->catches_.
63006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  std::sort(dex_pcs.begin(), dex_pcs.end());
63106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko
6326459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee  bool success = true;
63306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  auto it = dex_pcs.begin(), end = dex_pcs.end();
63406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  for (uint32_t dex_pc : mir_graph_->catches_) {
63506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    while (it != end && *it < dex_pc) {
63606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      LOG(INFO) << "Unexpected catch entry @ dex pc 0x" << std::hex << *it;
63706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      ++it;
6386459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee      success = false;
6396459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee    }
64006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    if (it == end || *it > dex_pc) {
64106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      LOG(INFO) << "Missing native PC for catch entry @ 0x" << std::hex << dex_pc;
6426459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee      success = false;
64306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    } else {
64406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      ++it;
6456459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee    }
6466459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee  }
6476459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee  if (!success) {
6481fd3346740dfb7f47be9922312b68a4227fada96buzbee    LOG(INFO) << "Bad dex2pcMapping table in " << PrettyMethod(cu_->method_idx, *cu_->dex_file);
6491fd3346740dfb7f47be9922312b68a4227fada96buzbee    LOG(INFO) << "Entries @ decode: " << mir_graph_->catches_.size() << ", Entries in table: "
65006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko              << table.DexToPcSize();
6516459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee  }
6526459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee  return success;
6536459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee}
6546459e7cb35ca83ffc2f266dddeb83673bc07ecd4buzbee
655311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
6562ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::CreateMappingTables() {
6571e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t pc2dex_data_size = 0u;
6581e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t pc2dex_entries = 0u;
6591e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t pc2dex_offset = 0u;
6601e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t pc2dex_dalvik_offset = 0u;
6611e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t dex2pc_data_size = 0u;
6621e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t dex2pc_entries = 0u;
6631e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t dex2pc_offset = 0u;
6641e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t dex2pc_dalvik_offset = 0u;
6651fd3346740dfb7f47be9922312b68a4227fada96buzbee  for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) {
666fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) {
6671e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      pc2dex_entries += 1;
6681e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      DCHECK(pc2dex_offset <= tgt_lir->offset);
6691e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      pc2dex_data_size += UnsignedLeb128Size(tgt_lir->offset - pc2dex_offset);
6701e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      pc2dex_data_size += SignedLeb128Size(static_cast<int32_t>(tgt_lir->dalvik_offset) -
6711e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko                                           static_cast<int32_t>(pc2dex_dalvik_offset));
6721e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      pc2dex_offset = tgt_lir->offset;
6731e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      pc2dex_dalvik_offset = tgt_lir->dalvik_offset;
674a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee    }
675fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) {
6761e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      dex2pc_entries += 1;
6771e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      DCHECK(dex2pc_offset <= tgt_lir->offset);
6781e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      dex2pc_data_size += UnsignedLeb128Size(tgt_lir->offset - dex2pc_offset);
6791e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      dex2pc_data_size += SignedLeb128Size(static_cast<int32_t>(tgt_lir->dalvik_offset) -
6801e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko                                           static_cast<int32_t>(dex2pc_dalvik_offset));
6811e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      dex2pc_offset = tgt_lir->offset;
6821e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko      dex2pc_dalvik_offset = tgt_lir->dalvik_offset;
683e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee    }
684a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
6851e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko
6861e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t total_entries = pc2dex_entries + dex2pc_entries;
6871e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t hdr_data_size = UnsignedLeb128Size(total_entries) + UnsignedLeb128Size(pc2dex_entries);
6881e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t data_size = hdr_data_size + pc2dex_data_size + dex2pc_data_size;
68906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  encoded_mapping_table_.resize(data_size);
69006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  uint8_t* write_pos = &encoded_mapping_table_[0];
69106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  write_pos = EncodeUnsignedLeb128(write_pos, total_entries);
69206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  write_pos = EncodeUnsignedLeb128(write_pos, pc2dex_entries);
69306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  DCHECK_EQ(static_cast<size_t>(write_pos - &encoded_mapping_table_[0]), hdr_data_size);
69406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  uint8_t* write_pos2 = write_pos + pc2dex_data_size;
6951e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko
6961e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  pc2dex_offset = 0u;
6971e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  pc2dex_dalvik_offset = 0u;
69806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  dex2pc_offset = 0u;
69906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  dex2pc_dalvik_offset = 0u;
70006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) {
70106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) {
70206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      DCHECK(pc2dex_offset <= tgt_lir->offset);
70306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      write_pos = EncodeUnsignedLeb128(write_pos, tgt_lir->offset - pc2dex_offset);
70406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      write_pos = EncodeSignedLeb128(write_pos, static_cast<int32_t>(tgt_lir->dalvik_offset) -
70506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko                                     static_cast<int32_t>(pc2dex_dalvik_offset));
70606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      pc2dex_offset = tgt_lir->offset;
70706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      pc2dex_dalvik_offset = tgt_lir->dalvik_offset;
70806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    }
70906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) {
71006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      DCHECK(dex2pc_offset <= tgt_lir->offset);
71106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      write_pos2 = EncodeUnsignedLeb128(write_pos2, tgt_lir->offset - dex2pc_offset);
71206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      write_pos2 = EncodeSignedLeb128(write_pos2, static_cast<int32_t>(tgt_lir->dalvik_offset) -
71306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko                                      static_cast<int32_t>(dex2pc_dalvik_offset));
71406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      dex2pc_offset = tgt_lir->offset;
71506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      dex2pc_dalvik_offset = tgt_lir->dalvik_offset;
71606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    }
7171e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  }
71806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  DCHECK_EQ(static_cast<size_t>(write_pos - &encoded_mapping_table_[0]),
71906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko            hdr_data_size + pc2dex_data_size);
72006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  DCHECK_EQ(static_cast<size_t>(write_pos2 - &encoded_mapping_table_[0]), data_size);
7211e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko
72296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  if (kIsDebugBuild) {
72306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    CHECK(VerifyCatchEntries());
72406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko
72596faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    // Verify the encoded table holds the expected data.
72606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    MappingTable table(&encoded_mapping_table_[0]);
72796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    CHECK_EQ(table.TotalSize(), total_entries);
72896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    CHECK_EQ(table.PcToDexSize(), pc2dex_entries);
7291e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko    auto it = table.PcToDexBegin();
7301e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko    auto it2 = table.DexToPcBegin();
73106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) {
73206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) {
73306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko        CHECK_EQ(tgt_lir->offset, it.NativePcOffset());
73406606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko        CHECK_EQ(tgt_lir->dalvik_offset, it.DexPc());
73506606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko        ++it;
73606606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      }
73706606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) {
73806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko        CHECK_EQ(tgt_lir->offset, it2.NativePcOffset());
73906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko        CHECK_EQ(tgt_lir->dalvik_offset, it2.DexPc());
74006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko        ++it2;
74106606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko      }
74296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers    }
74306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    CHECK(it == table.PcToDexEnd());
7441e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko    CHECK(it2 == table.DexToPcEnd());
745311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  }
746e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
747e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
7481fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::CreateNativeGcMap() {
74906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  DCHECK(!encoded_mapping_table_.empty());
75006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  MappingTable mapping_table(&encoded_mapping_table_[0]);
7510c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  uint32_t max_native_offset = 0;
75206606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  for (auto it = mapping_table.PcToDexBegin(), end = mapping_table.PcToDexEnd(); it != end; ++it) {
75306606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    uint32_t native_offset = it.NativePcOffset();
7540c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    if (native_offset > max_native_offset) {
7550c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers      max_native_offset = native_offset;
7560c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    }
7570c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
75851c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom  MethodReference method_ref(cu_->dex_file, cu_->method_idx);
7592730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko  const std::vector<uint8_t>& gc_map_raw =
7602730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko      mir_graph_->GetCurrentDexCompilationUnit()->GetVerifiedMethod()->GetDexGcMap();
7612730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko  verifier::DexPcToReferenceMap dex_gc_map(&(gc_map_raw)[0]);
7622730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko  DCHECK_EQ(gc_map_raw.size(), dex_gc_map.RawSize());
7630c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  // Compute native offset to references size.
76492cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray  GcMapBuilder native_gc_map_builder(&native_gc_map_,
76592cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray                                     mapping_table.PcToDexSize(),
76692cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray                                     max_native_offset, dex_gc_map.RegWidth());
7670c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
76806606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko  for (auto it = mapping_table.PcToDexBegin(), end = mapping_table.PcToDexEnd(); it != end; ++it) {
76906606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    uint32_t native_offset = it.NativePcOffset();
77006606b9c4a1c00154ed15f719ad8ea994e54ee8eVladimir Marko    uint32_t dex_pc = it.DexPc();
7710c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers    const uint8_t* references = dex_gc_map.FindBitMap(dex_pc, false);
772f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison    CHECK(references != NULL) << "Missing ref for dex pc 0x" << std::hex << dex_pc <<
773f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison        ": " << PrettyMethod(cu_->method_idx, *cu_->dex_file);
774a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee    native_gc_map_builder.AddEntry(native_offset, references);
7750c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers  }
77625fda92083d5b93b38cc1f6b12ac6a44d992d6a4Mathieu Chartier
77725fda92083d5b93b38cc1f6b12ac6a44d992d6a4Mathieu Chartier  // Maybe not necessary, but this could help prevent errors where we access the verified method
77825fda92083d5b93b38cc1f6b12ac6a44d992d6a4Mathieu Chartier  // after it has been deleted.
77925fda92083d5b93b38cc1f6b12ac6a44d992d6a4Mathieu Chartier  mir_graph_->GetCurrentDexCompilationUnit()->ClearVerifiedMethod();
7800c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers}
7810c7abda482f53db3d153c073d1c7a145f84e0626Ian Rogers
782e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Determine the offset of each literal field */
7830d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignLiteralOffset(CodeOffset offset) {
7841fd3346740dfb7f47be9922312b68a4227fada96buzbee  offset = AssignLiteralOffsetCommon(literal_list_, offset);
785ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers  unsigned int ptr_size = GetInstructionSetPointerSize(cu_->instruction_set);
786ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers  offset = AssignLiteralPointerOffsetCommon(code_literal_list_, offset, ptr_size);
787ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers  offset = AssignLiteralPointerOffsetCommon(method_literal_list_, offset, ptr_size);
788ff093b31d75658c3404f9b51ee45760f346f06d9Ian Rogers  offset = AssignLiteralPointerOffsetCommon(class_literal_list_, offset, ptr_size);
789807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier  offset = AssignLiteralPointerOffsetCommon(string_literal_list_, offset, ptr_size);
790a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return offset;
791e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
792e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
7930d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignSwitchTablesOffset(CodeOffset offset) {
794862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_);
795a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  while (true) {
7960d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee    Mir2Lir::SwitchTable* tab_rec = iterator.Next();
797fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec == NULL) break;
798fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    tab_rec->offset = offset;
799fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) {
800fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      offset += tab_rec->table[1] * (sizeof(int) * 2);
801a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    } else {
802fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      DCHECK_EQ(static_cast<int>(tab_rec->table[0]),
803a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                static_cast<int>(Instruction::kPackedSwitchSignature));
804fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      offset += tab_rec->table[1] * sizeof(int);
805e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee    }
806a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
807a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return offset;
808e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
809e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
8100d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeint Mir2Lir::AssignFillArrayDataOffset(CodeOffset offset) {
811862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<FillArrayData*>::Iterator iterator(&fill_array_data_);
812a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  while (true) {
813862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    Mir2Lir::FillArrayData *tab_rec = iterator.Next();
814fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec == NULL) break;
815fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    tab_rec->offset = offset;
816fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    offset += tab_rec->size;
817a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    // word align
818660188264dee3c8f3510e2e24c11816c6b60f197Andreas Gampe    offset = RoundUp(offset, 4);
819a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    }
820a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return offset;
821e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
822e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
82331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee/*
82431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee * Insert a kPseudoCaseLabel at the beginning of the Dalvik
825b48819db07f9a0992a72173380c24249d7fc648abuzbee * offset vaddr if pretty-printing, otherise use the standard block
826b48819db07f9a0992a72173380c24249d7fc648abuzbee * label.  The selected label will be used to fix up the case
827252254b130067cd7a5071865e793966871ae0246buzbee * branch table during the assembly phase.  All resource flags
828252254b130067cd7a5071865e793966871ae0246buzbee * are set to prevent code motion.  KeyVal is just there for debugging.
82931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee */
8300d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeLIR* Mir2Lir::InsertCaseLabel(DexOffset vaddr, int keyVal) {
831252254b130067cd7a5071865e793966871ae0246buzbee  LIR* boundary_lir = &block_label_list_[mir_graph_->FindBlock(vaddr)->id];
832b48819db07f9a0992a72173380c24249d7fc648abuzbee  LIR* res = boundary_lir;
833b48819db07f9a0992a72173380c24249d7fc648abuzbee  if (cu_->verbose) {
834b48819db07f9a0992a72173380c24249d7fc648abuzbee    // Only pay the expense if we're pretty-printing.
83583cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko    LIR* new_label = static_cast<LIR*>(arena_->Alloc(sizeof(LIR), kArenaAllocLIR));
836b48819db07f9a0992a72173380c24249d7fc648abuzbee    new_label->dalvik_offset = vaddr;
837b48819db07f9a0992a72173380c24249d7fc648abuzbee    new_label->opcode = kPseudoCaseLabel;
838b48819db07f9a0992a72173380c24249d7fc648abuzbee    new_label->operands[0] = keyVal;
839b48819db07f9a0992a72173380c24249d7fc648abuzbee    new_label->flags.fixup = kFixupLabel;
840b48819db07f9a0992a72173380c24249d7fc648abuzbee    DCHECK(!new_label->flags.use_def_invalid);
8418dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    new_label->u.m.def_mask = &kEncodeAll;
842b48819db07f9a0992a72173380c24249d7fc648abuzbee    InsertLIRAfter(boundary_lir, new_label);
843b48819db07f9a0992a72173380c24249d7fc648abuzbee    res = new_label;
844b48819db07f9a0992a72173380c24249d7fc648abuzbee  }
845b48819db07f9a0992a72173380c24249d7fc648abuzbee  return res;
84631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
84731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
8480d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkPackedCaseLabels(Mir2Lir::SwitchTable* tab_rec) {
849fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  const uint16_t* table = tab_rec->table;
8500d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  DexOffset base_vaddr = tab_rec->vaddr;
8510d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  const int32_t *targets = reinterpret_cast<const int32_t*>(&table[4]);
852a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int entries = table[1];
853fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int low_key = s4FromSwitchData(&table[2]);
854a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  for (int i = 0; i < entries; i++) {
8551fd3346740dfb7f47be9922312b68a4227fada96buzbee    tab_rec->targets[i] = InsertCaseLabel(base_vaddr + targets[i], i + low_key);
856a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
85731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
85831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
8590d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkSparseCaseLabels(Mir2Lir::SwitchTable* tab_rec) {
860fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  const uint16_t* table = tab_rec->table;
8610d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  DexOffset base_vaddr = tab_rec->vaddr;
862a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int entries = table[1];
8630d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  const int32_t* keys = reinterpret_cast<const int32_t*>(&table[2]);
8640d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  const int32_t* targets = &keys[entries];
865a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  for (int i = 0; i < entries; i++) {
8661fd3346740dfb7f47be9922312b68a4227fada96buzbee    tab_rec->targets[i] = InsertCaseLabel(base_vaddr + targets[i], keys[i]);
867a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
86831a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
86931a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
8702ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::ProcessSwitchTables() {
871862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_);
872a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  while (true) {
873862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    Mir2Lir::SwitchTable *tab_rec = iterator.Next();
874fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec == NULL) break;
875fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    if (tab_rec->table[0] == Instruction::kPackedSwitchSignature) {
8761fd3346740dfb7f47be9922312b68a4227fada96buzbee      MarkPackedCaseLabels(tab_rec);
877fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    } else if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) {
8781fd3346740dfb7f47be9922312b68a4227fada96buzbee      MarkSparseCaseLabels(tab_rec);
879a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    } else {
880a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      LOG(FATAL) << "Invalid switch table";
88131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee    }
882a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
88331a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
88431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
8852ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpSparseSwitchTable(const uint16_t* table) {
886a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /*
887a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * Sparse switch data format:
888a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  ushort ident = 0x0200   magic value
889a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  ushort size       number of entries in the table; > 0
890a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  int keys[size]      keys, sorted low-to-high; 32-bit aligned
891a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  int targets[size]     branch targets, relative to switch opcode
892a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *
893a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * Total size is (2+size*4) 16-bit code units.
894a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   */
895eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee  uint16_t ident = table[0];
896a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int entries = table[1];
8970d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  const int32_t* keys = reinterpret_cast<const int32_t*>(&table[2]);
8980d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  const int32_t* targets = &keys[entries];
899a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  LOG(INFO) <<  "Sparse switch table - ident:0x" << std::hex << ident
900a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee            << ", entries: " << std::dec << entries;
901a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  for (int i = 0; i < entries; i++) {
902a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    LOG(INFO) << "  Key[" << keys[i] << "] -> 0x" << std::hex << targets[i];
903a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
90431a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
90531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee
9062ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::DumpPackedSwitchTable(const uint16_t* table) {
907a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /*
908a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * Packed switch data format:
909a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  ushort ident = 0x0100   magic value
910a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  ushort size       number of entries in the table
911a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  int first_key       first (and lowest) switch case value
912a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *  int targets[size]     branch targets, relative to switch opcode
913a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   *
914a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   * Total size is (4+size*2) 16-bit code units.
915a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee   */
916eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee  uint16_t ident = table[0];
9170d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  const int32_t* targets = reinterpret_cast<const int32_t*>(&table[4]);
918a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int entries = table[1];
919fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  int low_key = s4FromSwitchData(&table[2]);
920a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  LOG(INFO) << "Packed switch table - ident:0x" << std::hex << ident
921fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee            << ", entries: " << std::dec << entries << ", low_key: " << low_key;
922a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  for (int i = 0; i < entries; i++) {
923fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    LOG(INFO) << "  Key[" << (i + low_key) << "] -> 0x" << std::hex
924a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee              << targets[i];
925a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
92631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee}
927e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
928252254b130067cd7a5071865e793966871ae0246buzbee/* Set up special LIR to mark a Dalvik byte-code instruction start for pretty printing */
9290d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeevoid Mir2Lir::MarkBoundary(DexOffset offset, const char* inst_str) {
9300d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  // NOTE: only used for debug listings.
9310d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  NewLIR1(kPseudoDalvikByteCodeBoundary, WrapPointer(ArenaStrdup(inst_str)));
932d1643e41ef242ae656f667bf3c8b0324635cefd3buzbee}
933e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
9342ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool Mir2Lir::EvaluateBranch(Instruction::Code opcode, int32_t src1, int32_t src2) {
935e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee  bool is_taken;
936e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee  switch (opcode) {
937e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_EQ: is_taken = (src1 == src2); break;
938e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_NE: is_taken = (src1 != src2); break;
939e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_LT: is_taken = (src1 < src2); break;
940e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_GE: is_taken = (src1 >= src2); break;
941e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_GT: is_taken = (src1 > src2); break;
942e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_LE: is_taken = (src1 <= src2); break;
943e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_EQZ: is_taken = (src1 == 0); break;
944e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_NEZ: is_taken = (src1 != 0); break;
945e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_LTZ: is_taken = (src1 < 0); break;
946e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_GEZ: is_taken = (src1 >= 0); break;
947e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_GTZ: is_taken = (src1 > 0); break;
948e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    case Instruction::IF_LEZ: is_taken = (src1 <= 0); break;
949e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee    default:
950e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee      LOG(FATAL) << "Unexpected opcode " << opcode;
951e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee      is_taken = false;
952e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee  }
953e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee  return is_taken;
954e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee}
955e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee
9564ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee// Convert relation of src1/src2 to src2/src1
9571fd3346740dfb7f47be9922312b68a4227fada96buzbeeConditionCode Mir2Lir::FlipComparisonOrder(ConditionCode before) {
9584ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  ConditionCode res;
9594ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  switch (before) {
9604ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    case kCondEq: res = kCondEq; break;
9614ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    case kCondNe: res = kCondNe; break;
9624ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    case kCondLt: res = kCondGt; break;
9634ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    case kCondGt: res = kCondLt; break;
9644ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    case kCondLe: res = kCondGe; break;
9654ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    case kCondGe: res = kCondLe; break;
9664ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    default:
9674ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      res = static_cast<ConditionCode>(0);
9684ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      LOG(FATAL) << "Unexpected ccode " << before;
9694ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  }
9704ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  return res;
9714ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee}
9724ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee
973a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir MarkoConditionCode Mir2Lir::NegateComparison(ConditionCode before) {
974a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko  ConditionCode res;
975a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko  switch (before) {
976a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko    case kCondEq: res = kCondNe; break;
977a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko    case kCondNe: res = kCondEq; break;
978a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko    case kCondLt: res = kCondGe; break;
979a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko    case kCondGt: res = kCondLe; break;
980a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko    case kCondLe: res = kCondGt; break;
981a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko    case kCondGe: res = kCondLt; break;
982a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko    default:
983a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko      res = static_cast<ConditionCode>(0);
984a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko      LOG(FATAL) << "Unexpected ccode " << before;
985a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko  }
986a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko  return res;
987a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko}
988a1a7074eb8256d101f7b5d256cda26d7de6ce6ceVladimir Marko
989862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee// TODO: move to mir_to_lir.cc
990862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbeeMir2Lir::Mir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena)
9916282dc12440a2072dc06a616160027ff21bd895eIan Rogers    : Backend(arena),
9926282dc12440a2072dc06a616160027ff21bd895eIan Rogers      literal_list_(NULL),
9931fd3346740dfb7f47be9922312b68a4227fada96buzbee      method_literal_list_(NULL),
994be1ca55db3362f5b100c4c65da5342fd299520bbHiroshi Yamauchi      class_literal_list_(NULL),
995807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier      string_literal_list_(NULL),
9961fd3346740dfb7f47be9922312b68a4227fada96buzbee      code_literal_list_(NULL),
997b48819db07f9a0992a72173380c24249d7fc648abuzbee      first_fixup_(NULL),
9981fd3346740dfb7f47be9922312b68a4227fada96buzbee      cu_(cu),
9991fd3346740dfb7f47be9922312b68a4227fada96buzbee      mir_graph_(mir_graph),
1000862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      switch_tables_(arena, 4, kGrowableArraySwitchTables),
1001862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      fill_array_data_(arena, 4, kGrowableArrayFillArrayData),
1002bd663de599b16229085759366c56e2ed5a1dc7ecbuzbee      tempreg_info_(arena, 20, kGrowableArrayMisc),
1003091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      reginfo_map_(arena, RegStorage::kMaxRegs, kGrowableArrayMisc),
10040d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee      pointer_storage_(arena, 128, kGrowableArrayMisc),
10051fd3346740dfb7f47be9922312b68a4227fada96buzbee      data_offset_(0),
10061fd3346740dfb7f47be9922312b68a4227fada96buzbee      total_size_(0),
10071fd3346740dfb7f47be9922312b68a4227fada96buzbee      block_label_list_(NULL),
1008d69835d841cb7663faaa2f1996e73e8c0b3f6d76buzbee      promotion_map_(NULL),
1009862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      current_dalvik_offset_(0),
1010b48819db07f9a0992a72173380c24249d7fc648abuzbee      estimated_native_code_size_(0),
1011862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      reg_pool_(NULL),
10121fd3346740dfb7f47be9922312b68a4227fada96buzbee      live_sreg_(0),
10138081d2b8d7a743729557051d0294e040e61c747aVladimir Marko      core_vmap_table_(mir_graph->GetArena()->Adapter()),
10148081d2b8d7a743729557051d0294e040e61c747aVladimir Marko      fp_vmap_table_(mir_graph->GetArena()->Adapter()),
10151fd3346740dfb7f47be9922312b68a4227fada96buzbee      num_core_spills_(0),
10161fd3346740dfb7f47be9922312b68a4227fada96buzbee      num_fp_spills_(0),
10171fd3346740dfb7f47be9922312b68a4227fada96buzbee      frame_size_(0),
10181fd3346740dfb7f47be9922312b68a4227fada96buzbee      core_spill_mask_(0),
10191fd3346740dfb7f47be9922312b68a4227fada96buzbee      fp_spill_mask_(0),
10201fd3346740dfb7f47be9922312b68a4227fada96buzbee      first_lir_insn_(NULL),
1021bcec6fba95ee7974d3f7b81c3c02e7eb3ca3df00Dave Allison      last_lir_insn_(NULL),
10228dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko      slow_paths_(arena, 32, kGrowableArraySlowPaths),
10238dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko      mem_ref_type_(ResourceMask::kHeapRef),
10248dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko      mask_cache_(arena) {
10250d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  // Reserve pointer id 0 for NULL.
10260d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  size_t null_idx = WrapPointer(NULL);
10270d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee  DCHECK_EQ(null_idx, 0U);
10281fd3346740dfb7f47be9922312b68a4227fada96buzbee}
10291fd3346740dfb7f47be9922312b68a4227fada96buzbee
10301fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid Mir2Lir::Materialize() {
1031a61f49539a59b610e557b5513695295639496750buzbee  cu_->NewTimingSplit("RegisterAllocation");
10321fd3346740dfb7f47be9922312b68a4227fada96buzbee  CompilerInitializeRegAlloc();  // Needs to happen after SSA naming
10331fd3346740dfb7f47be9922312b68a4227fada96buzbee
10341fd3346740dfb7f47be9922312b68a4227fada96buzbee  /* Allocate Registers using simple local allocation scheme */
10351fd3346740dfb7f47be9922312b68a4227fada96buzbee  SimpleRegAlloc();
10361fd3346740dfb7f47be9922312b68a4227fada96buzbee
10373bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru  /* First try the custom light codegen for special cases. */
10385816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko  DCHECK(cu_->compiler_driver->GetMethodInlinerMap() != nullptr);
10393bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru  bool special_worked = cu_->compiler_driver->GetMethodInlinerMap()->GetMethodInliner(cu_->dex_file)
10405816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko      ->GenSpecial(this, cu_->method_idx);
10411fd3346740dfb7f47be9922312b68a4227fada96buzbee
10423bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru  /* Take normal path for converting MIR to LIR only if the special codegen did not succeed. */
10433bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru  if (special_worked == false) {
10441fd3346740dfb7f47be9922312b68a4227fada96buzbee    MethodMIR2LIR();
10451fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
10461fd3346740dfb7f47be9922312b68a4227fada96buzbee
10471fd3346740dfb7f47be9922312b68a4227fada96buzbee  /* Method is not empty */
10481fd3346740dfb7f47be9922312b68a4227fada96buzbee  if (first_lir_insn_) {
10491fd3346740dfb7f47be9922312b68a4227fada96buzbee    // mark the targets of switch statement case labels
10501fd3346740dfb7f47be9922312b68a4227fada96buzbee    ProcessSwitchTables();
10511fd3346740dfb7f47be9922312b68a4227fada96buzbee
10521fd3346740dfb7f47be9922312b68a4227fada96buzbee    /* Convert LIR into machine code. */
10531fd3346740dfb7f47be9922312b68a4227fada96buzbee    AssembleLIR();
10541fd3346740dfb7f47be9922312b68a4227fada96buzbee
1055b01bf15d18f9b08d77e7a3c6e2897af0e02bf8cabuzbee    if ((cu_->enable_debug & (1 << kDebugCodegenDump)) != 0) {
10561fd3346740dfb7f47be9922312b68a4227fada96buzbee      CodegenDump();
10571fd3346740dfb7f47be9922312b68a4227fada96buzbee    }
10581fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
10591fd3346740dfb7f47be9922312b68a4227fada96buzbee}
10601fd3346740dfb7f47be9922312b68a4227fada96buzbee
10611fd3346740dfb7f47be9922312b68a4227fada96buzbeeCompiledMethod* Mir2Lir::GetCompiledMethod() {
10622e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko  // Combine vmap tables - core regs, then fp regs - into vmap_table.
10632e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko  Leb128EncodingVector vmap_encoder;
10641fd3346740dfb7f47be9922312b68a4227fada96buzbee  if (frame_size_ > 0) {
10652e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko    // Prefix the encoded data with its size.
10662e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko    size_t size = core_vmap_table_.size() + 1 /* marker */ + fp_vmap_table_.size();
10672e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko    vmap_encoder.Reserve(size + 1u);  // All values are likely to be one byte in ULEB128 (<128).
10682e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko    vmap_encoder.PushBackUnsigned(size);
10692e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko    // Core regs may have been inserted out of order - sort first.
10702e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko    std::sort(core_vmap_table_.begin(), core_vmap_table_.end());
10712e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko    for (size_t i = 0 ; i < core_vmap_table_.size(); ++i) {
10722e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko      // Copy, stripping out the phys register sort key.
10732e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko      vmap_encoder.PushBackUnsigned(
10742e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko          ~(-1 << VREG_NUM_WIDTH) & (core_vmap_table_[i] + VmapTable::kEntryAdjustment));
10752e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko    }
10762e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko    // Push a marker to take place of lr.
10772e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko    vmap_encoder.PushBackUnsigned(VmapTable::kAdjustedFpMarker);
1078c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    if (cu_->instruction_set == kThumb2) {
1079c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      // fp regs already sorted.
1080c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      for (uint32_t i = 0; i < fp_vmap_table_.size(); i++) {
1081c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov        vmap_encoder.PushBackUnsigned(fp_vmap_table_[i] + VmapTable::kEntryAdjustment);
1082c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      }
1083c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov    } else {
1084c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      // For other platforms regs may have been inserted out of order - sort first.
1085c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      std::sort(fp_vmap_table_.begin(), fp_vmap_table_.end());
1086c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      for (size_t i = 0 ; i < fp_vmap_table_.size(); ++i) {
1087c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov        // Copy, stripping out the phys register sort key.
1088c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov        vmap_encoder.PushBackUnsigned(
1089c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov            ~(-1 << VREG_NUM_WIDTH) & (fp_vmap_table_[i] + VmapTable::kEntryAdjustment));
1090c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov      }
10912e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko    }
10921fd3346740dfb7f47be9922312b68a4227fada96buzbee  } else {
10938194963098247be6bca9cc4a54dbfa65c73e8cccVladimir Marko    DCHECK_EQ(POPCOUNT(core_spill_mask_), 0);
10948194963098247be6bca9cc4a54dbfa65c73e8cccVladimir Marko    DCHECK_EQ(POPCOUNT(fp_spill_mask_), 0);
10952e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko    DCHECK_EQ(core_vmap_table_.size(), 0u);
10962e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko    DCHECK_EQ(fp_vmap_table_.size(), 0u);
10972e589aa58a1372909f95e731fd6b8895f6359c3aVladimir Marko    vmap_encoder.PushBackUnsigned(0u);  // Size is 0.
10981fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
1099ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
1100700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<std::vector<uint8_t>> cfi_info(ReturnCallFrameInformation());
110162746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  ArrayRef<const uint8_t> cfi_ref;
110262746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  if (cfi_info.get() != nullptr) {
110362746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe    cfi_ref = ArrayRef<const uint8_t>(*cfi_info);
110462746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  }
110562746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  return CompiledMethod::SwapAllocCompiledMethod(
110662746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe      cu_->compiler_driver, cu_->instruction_set,
110762746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe      ArrayRef<const uint8_t>(code_buffer_),
110862746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe      frame_size_, core_spill_mask_, fp_spill_mask_,
110962746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe      ArrayRef<const uint8_t>(encoded_mapping_table_),
111062746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe      ArrayRef<const uint8_t>(vmap_encoder.GetData()),
111162746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe      ArrayRef<const uint8_t>(native_gc_map_),
111262746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe      cfi_ref);
11131fd3346740dfb7f47be9922312b68a4227fada96buzbee}
11141fd3346740dfb7f47be9922312b68a4227fada96buzbee
1115da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusorusize_t Mir2Lir::GetMaxPossibleCompilerTemps() const {
1116da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  // Chose a reasonably small value in order to contain stack growth.
1117da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  // Backends that are smarter about spill region can return larger values.
1118da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  const size_t max_compiler_temps = 10;
1119da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  return max_compiler_temps;
1120da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru}
1121da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru
1122da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusorusize_t Mir2Lir::GetNumBytesForCompilerTempSpillRegion() {
1123da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  // By default assume that the Mir2Lir will need one slot for each temporary.
1124da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  // If the backend can better determine temps that have non-overlapping ranges and
1125da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  // temps that do not need spilled, it can actually provide a small region.
1126da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru  return (mir_graph_->GetNumUsedCompilerTemps() * sizeof(uint32_t));
1127da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru}
1128da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru
11291fd3346740dfb7f47be9922312b68a4227fada96buzbeeint Mir2Lir::ComputeFrameSize() {
11301fd3346740dfb7f47be9922312b68a4227fada96buzbee  /* Figure out the frame size */
1131f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko  uint32_t size = num_core_spills_ * GetBytesPerGprSpillLocation(cu_->instruction_set)
1132f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko                  + num_fp_spills_ * GetBytesPerFprSpillLocation(cu_->instruction_set)
1133f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko                  + sizeof(uint32_t)  // Filler.
1134f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko                  + (cu_->num_regs + cu_->num_outs) * sizeof(uint32_t)
1135f29a4244bbc278843237f0ae242de077e093b580Dmitry Petrochenko                  + GetNumBytesForCompilerTempSpillRegion();
11361fd3346740dfb7f47be9922312b68a4227fada96buzbee  /* Align and set */
1137660188264dee3c8f3510e2e24c11816c6b60f197Andreas Gampe  return RoundUp(size, kStackAlignment);
11381fd3346740dfb7f47be9922312b68a4227fada96buzbee}
11391fd3346740dfb7f47be9922312b68a4227fada96buzbee
11401fd3346740dfb7f47be9922312b68a4227fada96buzbee/*
11411fd3346740dfb7f47be9922312b68a4227fada96buzbee * Append an LIR instruction to the LIR list maintained by a compilation
11421fd3346740dfb7f47be9922312b68a4227fada96buzbee * unit
11431fd3346740dfb7f47be9922312b68a4227fada96buzbee */
11442ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::AppendLIR(LIR* lir) {
11451fd3346740dfb7f47be9922312b68a4227fada96buzbee  if (first_lir_insn_ == NULL) {
11461fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK(last_lir_insn_ == NULL);
11471fd3346740dfb7f47be9922312b68a4227fada96buzbee    last_lir_insn_ = first_lir_insn_ = lir;
11481fd3346740dfb7f47be9922312b68a4227fada96buzbee    lir->prev = lir->next = NULL;
11491fd3346740dfb7f47be9922312b68a4227fada96buzbee  } else {
11501fd3346740dfb7f47be9922312b68a4227fada96buzbee    last_lir_insn_->next = lir;
11511fd3346740dfb7f47be9922312b68a4227fada96buzbee    lir->prev = last_lir_insn_;
11521fd3346740dfb7f47be9922312b68a4227fada96buzbee    lir->next = NULL;
11531fd3346740dfb7f47be9922312b68a4227fada96buzbee    last_lir_insn_ = lir;
11541fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
11551fd3346740dfb7f47be9922312b68a4227fada96buzbee}
11561fd3346740dfb7f47be9922312b68a4227fada96buzbee
11571fd3346740dfb7f47be9922312b68a4227fada96buzbee/*
11581fd3346740dfb7f47be9922312b68a4227fada96buzbee * Insert an LIR instruction before the current instruction, which cannot be the
11591fd3346740dfb7f47be9922312b68a4227fada96buzbee * first instruction.
11601fd3346740dfb7f47be9922312b68a4227fada96buzbee *
11611fd3346740dfb7f47be9922312b68a4227fada96buzbee * prev_lir <-> new_lir <-> current_lir
11621fd3346740dfb7f47be9922312b68a4227fada96buzbee */
11632ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InsertLIRBefore(LIR* current_lir, LIR* new_lir) {
11641fd3346740dfb7f47be9922312b68a4227fada96buzbee  DCHECK(current_lir->prev != NULL);
11651fd3346740dfb7f47be9922312b68a4227fada96buzbee  LIR *prev_lir = current_lir->prev;
11661fd3346740dfb7f47be9922312b68a4227fada96buzbee
11671fd3346740dfb7f47be9922312b68a4227fada96buzbee  prev_lir->next = new_lir;
11681fd3346740dfb7f47be9922312b68a4227fada96buzbee  new_lir->prev = prev_lir;
11691fd3346740dfb7f47be9922312b68a4227fada96buzbee  new_lir->next = current_lir;
11701fd3346740dfb7f47be9922312b68a4227fada96buzbee  current_lir->prev = new_lir;
11711fd3346740dfb7f47be9922312b68a4227fada96buzbee}
11721fd3346740dfb7f47be9922312b68a4227fada96buzbee
11731fd3346740dfb7f47be9922312b68a4227fada96buzbee/*
11741fd3346740dfb7f47be9922312b68a4227fada96buzbee * Insert an LIR instruction after the current instruction, which cannot be the
11753c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe * last instruction.
11761fd3346740dfb7f47be9922312b68a4227fada96buzbee *
11771fd3346740dfb7f47be9922312b68a4227fada96buzbee * current_lir -> new_lir -> old_next
11781fd3346740dfb7f47be9922312b68a4227fada96buzbee */
11792ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid Mir2Lir::InsertLIRAfter(LIR* current_lir, LIR* new_lir) {
11801fd3346740dfb7f47be9922312b68a4227fada96buzbee  new_lir->prev = current_lir;
11811fd3346740dfb7f47be9922312b68a4227fada96buzbee  new_lir->next = current_lir->next;
11821fd3346740dfb7f47be9922312b68a4227fada96buzbee  current_lir->next = new_lir;
11831fd3346740dfb7f47be9922312b68a4227fada96buzbee  new_lir->next->prev = new_lir;
11841fd3346740dfb7f47be9922312b68a4227fada96buzbee}
11851fd3346740dfb7f47be9922312b68a4227fada96buzbee
11864708dcd68eebf1173aef1097dad8ab13466059aaMark Mendellbool Mir2Lir::IsPowerOfTwo(uint64_t x) {
11874708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  return (x & (x - 1)) == 0;
11884708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell}
11894708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell
11904708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell// Returns the index of the lowest set bit in 'x'.
11914708dcd68eebf1173aef1097dad8ab13466059aaMark Mendellint32_t Mir2Lir::LowestSetBit(uint64_t x) {
11924708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  int bit_posn = 0;
11934708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  while ((x & 0xf) == 0) {
11944708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell    bit_posn += 4;
11954708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell    x >>= 4;
11964708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  }
11974708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  while ((x & 1) == 0) {
11984708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell    bit_posn++;
11994708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell    x >>= 1;
12004708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  }
12014708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  return bit_posn;
12024708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell}
12034708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell
12044708dcd68eebf1173aef1097dad8ab13466059aaMark Mendellbool Mir2Lir::BadOverlap(RegLocation rl_src, RegLocation rl_dest) {
12054708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  DCHECK(rl_src.wide);
12064708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  DCHECK(rl_dest.wide);
12074708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell  return (abs(mir_graph_->SRegToVReg(rl_src.s_reg_low) - mir_graph_->SRegToVReg(rl_dest.s_reg_low)) == 1);
12084708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell}
12094708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell
12102700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR *Mir2Lir::OpCmpMemImmBranch(ConditionCode cond, RegStorage temp_reg, RegStorage base_reg,
121169dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison                                int offset, int check_value, LIR* target, LIR** compare) {
1212766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell  // Handle this for architectures that can't compare to memory.
121369dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison  LIR* inst = Load32Disp(base_reg, offset, temp_reg);
121469dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison  if (compare != nullptr) {
121569dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison    *compare = inst;
121669dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison  }
1217766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell  LIR* branch = OpCmpImmBranch(cond, temp_reg, check_value, target);
1218766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell  return branch;
1219766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell}
1220766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell
1221bcec6fba95ee7974d3f7b81c3c02e7eb3ca3df00Dave Allisonvoid Mir2Lir::AddSlowPath(LIRSlowPath* slowpath) {
1222bcec6fba95ee7974d3f7b81c3c02e7eb3ca3df00Dave Allison  slow_paths_.Insert(slowpath);
1223bcec6fba95ee7974d3f7b81c3c02e7eb3ca3df00Dave Allison}
122455d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell
122549161cef10a308aedada18e9aa742498d6e6c8c7Jeff Haovoid Mir2Lir::LoadCodeAddress(const MethodReference& target_method, InvokeType type,
122649161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao                              SpecialTargetRegister symbolic_reg) {
1227a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko  LIR* data_target = ScanLiteralPoolMethod(code_literal_list_, target_method);
122855d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell  if (data_target == NULL) {
1229a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko    data_target = AddWordData(&code_literal_list_, target_method.dex_method_index);
123049161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao    data_target->operands[1] = WrapPointer(const_cast<DexFile*>(target_method.dex_file));
1231a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko    // NOTE: The invoke type doesn't contribute to the literal identity. In fact, we can have
1232a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko    // the same method invoked with kVirtual, kSuper and kInterface but the class linker will
1233a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko    // resolve these invokes to the same method, so we don't care which one we record here.
123449161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao    data_target->operands[2] = type;
123555d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell  }
1236a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu  // Loads a code pointer. Code from oat file can be mapped anywhere.
1237a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu  LIR* load_pc_rel = OpPcRelLoad(TargetPtrReg(symbolic_reg), data_target);
123855d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell  AppendLIR(load_pc_rel);
123955d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell  DCHECK_NE(cu_->instruction_set, kMips) << reinterpret_cast<void*>(data_target);
124055d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell}
124155d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell
124249161cef10a308aedada18e9aa742498d6e6c8c7Jeff Haovoid Mir2Lir::LoadMethodAddress(const MethodReference& target_method, InvokeType type,
124349161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao                                SpecialTargetRegister symbolic_reg) {
1244a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko  LIR* data_target = ScanLiteralPoolMethod(method_literal_list_, target_method);
124555d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell  if (data_target == NULL) {
1246a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko    data_target = AddWordData(&method_literal_list_, target_method.dex_method_index);
124749161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao    data_target->operands[1] = WrapPointer(const_cast<DexFile*>(target_method.dex_file));
1248a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko    // NOTE: The invoke type doesn't contribute to the literal identity. In fact, we can have
1249a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko    // the same method invoked with kVirtual, kSuper and kInterface but the class linker will
1250a51a0b0300268b605e3ad71b0e87ff394032c5e7Vladimir Marko    // resolve these invokes to the same method, so we don't care which one we record here.
125149161cef10a308aedada18e9aa742498d6e6c8c7Jeff Hao    data_target->operands[2] = type;
125255d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell  }
1253a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu  // Loads an ArtMethod pointer, which is a reference as it lives in the heap.
1254ccc60264229ac96d798528d2cb7dbbdd0deca993Andreas Gampe  LIR* load_pc_rel = OpPcRelLoad(TargetReg(symbolic_reg, kRef), data_target);
125555d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell  AppendLIR(load_pc_rel);
125655d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell  DCHECK_NE(cu_->instruction_set, kMips) << reinterpret_cast<void*>(data_target);
125755d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell}
125855d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell
125955d0eac918321e0525f6e6491f36a80977e0d416Mark Mendellvoid Mir2Lir::LoadClassType(uint32_t type_idx, SpecialTargetRegister symbolic_reg) {
126055d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell  // Use the literal pool and a PC-relative load from a data word.
126155d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell  LIR* data_target = ScanLiteralPool(class_literal_list_, type_idx, 0);
126255d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell  if (data_target == nullptr) {
126355d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell    data_target = AddWordData(&class_literal_list_, type_idx);
126455d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell  }
1265a77ee5103532abb197f492c14a9e6fb437054e2aChao-ying Fu  // Loads a Class pointer, which is a reference as it lives in the heap.
1266ccc60264229ac96d798528d2cb7dbbdd0deca993Andreas Gampe  LIR* load_pc_rel = OpPcRelLoad(TargetReg(symbolic_reg, kRef), data_target);
126755d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell  AppendLIR(load_pc_rel);
126855d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell}
126955d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell
1270807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartiervoid Mir2Lir::LoadString(uint32_t string_idx, RegStorage target_reg) {
1271807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier  // Use the literal pool and a PC-relative load from a data word.
1272807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier  LIR* data_target = ScanLiteralPool(string_literal_list_, string_idx, 0);
1273807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier  if (data_target == nullptr) {
1274807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier    data_target = AddWordData(&string_literal_list_, string_idx);
1275807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier  }
1276807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier  // Loads a Class pointer, which is a reference as it lives in the heap.
1277807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier  LIR* load_pc_rel = OpPcRelLoad(target_reg, data_target);
1278807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier  AppendLIR(load_pc_rel);
1279807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier}
1280807140048f82a2b87ee5bcf337f23b6a3d1d5269Mathieu Chartier
1281ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendellstd::vector<uint8_t>* Mir2Lir::ReturnCallFrameInformation() {
1282ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // Default case is to do nothing.
1283ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  return nullptr;
1284ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell}
1285ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
12862700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeRegLocation Mir2Lir::NarrowRegLoc(RegLocation loc) {
1287091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  if (loc.location == kLocPhysReg) {
128885089dd28a39dd20f42ac258398b2a08668f9ef1buzbee    DCHECK(!loc.reg.Is32Bit());
1289091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee    if (loc.reg.IsPair()) {
129085089dd28a39dd20f42ac258398b2a08668f9ef1buzbee      RegisterInfo* info_lo = GetRegInfo(loc.reg.GetLow());
129185089dd28a39dd20f42ac258398b2a08668f9ef1buzbee      RegisterInfo* info_hi = GetRegInfo(loc.reg.GetHigh());
129285089dd28a39dd20f42ac258398b2a08668f9ef1buzbee      info_lo->SetIsWide(false);
129385089dd28a39dd20f42ac258398b2a08668f9ef1buzbee      info_hi->SetIsWide(false);
129485089dd28a39dd20f42ac258398b2a08668f9ef1buzbee      loc.reg = info_lo->GetReg();
1295091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee    } else {
129685089dd28a39dd20f42ac258398b2a08668f9ef1buzbee      RegisterInfo* info = GetRegInfo(loc.reg);
129785089dd28a39dd20f42ac258398b2a08668f9ef1buzbee      RegisterInfo* info_new = info->FindMatchingView(RegisterInfo::k32SoloStorageMask);
129885089dd28a39dd20f42ac258398b2a08668f9ef1buzbee      DCHECK(info_new != nullptr);
129985089dd28a39dd20f42ac258398b2a08668f9ef1buzbee      if (info->IsLive() && (info->SReg() == loc.s_reg_low)) {
130085089dd28a39dd20f42ac258398b2a08668f9ef1buzbee        info->MarkDead();
130185089dd28a39dd20f42ac258398b2a08668f9ef1buzbee        info_new->MarkLive(loc.s_reg_low);
130285089dd28a39dd20f42ac258398b2a08668f9ef1buzbee      }
130385089dd28a39dd20f42ac258398b2a08668f9ef1buzbee      loc.reg = info_new->GetReg();
1304091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee    }
130585089dd28a39dd20f42ac258398b2a08668f9ef1buzbee    DCHECK(loc.reg.Valid());
13062700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  }
130785089dd28a39dd20f42ac258398b2a08668f9ef1buzbee  loc.wide = false;
13082700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  return loc;
13092700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee}
13102700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee
1311d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendellvoid Mir2Lir::GenMachineSpecificExtendedMethodMIR(BasicBlock* bb, MIR* mir) {
1312d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell  LOG(FATAL) << "Unknown MIR opcode not supported on this architecture";
1313d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell}
1314d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell
13157934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom}  // namespace art
1316