gbc_expander.cc revision 98573f907b2f5d1ccb4f6549a487f567599a82d3
121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao/*
221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao * Copyright (C) 2012 The Android Open Source Project
321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao *
421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License");
521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao * you may not use this file except in compliance with the License.
621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao * You may obtain a copy of the License at
721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao *
821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao *      http://www.apache.org/licenses/LICENSE-2.0
921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao *
1021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao * Unless required by applicable law or agreed to in writing, software
1121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS,
1221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao * See the License for the specific language governing permissions and
1421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao * limitations under the License.
1521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao */
1621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
1721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include "ir_builder.h"
1821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include "utils_llvm.h"
1921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
205e869b6560f918837cc6be3a50234deb2be46385TDYa#include "compiler.h"
2121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include "greenland/intrinsic_helper.h"
2298573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers#include "mirror/abstract_method.h"
2398573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers#include "mirror/array.h"
245e869b6560f918837cc6be3a50234deb2be46385TDYa#include "oat_compilation_unit.h"
2521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include "thread.h"
265e869b6560f918837cc6be3a50234deb2be46385TDYa#include "verifier/method_verifier.h"
2721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
28efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#include "compiler/compiler_ir.h"
29449a49bedfb72f0d5643977a99346935f1b33c55buzbee#include "compiler/codegen/codegen.h"
30920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYausing art::kMIRIgnoreNullCheck;
31920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYausing art::kMIRIgnoreRangeCheck;
32920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa
3321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include <llvm/ADT/STLExtras.h>
3421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include <llvm/Intrinsics.h>
35d36a2aceeb17b2b1745fc64a8f1dfc77425d43deLogan Chien#include <llvm/Metadata.h>
3621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include <llvm/Pass.h>
3721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include <llvm/Support/CFG.h>
3821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include <llvm/Support/InstIterator.h>
3921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
4021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include <vector>
41aa55887fd30484a77e7775dfbcddbee883ce6380TDYa#include <map>
42aa55887fd30484a77e7775dfbcddbee883ce6380TDYa#include <utility>
4321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
44920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYausing namespace art::compiler_llvm;
4521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
4621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaousing art::greenland::IntrinsicHelper;
4721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
48b259652a72293b4bd3c346bb0e40fb8a7f878fa2Shih-wei Liaonamespace art {
4926f10eed520942d3db754c31941e457048475f61buzbeeextern char RemapShorty(char shortyType);
50b259652a72293b4bd3c346bb0e40fb8a7f878fa2Shih-wei Liao};
51b259652a72293b4bd3c346bb0e40fb8a7f878fa2Shih-wei Liao
5221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaonamespace {
5321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
5421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaoclass GBCExpanderPass : public llvm::FunctionPass {
5521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao private:
5621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  const IntrinsicHelper& intrinsic_helper_;
5721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  IRBuilder& irb_;
5821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
5921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::LLVMContext& context_;
6021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  RuntimeSupportBuilder& rtb_;
6121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
6221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao private:
6321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::AllocaInst* shadow_frame_;
6421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* old_shadow_frame_;
6521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
6621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao private:
67920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  art::Compiler* compiler_;
685e869b6560f918837cc6be3a50234deb2be46385TDYa
69920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  const art::DexFile* dex_file_;
70920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  const art::DexFile::CodeItem* code_item_;
715e869b6560f918837cc6be3a50234deb2be46385TDYa
72920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  art::OatCompilationUnit* oat_compilation_unit_;
735e869b6560f918837cc6be3a50234deb2be46385TDYa
745e869b6560f918837cc6be3a50234deb2be46385TDYa  uint32_t method_idx_;
755e869b6560f918837cc6be3a50234deb2be46385TDYa
765e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::Function* func_;
775e869b6560f918837cc6be3a50234deb2be46385TDYa
785e869b6560f918837cc6be3a50234deb2be46385TDYa  std::vector<llvm::BasicBlock*> basic_blocks_;
795e869b6560f918837cc6be3a50234deb2be46385TDYa
805e869b6560f918837cc6be3a50234deb2be46385TDYa  std::vector<llvm::BasicBlock*> basic_block_landing_pads_;
8155e5e6c5702e3f1f68bd83ae741af769740d9a74TDYa  llvm::BasicBlock* current_bb_;
82aa55887fd30484a77e7775dfbcddbee883ce6380TDYa  std::map<llvm::BasicBlock*, std::vector<std::pair<llvm::BasicBlock*, llvm::BasicBlock*> > >
83aa55887fd30484a77e7775dfbcddbee883ce6380TDYa      landing_pad_phi_mapping_;
845e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::BasicBlock* basic_block_unwind_;
855e869b6560f918837cc6be3a50234deb2be46385TDYa
8667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  bool changed_;
8767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
885e869b6560f918837cc6be3a50234deb2be46385TDYa private:
8921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  //----------------------------------------------------------------------------
9075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  // Constant for GBC expansion
9175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  //----------------------------------------------------------------------------
9275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  enum IntegerShiftKind {
9375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    kIntegerSHL,
9475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    kIntegerSHR,
9575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    kIntegerUSHR,
9675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  };
9775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
9875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien private:
9975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  //----------------------------------------------------------------------------
10021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Helper function for GBC expansion
10121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  //----------------------------------------------------------------------------
10221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
10321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* ExpandToRuntime(runtime_support::RuntimeId rt,
10421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                               llvm::CallInst& inst);
10521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
1065e869b6560f918837cc6be3a50234deb2be46385TDYa  uint64_t LV2UInt(llvm::Value* lv) {
1075e869b6560f918837cc6be3a50234deb2be46385TDYa    return llvm::cast<llvm::ConstantInt>(lv)->getZExtValue();
1085e869b6560f918837cc6be3a50234deb2be46385TDYa  }
1095e869b6560f918837cc6be3a50234deb2be46385TDYa
1105e869b6560f918837cc6be3a50234deb2be46385TDYa  int64_t LV2SInt(llvm::Value* lv) {
1115e869b6560f918837cc6be3a50234deb2be46385TDYa    return llvm::cast<llvm::ConstantInt>(lv)->getSExtValue();
1125e869b6560f918837cc6be3a50234deb2be46385TDYa  }
1135e869b6560f918837cc6be3a50234deb2be46385TDYa
11421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao private:
11521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // TODO: Almost all Emit* are directly copy-n-paste from MethodCompiler.
11621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Refactor these utility functions from MethodCompiler to avoid forking.
11721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
11867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  void EmitStackOverflowCheck(llvm::Instruction* first_non_alloca);
11967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
12067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  void RewriteFunction();
12167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
12267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  void RewriteBasicBlock(llvm::BasicBlock* original_block);
12367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
12467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  void UpdatePhiInstruction(llvm::BasicBlock* old_basic_block,
12567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien                            llvm::BasicBlock* new_basic_block);
12667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
12721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
12821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  //----------------------------------------------------------------------------
12921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Dex cache code generation helper function
13021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  //----------------------------------------------------------------------------
131920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  llvm::Value* EmitLoadDexCacheAddr(art::MemberOffset dex_cache_offset);
13221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
13321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* EmitLoadDexCacheStaticStorageFieldAddr(uint32_t type_idx);
13421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
13521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* EmitLoadDexCacheResolvedTypeFieldAddr(uint32_t type_idx);
13621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
13721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* EmitLoadDexCacheResolvedMethodFieldAddr(uint32_t method_idx);
13821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
13921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* EmitLoadDexCacheStringFieldAddr(uint32_t string_idx);
14021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
14121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  //----------------------------------------------------------------------------
14221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Code generation helper function
14321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  //----------------------------------------------------------------------------
14421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* EmitLoadMethodObjectAddr();
14521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
14621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* EmitLoadArrayLength(llvm::Value* array);
14721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
14821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* EmitLoadSDCalleeMethodObjectAddr(uint32_t callee_method_idx);
14921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
15021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* EmitLoadVirtualCalleeMethodObjectAddr(int vtable_idx,
15121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                                     llvm::Value* this_addr);
15221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
15321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* EmitArrayGEP(llvm::Value* array_addr,
15421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                            llvm::Value* index_value,
15521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                            JType elem_jty);
15621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
15721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao private:
15821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  //----------------------------------------------------------------------------
15921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Expand Greenland intrinsics
16021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  //----------------------------------------------------------------------------
16121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  void Expand_TestSuspend(llvm::CallInst& call_inst);
16221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
1639a129457c233b653c7a8f65c963509267252b0a7TDYa  void Expand_MarkGCCard(llvm::CallInst& call_inst);
1649a129457c233b653c7a8f65c963509267252b0a7TDYa
16521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* Expand_LoadStringFromDexCache(llvm::Value* string_idx_value);
16621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
16721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* Expand_LoadTypeFromDexCache(llvm::Value* type_idx_value);
16821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
16921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  void Expand_LockObject(llvm::Value* obj);
17021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
17121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  void Expand_UnlockObject(llvm::Value* obj);
17221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
17321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* Expand_ArrayGet(llvm::Value* array_addr,
17421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                               llvm::Value* index_value,
17521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                               JType elem_jty);
17621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
17721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  void Expand_ArrayPut(llvm::Value* new_value,
17821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                       llvm::Value* array_addr,
17921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                       llvm::Value* index_value,
18021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                       JType elem_jty);
18121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
18221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  void Expand_FilledNewArray(llvm::CallInst& call_inst);
18321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
18421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* Expand_IGetFast(llvm::Value* field_offset_value,
18521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                               llvm::Value* is_volatile_value,
18621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                               llvm::Value* object_addr,
18721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                               JType field_jty);
18821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
18921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  void Expand_IPutFast(llvm::Value* field_offset_value,
19021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                       llvm::Value* is_volatile_value,
19121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                       llvm::Value* object_addr,
19221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                       llvm::Value* new_value,
19321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                       JType field_jty);
19421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
19521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* Expand_SGetFast(llvm::Value* static_storage_addr,
19621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                               llvm::Value* field_offset_value,
19721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                               llvm::Value* is_volatile_value,
19821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                               JType field_jty);
19921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
20021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  void Expand_SPutFast(llvm::Value* static_storage_addr,
20121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                       llvm::Value* field_offset_value,
20221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                       llvm::Value* is_volatile_value,
20321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                       llvm::Value* new_value,
20421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                       JType field_jty);
20521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
20621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* Expand_LoadDeclaringClassSSB(llvm::Value* method_object_addr);
20721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
20821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* Expand_LoadClassSSBFromDexCache(llvm::Value* type_idx_value);
20921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
21021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value*
21121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  Expand_GetSDCalleeMethodObjAddrFast(llvm::Value* callee_method_idx_value);
21221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
21321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value*
21421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  Expand_GetVirtualCalleeMethodObjAddrFast(llvm::Value* vtable_idx_value,
21521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                           llvm::Value* this_addr);
21621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
21721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* Expand_Invoke(llvm::CallInst& call_inst);
21821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
2194ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa  llvm::Value* Expand_DivRem(llvm::CallInst& call_inst, bool is_div, JType op_jty);
22021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
221ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  void Expand_AllocaShadowFrame(llvm::Value* num_vregs_value);
22221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
2238e950c117975d23f50ed7e32ca5db01a813c25d0TDYa  void Expand_SetVReg(llvm::Value* entry_idx, llvm::Value* obj);
2248e950c117975d23f50ed7e32ca5db01a813c25d0TDYa
22521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  void Expand_PopShadowFrame();
22621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
22721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  void Expand_UpdateDexPC(llvm::Value* dex_pc_value);
22821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
229a1b2185820e6080864d18a35759cc046dc4ee578TDYa  //----------------------------------------------------------------------------
230a1b2185820e6080864d18a35759cc046dc4ee578TDYa  // Quick
231a1b2185820e6080864d18a35759cc046dc4ee578TDYa  //----------------------------------------------------------------------------
232a1b2185820e6080864d18a35759cc046dc4ee578TDYa
233a1b2185820e6080864d18a35759cc046dc4ee578TDYa  llvm::Value* Expand_FPCompare(llvm::Value* src1_value,
234a1b2185820e6080864d18a35759cc046dc4ee578TDYa                                llvm::Value* src2_value,
235a1b2185820e6080864d18a35759cc046dc4ee578TDYa                                bool gt_bias);
236a1b2185820e6080864d18a35759cc046dc4ee578TDYa
237a1b2185820e6080864d18a35759cc046dc4ee578TDYa  llvm::Value* Expand_LongCompare(llvm::Value* src1_value, llvm::Value* src2_value);
238a1b2185820e6080864d18a35759cc046dc4ee578TDYa
239a1b2185820e6080864d18a35759cc046dc4ee578TDYa  llvm::Value* EmitCompareResultSelection(llvm::Value* cmp_eq,
240a1b2185820e6080864d18a35759cc046dc4ee578TDYa                                          llvm::Value* cmp_lt);
241a1b2185820e6080864d18a35759cc046dc4ee578TDYa
242f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* EmitLoadConstantClass(uint32_t dex_pc, uint32_t type_idx);
2435a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Value* EmitLoadStaticStorage(uint32_t dex_pc, uint32_t type_idx);
2445a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
2455e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::Value* Expand_HLIGet(llvm::CallInst& call_inst, JType field_jty);
2465e869b6560f918837cc6be3a50234deb2be46385TDYa  void Expand_HLIPut(llvm::CallInst& call_inst, JType field_jty);
2475e869b6560f918837cc6be3a50234deb2be46385TDYa
2485a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Value* Expand_HLSget(llvm::CallInst& call_inst, JType field_jty);
2495a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  void Expand_HLSput(llvm::CallInst& call_inst, JType field_jty);
2505a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
2515a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Value* Expand_HLArrayGet(llvm::CallInst& call_inst, JType field_jty);
2525a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  void Expand_HLArrayPut(llvm::CallInst& call_inst, JType field_jty);
2535a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
254f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* Expand_ConstString(llvm::CallInst& call_inst);
255f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* Expand_ConstClass(llvm::CallInst& call_inst);
256f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
257f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  void Expand_MonitorEnter(llvm::CallInst& call_inst);
258f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  void Expand_MonitorExit(llvm::CallInst& call_inst);
259f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
260f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  void Expand_HLCheckCast(llvm::CallInst& call_inst);
261f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* Expand_InstanceOf(llvm::CallInst& call_inst);
262f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
263f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* Expand_NewInstance(llvm::CallInst& call_inst);
264f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
265f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* Expand_HLInvoke(llvm::CallInst& call_inst);
266f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
267f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* Expand_OptArrayLength(llvm::CallInst& call_inst);
268f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* Expand_NewArray(llvm::CallInst& call_inst);
269f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* Expand_HLFilledNewArray(llvm::CallInst& call_inst);
270f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  void Expand_HLFillArrayData(llvm::CallInst& call_inst);
271f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
272f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* EmitAllocNewArray(uint32_t dex_pc,
273f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                                 llvm::Value* array_length_value,
274f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                                 uint32_t type_idx,
275f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                                 bool is_filled_new_array);
276f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
277f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* EmitCallRuntimeForCalleeMethodObjectAddr(uint32_t callee_method_idx,
278920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa                                                        art::InvokeType invoke_type,
279f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                                                        llvm::Value* this_addr,
280f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                                                        uint32_t dex_pc,
281f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                                                        bool is_fast_path);
282f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2835e869b6560f918837cc6be3a50234deb2be46385TDYa  void EmitMarkGCCard(llvm::Value* value, llvm::Value* target_addr);
2845e869b6560f918837cc6be3a50234deb2be46385TDYa
2855e869b6560f918837cc6be3a50234deb2be46385TDYa  void EmitUpdateDexPC(uint32_t dex_pc);
2865e869b6560f918837cc6be3a50234deb2be46385TDYa
2875e869b6560f918837cc6be3a50234deb2be46385TDYa  void EmitGuard_DivZeroException(uint32_t dex_pc,
2885e869b6560f918837cc6be3a50234deb2be46385TDYa                                  llvm::Value* denominator,
2895e869b6560f918837cc6be3a50234deb2be46385TDYa                                  JType op_jty);
2905e869b6560f918837cc6be3a50234deb2be46385TDYa
2915e869b6560f918837cc6be3a50234deb2be46385TDYa  void EmitGuard_NullPointerException(uint32_t dex_pc,
2925e869b6560f918837cc6be3a50234deb2be46385TDYa                                      llvm::Value* object);
2935e869b6560f918837cc6be3a50234deb2be46385TDYa
2945e869b6560f918837cc6be3a50234deb2be46385TDYa  void EmitGuard_ArrayIndexOutOfBoundsException(uint32_t dex_pc,
2955e869b6560f918837cc6be3a50234deb2be46385TDYa                                                llvm::Value* array,
2965e869b6560f918837cc6be3a50234deb2be46385TDYa                                                llvm::Value* index);
2975e869b6560f918837cc6be3a50234deb2be46385TDYa
2985e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::FunctionType* GetFunctionType(uint32_t method_idx, bool is_static);
2995e869b6560f918837cc6be3a50234deb2be46385TDYa
3005e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::BasicBlock* GetBasicBlock(uint32_t dex_pc);
3015e869b6560f918837cc6be3a50234deb2be46385TDYa
3025e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::BasicBlock* CreateBasicBlockWithDexPC(uint32_t dex_pc,
3035e869b6560f918837cc6be3a50234deb2be46385TDYa                                              const char* postfix);
3045e869b6560f918837cc6be3a50234deb2be46385TDYa
3055e869b6560f918837cc6be3a50234deb2be46385TDYa  int32_t GetTryItemOffset(uint32_t dex_pc);
3065e869b6560f918837cc6be3a50234deb2be46385TDYa
3075e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::BasicBlock* GetLandingPadBasicBlock(uint32_t dex_pc);
3085e869b6560f918837cc6be3a50234deb2be46385TDYa
3095e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::BasicBlock* GetUnwindBasicBlock();
3105e869b6560f918837cc6be3a50234deb2be46385TDYa
3115e869b6560f918837cc6be3a50234deb2be46385TDYa  void EmitGuard_ExceptionLandingPad(uint32_t dex_pc);
3125e869b6560f918837cc6be3a50234deb2be46385TDYa
3135e869b6560f918837cc6be3a50234deb2be46385TDYa  void EmitBranchExceptionLandingPad(uint32_t dex_pc);
3145e869b6560f918837cc6be3a50234deb2be46385TDYa
31575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  //----------------------------------------------------------------------------
31675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  // Expand Arithmetic Helper Intrinsics
31775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  //----------------------------------------------------------------------------
31875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
31975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  llvm::Value* Expand_IntegerShift(llvm::Value* src1_value,
32075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                                   llvm::Value* src2_value,
32175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                                   IntegerShiftKind kind,
32275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                                   JType op_jty);
32375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
32421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao public:
32521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  static char ID;
32621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
32721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  GBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb)
32821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      : llvm::FunctionPass(ID), intrinsic_helper_(intrinsic_helper), irb_(irb),
329e5b8f8b3eaef9871b8cea42cc8e98548754ac051Logan Chien        context_(irb.getContext()), rtb_(irb.Runtime()),
3308e950c117975d23f50ed7e32ca5db01a813c25d0TDYa        shadow_frame_(NULL), old_shadow_frame_(NULL),
331bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao        compiler_(NULL), dex_file_(NULL), code_item_(NULL),
33267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien        oat_compilation_unit_(NULL), method_idx_(-1u), func_(NULL),
33367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien        changed_(false)
33421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  { }
33521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
336bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  GBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb,
337920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa                  art::Compiler* compiler, art::OatCompilationUnit* oat_compilation_unit)
338bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao      : llvm::FunctionPass(ID), intrinsic_helper_(intrinsic_helper), irb_(irb),
339bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao        context_(irb.getContext()), rtb_(irb.Runtime()),
3408e950c117975d23f50ed7e32ca5db01a813c25d0TDYa        shadow_frame_(NULL), old_shadow_frame_(NULL),
341bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao        compiler_(compiler),
342bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao        dex_file_(oat_compilation_unit->GetDexFile()),
343bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao        code_item_(oat_compilation_unit->GetCodeItem()),
344bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao        oat_compilation_unit_(oat_compilation_unit),
345bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao        method_idx_(oat_compilation_unit->GetDexMethodIndex()),
346bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao        func_(NULL), changed_(false)
347bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  { }
348bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao
34921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  bool runOnFunction(llvm::Function& func);
35021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
35121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao private:
35267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  void InsertStackOverflowCheck(llvm::Function& func);
35321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
35421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* ExpandIntrinsic(IntrinsicHelper::IntrinsicId intr_id,
35521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                               llvm::CallInst& call_inst);
35621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
35721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao};
35821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
35921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaochar GBCExpanderPass::ID = 0;
36021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
36121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaobool GBCExpanderPass::runOnFunction(llvm::Function& func) {
362b672d1e48b6e02bb69c7cd9bcfa7509c81514c07TDYa  // Runtime support or stub
363b672d1e48b6e02bb69c7cd9bcfa7509c81514c07TDYa  if (func.getName().startswith("art_") || func.getName().startswith("Art")) {
364b672d1e48b6e02bb69c7cd9bcfa7509c81514c07TDYa    return false;
365b672d1e48b6e02bb69c7cd9bcfa7509c81514c07TDYa  }
36621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
36767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  // Setup rewrite context
36867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  shadow_frame_ = NULL;
36967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  old_shadow_frame_ = NULL;
37067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  func_ = &func;
37167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  changed_ = false; // Assume unchanged
37221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
373bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  basic_blocks_.resize(code_item_->insns_size_in_code_units_);
374bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  basic_block_landing_pads_.resize(code_item_->tries_size_, NULL);
375bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  basic_block_unwind_ = NULL;
376bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  for (llvm::Function::iterator bb_iter = func_->begin(), bb_end = func_->end();
377bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao       bb_iter != bb_end;
378bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao       ++bb_iter) {
379bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao    if (bb_iter->begin()->getMetadata("DexOff") == NULL) {
380bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao      continue;
381bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao    }
382bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao    uint32_t dex_pc = LV2UInt(bb_iter->begin()->getMetadata("DexOff")->getOperand(0));
383bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao    basic_blocks_[dex_pc] = bb_iter;
384bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  }
385bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao
38667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  // Insert stack overflow check
38767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  InsertStackOverflowCheck(func); // TODO: Use intrinsic.
38821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
38967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  // Rewrite the intrinsics
39067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  RewriteFunction();
39121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
39267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  VERIFY_LLVM_FUNCTION(func);
39321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
39467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  return changed_;
39567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien}
39667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
39767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chienvoid GBCExpanderPass::RewriteBasicBlock(llvm::BasicBlock* original_block) {
39867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  llvm::BasicBlock* curr_basic_block = original_block;
39967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
40067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  llvm::BasicBlock::iterator inst_iter = original_block->begin();
40167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  llvm::BasicBlock::iterator inst_end = original_block->end();
40267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
40367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  while (inst_iter != inst_end) {
40467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    llvm::CallInst* call_inst = llvm::dyn_cast<llvm::CallInst>(inst_iter);
40567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    IntrinsicHelper::IntrinsicId intr_id = IntrinsicHelper::UnknownId;
40667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
40767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    if (call_inst) {
40867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien      llvm::Function* callee_func = call_inst->getCalledFunction();
40967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien      intr_id = intrinsic_helper_.GetIntrinsicId(callee_func);
41021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
41121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
41267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    if (intr_id == IntrinsicHelper::UnknownId) {
41367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien      // This is not intrinsic call.  Skip this instruction.
41467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien      ++inst_iter;
41567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien      continue;
41667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    }
41721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
41867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    // Rewrite the intrinsic and change the function
41967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    changed_ = true;
42067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    irb_.SetInsertPoint(inst_iter);
42121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
42267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    // Expand the intrinsic
42367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    if (llvm::Value* new_value = ExpandIntrinsic(intr_id, *call_inst)) {
42467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien      inst_iter->replaceAllUsesWith(new_value);
42567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    }
42621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
42767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    // Remove the old intrinsic call instruction
42867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    llvm::BasicBlock::iterator old_inst = inst_iter++;
42967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    old_inst->eraseFromParent();
43067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
43167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    // Splice the instruction to the new basic block
43267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    llvm::BasicBlock* next_basic_block = irb_.GetInsertBlock();
43367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    if (next_basic_block != curr_basic_block) {
43467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien      next_basic_block->getInstList().splice(
43567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien          irb_.GetInsertPoint(), curr_basic_block->getInstList(),
43667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien          inst_iter, inst_end);
43767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien      curr_basic_block = next_basic_block;
43867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien      inst_end = curr_basic_block->end();
43967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    }
44067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  }
44167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien}
44221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
44321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
44467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chienvoid GBCExpanderPass::RewriteFunction() {
44567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  size_t num_basic_blocks = func_->getBasicBlockList().size();
44667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  // NOTE: We are not using (bb_iter != bb_end) as the for-loop condition,
44767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  // because we will create new basic block while expanding the intrinsics.
44867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  // We only want to iterate through the input basic blocks.
44921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
450aa55887fd30484a77e7775dfbcddbee883ce6380TDYa  landing_pad_phi_mapping_.clear();
451aa55887fd30484a77e7775dfbcddbee883ce6380TDYa
45267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  for (llvm::Function::iterator bb_iter = func_->begin();
45367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien       num_basic_blocks > 0; ++bb_iter, --num_basic_blocks) {
454627d8c4ae50f22f628fe6a768f2924ee7e0029deShih-wei Liao    // Set insert point to current basic block.
455627d8c4ae50f22f628fe6a768f2924ee7e0029deShih-wei Liao    irb_.SetInsertPoint(bb_iter);
45667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
45755e5e6c5702e3f1f68bd83ae741af769740d9a74TDYa    current_bb_ = bb_iter;
458aa55887fd30484a77e7775dfbcddbee883ce6380TDYa
45967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    // Rewrite the basic block
46067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    RewriteBasicBlock(bb_iter);
46167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
46267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    // Update the phi-instructions in the successor basic block
46367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    llvm::BasicBlock* last_block = irb_.GetInsertBlock();
46467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    if (last_block != bb_iter) {
46567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien      UpdatePhiInstruction(bb_iter, last_block);
46621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
46767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  }
468aa55887fd30484a77e7775dfbcddbee883ce6380TDYa
469aa55887fd30484a77e7775dfbcddbee883ce6380TDYa  typedef std::map<llvm::PHINode*, llvm::PHINode*> HandlerPHIMap;
470aa55887fd30484a77e7775dfbcddbee883ce6380TDYa  HandlerPHIMap handler_phi;
471aa55887fd30484a77e7775dfbcddbee883ce6380TDYa  // Iterate every used landing pad basic block
472aa55887fd30484a77e7775dfbcddbee883ce6380TDYa  for (size_t i = 0, ei = basic_block_landing_pads_.size(); i != ei; ++i) {
473aa55887fd30484a77e7775dfbcddbee883ce6380TDYa    llvm::BasicBlock* lbb = basic_block_landing_pads_[i];
474aa55887fd30484a77e7775dfbcddbee883ce6380TDYa    if (lbb == NULL) {
475aa55887fd30484a77e7775dfbcddbee883ce6380TDYa      continue;
476aa55887fd30484a77e7775dfbcddbee883ce6380TDYa    }
477aa55887fd30484a77e7775dfbcddbee883ce6380TDYa
478aa55887fd30484a77e7775dfbcddbee883ce6380TDYa    llvm::TerminatorInst* term_inst = lbb->getTerminator();
479aa55887fd30484a77e7775dfbcddbee883ce6380TDYa    std::vector<std::pair<llvm::BasicBlock*, llvm::BasicBlock*> >& rewrite_pair
480aa55887fd30484a77e7775dfbcddbee883ce6380TDYa        = landing_pad_phi_mapping_[lbb];
481aa55887fd30484a77e7775dfbcddbee883ce6380TDYa    irb_.SetInsertPoint(lbb->begin());
482aa55887fd30484a77e7775dfbcddbee883ce6380TDYa
483aa55887fd30484a77e7775dfbcddbee883ce6380TDYa    // Iterate every succeeding basic block (catch block)
484aa55887fd30484a77e7775dfbcddbee883ce6380TDYa    for (unsigned succ_iter = 0, succ_end = term_inst->getNumSuccessors();
485aa55887fd30484a77e7775dfbcddbee883ce6380TDYa         succ_iter != succ_end; ++succ_iter) {
486aa55887fd30484a77e7775dfbcddbee883ce6380TDYa      llvm::BasicBlock* succ_basic_block = term_inst->getSuccessor(succ_iter);
487aa55887fd30484a77e7775dfbcddbee883ce6380TDYa
488aa55887fd30484a77e7775dfbcddbee883ce6380TDYa      // Iterate every phi instructions in the succeeding basic block
489aa55887fd30484a77e7775dfbcddbee883ce6380TDYa      for (llvm::BasicBlock::iterator
490aa55887fd30484a77e7775dfbcddbee883ce6380TDYa           inst_iter = succ_basic_block->begin(),
491aa55887fd30484a77e7775dfbcddbee883ce6380TDYa           inst_end = succ_basic_block->end();
492aa55887fd30484a77e7775dfbcddbee883ce6380TDYa           inst_iter != inst_end; ++inst_iter) {
493aa55887fd30484a77e7775dfbcddbee883ce6380TDYa        llvm::PHINode *phi = llvm::dyn_cast<llvm::PHINode>(inst_iter);
494aa55887fd30484a77e7775dfbcddbee883ce6380TDYa
495aa55887fd30484a77e7775dfbcddbee883ce6380TDYa        if (!phi) {
496aa55887fd30484a77e7775dfbcddbee883ce6380TDYa          break; // Meet non-phi instruction.  Done.
497aa55887fd30484a77e7775dfbcddbee883ce6380TDYa        }
498aa55887fd30484a77e7775dfbcddbee883ce6380TDYa
499aa55887fd30484a77e7775dfbcddbee883ce6380TDYa        if (handler_phi[phi] == NULL) {
500aa55887fd30484a77e7775dfbcddbee883ce6380TDYa          handler_phi[phi] = llvm::PHINode::Create(phi->getType(), 1);
501aa55887fd30484a77e7775dfbcddbee883ce6380TDYa        }
502aa55887fd30484a77e7775dfbcddbee883ce6380TDYa
503aa55887fd30484a77e7775dfbcddbee883ce6380TDYa        // Create new_phi in landing pad
504aa55887fd30484a77e7775dfbcddbee883ce6380TDYa        llvm::PHINode* new_phi = irb_.CreatePHI(phi->getType(), rewrite_pair.size());
505aa55887fd30484a77e7775dfbcddbee883ce6380TDYa        // Insert all incoming value into new_phi by rewrite_pair
506aa55887fd30484a77e7775dfbcddbee883ce6380TDYa        for (size_t j = 0, ej = rewrite_pair.size(); j != ej; ++j) {
507aa55887fd30484a77e7775dfbcddbee883ce6380TDYa          llvm::BasicBlock* old_bb = rewrite_pair[j].first;
508aa55887fd30484a77e7775dfbcddbee883ce6380TDYa          llvm::BasicBlock* new_bb = rewrite_pair[j].second;
509aa55887fd30484a77e7775dfbcddbee883ce6380TDYa          new_phi->addIncoming(phi->getIncomingValueForBlock(old_bb), new_bb);
510aa55887fd30484a77e7775dfbcddbee883ce6380TDYa        }
511aa55887fd30484a77e7775dfbcddbee883ce6380TDYa        // Delete all incoming value from phi by rewrite_pair
512aa55887fd30484a77e7775dfbcddbee883ce6380TDYa        for (size_t j = 0, ej = rewrite_pair.size(); j != ej; ++j) {
513aa55887fd30484a77e7775dfbcddbee883ce6380TDYa          llvm::BasicBlock* old_bb = rewrite_pair[j].first;
514aa55887fd30484a77e7775dfbcddbee883ce6380TDYa          int old_bb_idx = phi->getBasicBlockIndex(old_bb);
515aa55887fd30484a77e7775dfbcddbee883ce6380TDYa          if (old_bb_idx >= 0) {
516aa55887fd30484a77e7775dfbcddbee883ce6380TDYa            phi->removeIncomingValue(old_bb_idx, false);
517aa55887fd30484a77e7775dfbcddbee883ce6380TDYa          }
518aa55887fd30484a77e7775dfbcddbee883ce6380TDYa        }
519aa55887fd30484a77e7775dfbcddbee883ce6380TDYa        // Insert new_phi into new handler phi
520aa55887fd30484a77e7775dfbcddbee883ce6380TDYa        handler_phi[phi]->addIncoming(new_phi, lbb);
521aa55887fd30484a77e7775dfbcddbee883ce6380TDYa      }
522aa55887fd30484a77e7775dfbcddbee883ce6380TDYa    }
523aa55887fd30484a77e7775dfbcddbee883ce6380TDYa  }
524aa55887fd30484a77e7775dfbcddbee883ce6380TDYa
525aa55887fd30484a77e7775dfbcddbee883ce6380TDYa  // Replace all handler phi
526aa55887fd30484a77e7775dfbcddbee883ce6380TDYa  // We can't just use the old handler phi, because some exception edges will disappear after we
527aa55887fd30484a77e7775dfbcddbee883ce6380TDYa  // compute fast-path.
528aa55887fd30484a77e7775dfbcddbee883ce6380TDYa  for (HandlerPHIMap::iterator it = handler_phi.begin(); it != handler_phi.end(); ++it) {
529aa55887fd30484a77e7775dfbcddbee883ce6380TDYa    llvm::PHINode* old_phi = it->first;
530aa55887fd30484a77e7775dfbcddbee883ce6380TDYa    llvm::PHINode* new_phi = it->second;
531aa55887fd30484a77e7775dfbcddbee883ce6380TDYa    new_phi->insertBefore(old_phi);
532aa55887fd30484a77e7775dfbcddbee883ce6380TDYa    old_phi->replaceAllUsesWith(new_phi);
533aa55887fd30484a77e7775dfbcddbee883ce6380TDYa    old_phi->eraseFromParent();
534aa55887fd30484a77e7775dfbcddbee883ce6380TDYa  }
53567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien}
53621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
53767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chienvoid GBCExpanderPass::UpdatePhiInstruction(llvm::BasicBlock* old_basic_block,
53867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien                                           llvm::BasicBlock* new_basic_block) {
53967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  llvm::TerminatorInst* term_inst = new_basic_block->getTerminator();
54067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
54167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  if (!term_inst) {
54267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    return; // No terminating instruction in new_basic_block.  Nothing to do.
54321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  }
54421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
54567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  // Iterate every succeeding basic block
54667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  for (unsigned succ_iter = 0, succ_end = term_inst->getNumSuccessors();
54767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien       succ_iter != succ_end; ++succ_iter) {
54867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    llvm::BasicBlock* succ_basic_block = term_inst->getSuccessor(succ_iter);
54967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
55067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    // Iterate every phi instructions in the succeeding basic block
55167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    for (llvm::BasicBlock::iterator
55267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien         inst_iter = succ_basic_block->begin(),
55367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien         inst_end = succ_basic_block->end();
55467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien         inst_iter != inst_end; ++inst_iter) {
55567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien      llvm::PHINode *phi = llvm::dyn_cast<llvm::PHINode>(inst_iter);
55621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
55767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien      if (!phi) {
55867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien        break; // Meet non-phi instruction.  Done.
55967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien      }
56067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
56167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien      // Update the incoming block of this phi instruction
56267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien      for (llvm::PHINode::block_iterator
56367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien           ibb_iter = phi->block_begin(), ibb_end = phi->block_end();
56467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien           ibb_iter != ibb_end; ++ibb_iter) {
56567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien        if (*ibb_iter == old_basic_block) {
56667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien          *ibb_iter = new_basic_block;
56767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien        }
56821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      }
56921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
57021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  }
57121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
57221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
57321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::ExpandToRuntime(runtime_support::RuntimeId rt,
57421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                              llvm::CallInst& inst) {
57521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Some GBC intrinsic can directly replace with IBC runtime. "Directly" means
57621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // the arguments passed to the GBC intrinsic are as the same as IBC runtime
57721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // function, therefore only called function is needed to change.
57821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  unsigned num_args = inst.getNumArgOperands();
57921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
58021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  if (num_args <= 0) {
58121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    return irb_.CreateCall(irb_.GetRuntime(rt));
58221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  } else {
58321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    std::vector<llvm::Value*> args;
58421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    for (unsigned i = 0; i < num_args; i++) {
58521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      args.push_back(inst.getArgOperand(i));
58621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
58721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
58821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    return irb_.CreateCall(irb_.GetRuntime(rt), args);
58921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  }
59021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
59121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
59267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chienvoid
59321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::EmitStackOverflowCheck(llvm::Instruction* first_non_alloca) {
59421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Function* func = first_non_alloca->getParent()->getParent();
59521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Module* module = func->getParent();
59621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
59721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Call llvm intrinsic function to get frame address.
59821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Function* frameaddress =
59921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      llvm::Intrinsic::getDeclaration(module, llvm::Intrinsic::frameaddress);
60021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
60121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // The type of llvm::frameaddress is: i8* @llvm.frameaddress(i32)
60221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* frame_address = irb_.CreateCall(frameaddress, irb_.getInt32(0));
60321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
60421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Cast i8* to int
60521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  frame_address = irb_.CreatePtrToInt(frame_address, irb_.getPtrEquivIntTy());
60621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
60721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Get thread.stack_end_
60821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* stack_end =
609920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    irb_.Runtime().EmitLoadFromThreadOffset(art::Thread::StackEndOffset().Int32Value(),
61021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                            irb_.getPtrEquivIntTy(),
61121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                            kTBAARuntimeInfo);
61221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
61321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Check the frame address < thread.stack_end_ ?
61421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* is_stack_overflow = irb_.CreateICmpULT(frame_address, stack_end);
61521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
61621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::BasicBlock* block_exception =
61721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      llvm::BasicBlock::Create(context_, "stack_overflow", func);
61821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
61921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::BasicBlock* block_continue =
62021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      llvm::BasicBlock::Create(context_, "stack_overflow_cont", func);
62121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
62221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  irb_.CreateCondBr(is_stack_overflow, block_exception, block_continue, kUnlikely);
62321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
62421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // If stack overflow, throw exception.
62521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  irb_.SetInsertPoint(block_exception);
62621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  irb_.CreateCall(irb_.GetRuntime(runtime_support::ThrowStackOverflowException));
62721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
62821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Unwind.
62921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Type* ret_type = func->getReturnType();
63021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  if (ret_type->isVoidTy()) {
63121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    irb_.CreateRetVoid();
63221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  } else {
63321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    // The return value is ignored when there's an exception. MethodCompiler
63421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    // returns zero value under the the corresponding return type  in this case.
63521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    // GBCExpander returns LLVM undef value here for brevity
63621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    irb_.CreateRet(llvm::UndefValue::get(ret_type));
63721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  }
63821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
63921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  irb_.SetInsertPoint(block_continue);
64021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
64121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
642920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYallvm::Value* GBCExpanderPass::EmitLoadDexCacheAddr(art::MemberOffset offset) {
64321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
64421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
64521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return irb_.LoadFromObjectOffset(method_object_addr,
64621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                   offset.Int32Value(),
64721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                   irb_.getJObjectTy(),
64821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                   kTBAAConstJObject);
64921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
65021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
65121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value*
65221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::EmitLoadDexCacheStaticStorageFieldAddr(uint32_t type_idx) {
65321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* static_storage_dex_cache_addr =
65498573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers    EmitLoadDexCacheAddr(art::mirror::AbstractMethod::DexCacheInitializedStaticStorageOffset());
65521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
65621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* type_idx_value = irb_.getPtrEquivInt(type_idx);
65721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
65821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return EmitArrayGEP(static_storage_dex_cache_addr, type_idx_value, kObject);
65921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
66021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
66121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value*
66221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::EmitLoadDexCacheResolvedTypeFieldAddr(uint32_t type_idx) {
66321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* resolved_type_dex_cache_addr =
66498573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers    EmitLoadDexCacheAddr(art::mirror::AbstractMethod::DexCacheResolvedTypesOffset());
66521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
66621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* type_idx_value = irb_.getPtrEquivInt(type_idx);
66721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
66821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return EmitArrayGEP(resolved_type_dex_cache_addr, type_idx_value, kObject);
66921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
67021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
67121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::
67221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoEmitLoadDexCacheResolvedMethodFieldAddr(uint32_t method_idx) {
67321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* resolved_method_dex_cache_addr =
67498573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers    EmitLoadDexCacheAddr(art::mirror::AbstractMethod::DexCacheResolvedMethodsOffset());
67521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
67621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* method_idx_value = irb_.getPtrEquivInt(method_idx);
67721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
67821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return EmitArrayGEP(resolved_method_dex_cache_addr, method_idx_value, kObject);
67921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
68021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
68121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::
68221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoEmitLoadDexCacheStringFieldAddr(uint32_t string_idx) {
68321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* string_dex_cache_addr =
68498573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers    EmitLoadDexCacheAddr(art::mirror::AbstractMethod::DexCacheStringsOffset());
68521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
68621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* string_idx_value = irb_.getPtrEquivInt(string_idx);
68721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
68821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return EmitArrayGEP(string_dex_cache_addr, string_idx_value, kObject);
68921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
69021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
69121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::EmitLoadMethodObjectAddr() {
69221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Function* parent_func = irb_.GetInsertBlock()->getParent();
69321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return parent_func->arg_begin();
69421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
69521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
69621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::EmitLoadArrayLength(llvm::Value* array) {
69721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Load array length
69821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return irb_.LoadFromObjectOffset(array,
69998573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers                                   art::mirror::Array::LengthOffset().Int32Value(),
70021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                   irb_.getJIntTy(),
70121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                   kTBAAConstJObject);
70221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
70321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
70421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
70521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value*
70621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::EmitLoadSDCalleeMethodObjectAddr(uint32_t callee_method_idx) {
70721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* callee_method_object_field_addr =
70821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    EmitLoadDexCacheResolvedMethodFieldAddr(callee_method_idx);
70921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
710ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  return irb_.CreateLoad(callee_method_object_field_addr, kTBAARuntimeInfo);
71121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
71221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
71321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::
71421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoEmitLoadVirtualCalleeMethodObjectAddr(int vtable_idx, llvm::Value* this_addr) {
71521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Load class object of *this* pointer
71621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* class_object_addr =
71721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    irb_.LoadFromObjectOffset(this_addr,
71898573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers                              art::mirror::Object::ClassOffset().Int32Value(),
71921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                              irb_.getJObjectTy(),
72021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                              kTBAAConstJObject);
72121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
72221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Load vtable address
72321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* vtable_addr =
72421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    irb_.LoadFromObjectOffset(class_object_addr,
72598573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers                              art::mirror::Class::VTableOffset().Int32Value(),
72621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                              irb_.getJObjectTy(),
72721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                              kTBAAConstJObject);
72821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
72921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Load callee method object
73021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* vtable_idx_value =
73121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    irb_.getPtrEquivInt(static_cast<uint64_t>(vtable_idx));
73221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
73321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* method_field_addr =
73421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    EmitArrayGEP(vtable_addr, vtable_idx_value, kObject);
73521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
73621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return irb_.CreateLoad(method_field_addr, kTBAAConstJObject);
73721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
73821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
73921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao// Emit Array GetElementPtr
74021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::EmitArrayGEP(llvm::Value* array_addr,
74121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                           llvm::Value* index_value,
74221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                           JType elem_jty) {
74321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
74421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  int data_offset;
74521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  if (elem_jty == kLong || elem_jty == kDouble ||
74698573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers      (elem_jty == kObject && sizeof(uint64_t) == sizeof(art::mirror::Object*))) {
74798573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers    data_offset = art::mirror::Array::DataOffset(sizeof(int64_t)).Int32Value();
74821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  } else {
74998573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers    data_offset = art::mirror::Array::DataOffset(sizeof(int32_t)).Int32Value();
75021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  }
75121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
75221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Constant* data_offset_value =
75321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    irb_.getPtrEquivInt(data_offset);
75421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
75521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Type* elem_type = irb_.getJType(elem_jty, kArray);
75621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
75721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* array_data_addr =
75821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    irb_.CreatePtrDisp(array_addr, data_offset_value,
75921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                       elem_type->getPointerTo());
76021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
76121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return irb_.CreateGEP(array_data_addr, index_value);
76221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
76321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
76421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_TestSuspend(llvm::CallInst& call_inst) {
765ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
766ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa
767ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  llvm::Value* suspend_count =
768ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa      irb_.Runtime().EmitLoadFromThreadOffset(art::Thread::ThreadFlagsOffset().Int32Value(),
769ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa                                              irb_.getInt16Ty(),
770ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa                                              kTBAARuntimeInfo);
771ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  llvm::Value* is_suspend = irb_.CreateICmpNE(suspend_count, irb_.getInt16(0));
772ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa
773ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  llvm::BasicBlock* basic_block_suspend = CreateBasicBlockWithDexPC(dex_pc, "suspend");
774ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  llvm::BasicBlock* basic_block_cont = CreateBasicBlockWithDexPC(dex_pc, "suspend_cont");
775ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa
776ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  irb_.CreateCondBr(is_suspend, basic_block_suspend, basic_block_cont, kUnlikely);
777ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa
778ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  irb_.SetInsertPoint(basic_block_suspend);
779ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  if (dex_pc != art::DexFile::kDexNoIndex) {
780ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa    EmitUpdateDexPC(dex_pc);
781ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  }
78221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  irb_.Runtime().EmitTestSuspend();
783ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  irb_.CreateBr(basic_block_cont);
784ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa
785ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  irb_.SetInsertPoint(basic_block_cont);
78621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return;
78721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
78821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
7899a129457c233b653c7a8f65c963509267252b0a7TDYavoid GBCExpanderPass::Expand_MarkGCCard(llvm::CallInst& call_inst) {
7909a129457c233b653c7a8f65c963509267252b0a7TDYa  irb_.Runtime().EmitMarkGCCard(call_inst.getArgOperand(0), call_inst.getArgOperand(1));
7919a129457c233b653c7a8f65c963509267252b0a7TDYa  return;
7929a129457c233b653c7a8f65c963509267252b0a7TDYa}
7939a129457c233b653c7a8f65c963509267252b0a7TDYa
79421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value*
79521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::Expand_LoadStringFromDexCache(llvm::Value* string_idx_value) {
79621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  uint32_t string_idx =
79721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    llvm::cast<llvm::ConstantInt>(string_idx_value)->getZExtValue();
79821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
79921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* string_field_addr = EmitLoadDexCacheStringFieldAddr(string_idx);
80021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
801ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  return irb_.CreateLoad(string_field_addr, kTBAARuntimeInfo);
80221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
80321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
80421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value*
80521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::Expand_LoadTypeFromDexCache(llvm::Value* type_idx_value) {
80621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  uint32_t type_idx =
80721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    llvm::cast<llvm::ConstantInt>(type_idx_value)->getZExtValue();
80821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
80921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* type_field_addr =
81021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    EmitLoadDexCacheResolvedTypeFieldAddr(type_idx);
81121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
812ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  return irb_.CreateLoad(type_field_addr, kTBAARuntimeInfo);
81321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
81421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
81521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_LockObject(llvm::Value* obj) {
81621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  rtb_.EmitLockObject(obj);
81721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return;
81821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
81921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
82021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_UnlockObject(llvm::Value* obj) {
82121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  rtb_.EmitUnlockObject(obj);
82221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return;
82321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
82421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
82521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::Expand_ArrayGet(llvm::Value* array_addr,
82621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                              llvm::Value* index_value,
82721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                              JType elem_jty) {
82821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* array_elem_addr =
82921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    EmitArrayGEP(array_addr, index_value, elem_jty);
83021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
83121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return irb_.CreateLoad(array_elem_addr, kTBAAHeapArray, elem_jty);
83221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
83321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
83421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_ArrayPut(llvm::Value* new_value,
83521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                      llvm::Value* array_addr,
83621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                      llvm::Value* index_value,
83721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                      JType elem_jty) {
83821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* array_elem_addr =
83921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    EmitArrayGEP(array_addr, index_value, elem_jty);
84021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
84121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  irb_.CreateStore(new_value, array_elem_addr, kTBAAHeapArray, elem_jty);
84221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
84321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return;
84421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
84521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
84621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_FilledNewArray(llvm::CallInst& call_inst) {
84721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Most of the codes refer to MethodCompiler::EmitInsn_FilledNewArray
84821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* array = call_inst.getArgOperand(0);
84921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
85021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  uint32_t element_jty =
85121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    llvm::cast<llvm::ConstantInt>(call_inst.getArgOperand(1))->getZExtValue();
85221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
85321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  DCHECK(call_inst.getNumArgOperands() > 2);
85421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  unsigned num_elements = (call_inst.getNumArgOperands() - 2);
85521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
85621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  bool is_elem_int_ty = (static_cast<JType>(element_jty) == kInt);
85721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
85821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  uint32_t alignment;
85921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Constant* elem_size;
86021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::PointerType* field_type;
86121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
86221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // NOTE: Currently filled-new-array only supports 'L', '[', and 'I'
86321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // as the element, thus we are only checking 2 cases: primitive int and
86421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // non-primitive type.
86521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  if (is_elem_int_ty) {
86621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    alignment = sizeof(int32_t);
86721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    elem_size = irb_.getPtrEquivInt(sizeof(int32_t));
86821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    field_type = irb_.getJIntTy()->getPointerTo();
86921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  } else {
87021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    alignment = irb_.getSizeOfPtrEquivInt();
87121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    elem_size = irb_.getSizeOfPtrEquivIntValue();
87221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    field_type = irb_.getJObjectTy()->getPointerTo();
87321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  }
87421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
87521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* data_field_offset =
87698573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers    irb_.getPtrEquivInt(art::mirror::Array::DataOffset(alignment).Int32Value());
87721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
87821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* data_field_addr =
87921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    irb_.CreatePtrDisp(array, data_field_offset, field_type);
88021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
88121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  for (unsigned i = 0; i < num_elements; ++i) {
88221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    // Values to fill the array begin at the 3rd argument
88321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    llvm::Value* reg_value = call_inst.getArgOperand(2 + i);
88421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
88521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    irb_.CreateStore(reg_value, data_field_addr, kTBAAHeapArray);
88621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
88721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    data_field_addr =
88821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      irb_.CreatePtrDisp(data_field_addr, elem_size, field_type);
88921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  }
89021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
89121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return;
89221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
89321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
89421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::Expand_IGetFast(llvm::Value* field_offset_value,
89521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                              llvm::Value* /*is_volatile_value*/,
89621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                              llvm::Value* object_addr,
89721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                              JType field_jty) {
89821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  int field_offset =
89921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue();
90021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
90121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  DCHECK_GE(field_offset, 0);
90221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
90321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::PointerType* field_type =
90421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    irb_.getJType(field_jty, kField)->getPointerTo();
90521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
90621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  field_offset_value = irb_.getPtrEquivInt(field_offset);
90721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
90821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* field_addr =
90921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    irb_.CreatePtrDisp(object_addr, field_offset_value, field_type);
91021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
91121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // TODO: Check is_volatile.  We need to generate atomic load instruction
91221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // when is_volatile is true.
91321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return irb_.CreateLoad(field_addr, kTBAAHeapInstance, field_jty);
91421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
91521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
91621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_IPutFast(llvm::Value* field_offset_value,
91721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                      llvm::Value* /* is_volatile_value */,
91821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                      llvm::Value* object_addr,
91921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                      llvm::Value* new_value,
92021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                      JType field_jty) {
92121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  int field_offset =
92221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue();
92321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
92421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  DCHECK_GE(field_offset, 0);
92521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
92621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::PointerType* field_type =
92721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    irb_.getJType(field_jty, kField)->getPointerTo();
92821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
92921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  field_offset_value = irb_.getPtrEquivInt(field_offset);
93021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
93121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* field_addr =
93221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    irb_.CreatePtrDisp(object_addr, field_offset_value, field_type);
93321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
93421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // TODO: Check is_volatile.  We need to generate atomic store instruction
93521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // when is_volatile is true.
93621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  irb_.CreateStore(new_value, field_addr, kTBAAHeapInstance, field_jty);
93721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
93821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return;
93921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
94021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
94121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::Expand_SGetFast(llvm::Value* static_storage_addr,
94221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                              llvm::Value* field_offset_value,
94321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                              llvm::Value* /*is_volatile_value*/,
94421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                              JType field_jty) {
94521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  int field_offset =
94621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue();
94721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
94821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  DCHECK_GE(field_offset, 0);
94921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
95021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset);
95121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
95221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* static_field_addr =
95321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value,
95421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                       irb_.getJType(field_jty, kField)->getPointerTo());
95521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
95621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // TODO: Check is_volatile.  We need to generate atomic store instruction
95721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // when is_volatile is true.
95821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return irb_.CreateLoad(static_field_addr, kTBAAHeapStatic, field_jty);
95921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
96021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
96121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_SPutFast(llvm::Value* static_storage_addr,
96221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                      llvm::Value* field_offset_value,
96321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                      llvm::Value* /* is_volatile_value */,
96421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                      llvm::Value* new_value,
96521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                      JType field_jty) {
96621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  int field_offset =
96721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue();
96821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
96921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  DCHECK_GE(field_offset, 0);
97021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
97121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset);
97221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
97321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* static_field_addr =
97421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value,
97521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                       irb_.getJType(field_jty, kField)->getPointerTo());
97621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
97721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // TODO: Check is_volatile.  We need to generate atomic store instruction
97821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // when is_volatile is true.
97921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  irb_.CreateStore(new_value, static_field_addr, kTBAAHeapStatic, field_jty);
98021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
98121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return;
98221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
98321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
98421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value*
98521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::Expand_LoadDeclaringClassSSB(llvm::Value* method_object_addr) {
98621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return irb_.LoadFromObjectOffset(method_object_addr,
98798573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers                                   art::mirror::AbstractMethod::DeclaringClassOffset().Int32Value(),
98821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                   irb_.getJObjectTy(),
98921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                   kTBAAConstJObject);
99021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
99121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
99221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value*
99321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::Expand_LoadClassSSBFromDexCache(llvm::Value* type_idx_value) {
99421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  uint32_t type_idx =
99521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    llvm::cast<llvm::ConstantInt>(type_idx_value)->getZExtValue();
99621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
99721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* storage_field_addr =
99821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    EmitLoadDexCacheStaticStorageFieldAddr(type_idx);
99921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
1000ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  return irb_.CreateLoad(storage_field_addr, kTBAARuntimeInfo);
100121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
100221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
100321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value*
100421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::Expand_GetSDCalleeMethodObjAddrFast(llvm::Value* callee_method_idx_value) {
100521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  uint32_t callee_method_idx =
100621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    llvm::cast<llvm::ConstantInt>(callee_method_idx_value)->getZExtValue();
100721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
100821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return EmitLoadSDCalleeMethodObjectAddr(callee_method_idx);
100921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
101021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
101121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::Expand_GetVirtualCalleeMethodObjAddrFast(
101221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    llvm::Value* vtable_idx_value,
101321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    llvm::Value* this_addr) {
101421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  int vtable_idx =
101521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    llvm::cast<llvm::ConstantInt>(vtable_idx_value)->getSExtValue();
101621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
101721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return EmitLoadVirtualCalleeMethodObjectAddr(vtable_idx, this_addr);
101821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
101921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
102021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::Expand_Invoke(llvm::CallInst& call_inst) {
102121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Most of the codes refer to MethodCompiler::EmitInsn_Invoke
102221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* callee_method_object_addr = call_inst.getArgOperand(0);
102321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  unsigned num_args = call_inst.getNumArgOperands();
102421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Type* ret_type = call_inst.getType();
102521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
102621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Determine the function type of the callee method
102721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  std::vector<llvm::Type*> args_type;
102821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  std::vector<llvm::Value*> args;
102921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  for (unsigned i = 0; i < num_args; i++) {
103021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    args.push_back(call_inst.getArgOperand(i));
103121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    args_type.push_back(args[i]->getType());
103221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  }
103321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
103421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::FunctionType* callee_method_type =
103521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    llvm::FunctionType::get(ret_type, args_type, false);
103621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
103721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* code_addr =
103821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    irb_.LoadFromObjectOffset(callee_method_object_addr,
103998573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers                              art::mirror::AbstractMethod::GetCodeOffset().Int32Value(),
104021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                              callee_method_type->getPointerTo(),
1041ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa                              kTBAARuntimeInfo);
104221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
104321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Invoke callee
104421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* retval = irb_.CreateCall(code_addr, args);
104521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
104621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return retval;
104721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
104821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
10494ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYallvm::Value* GBCExpanderPass::Expand_DivRem(llvm::CallInst& call_inst,
105021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                            bool is_div, JType op_jty) {
10514ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa  llvm::Value* dividend = call_inst.getArgOperand(0);
10524ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa  llvm::Value* divisor = call_inst.getArgOperand(1);
10534ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
10544ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa  EmitGuard_DivZeroException(dex_pc, divisor, op_jty);
105521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Most of the codes refer to MethodCompiler::EmitIntDivRemResultComputation
105621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
105721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Check the special case: MININT / -1 = MININT
105821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // That case will cause overflow, which is undefined behavior in llvm.
105921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // So we check the divisor is -1 or not, if the divisor is -1, we do
106021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // the special path to avoid undefined behavior.
106121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Type* op_type = irb_.getJType(op_jty, kAccurate);
106221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* zero = irb_.getJZero(op_jty);
106321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* neg_one = llvm::ConstantInt::getSigned(op_type, -1);
106421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
10655e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::Function* parent = irb_.GetInsertBlock()->getParent();
106621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::BasicBlock* eq_neg_one = llvm::BasicBlock::Create(context_, "", parent);
106721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::BasicBlock* ne_neg_one = llvm::BasicBlock::Create(context_, "", parent);
106821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::BasicBlock* neg_one_cont =
106921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    llvm::BasicBlock::Create(context_, "", parent);
107021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
107121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* is_equal_neg_one = irb_.CreateICmpEQ(divisor, neg_one);
107221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  irb_.CreateCondBr(is_equal_neg_one, eq_neg_one, ne_neg_one, kUnlikely);
107321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
107421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // If divisor == -1
107521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  irb_.SetInsertPoint(eq_neg_one);
107621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* eq_result;
107721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  if (is_div) {
107821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    // We can just change from "dividend div -1" to "neg dividend". The sub
107921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    // don't care the sign/unsigned because of two's complement representation.
108021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    // And the behavior is what we want:
108121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    //  -(2^n)        (2^n)-1
108221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    //  MININT  < k <= MAXINT    ->     mul k -1  =  -k
108321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    //  MININT == k              ->     mul k -1  =   k
108421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    //
108521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    // LLVM use sub to represent 'neg'
108621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    eq_result = irb_.CreateSub(zero, dividend);
108721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  } else {
108821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    // Everything modulo -1 will be 0.
108921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    eq_result = zero;
109021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  }
109121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  irb_.CreateBr(neg_one_cont);
109221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
109321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // If divisor != -1, just do the division.
109421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  irb_.SetInsertPoint(ne_neg_one);
109521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* ne_result;
109621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  if (is_div) {
109721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    ne_result = irb_.CreateSDiv(dividend, divisor);
109821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  } else {
109921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    ne_result = irb_.CreateSRem(dividend, divisor);
110021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  }
110121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  irb_.CreateBr(neg_one_cont);
110221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
110321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  irb_.SetInsertPoint(neg_one_cont);
110421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::PHINode* result = irb_.CreatePHI(op_type, 2);
110521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  result->addIncoming(eq_result, eq_neg_one);
110621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  result->addIncoming(ne_result, ne_neg_one);
110721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
110821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return result;
110921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
111021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
1111ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYavoid GBCExpanderPass::Expand_AllocaShadowFrame(llvm::Value* num_vregs_value) {
111221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Most of the codes refer to MethodCompiler::EmitPrologueAllocShadowFrame and
111321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // MethodCompiler::EmitPushShadowFrame
11148e950c117975d23f50ed7e32ca5db01a813c25d0TDYa  uint16_t num_vregs =
11158e950c117975d23f50ed7e32ca5db01a813c25d0TDYa    llvm::cast<llvm::ConstantInt>(num_vregs_value)->getZExtValue();
111621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
111721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::StructType* shadow_frame_type =
1118ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa    irb_.getShadowFrameTy(num_vregs);
111921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
112021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  shadow_frame_ = irb_.CreateAlloca(shadow_frame_type);
112121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
112221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Alloca a pointer to old shadow frame
112321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  old_shadow_frame_ =
112421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    irb_.CreateAlloca(shadow_frame_type->getElementType(0)->getPointerTo());
112521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
112621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Push the shadow frame
112721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
112821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
112921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* shadow_frame_upcast =
113021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    irb_.CreateConstGEP2_32(shadow_frame_, 0, 0);
113121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
113221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  llvm::Value* result = rtb_.EmitPushShadowFrame(shadow_frame_upcast,
113321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                                 method_object_addr,
11348e950c117975d23f50ed7e32ca5db01a813c25d0TDYa                                                 num_vregs);
113521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
113621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  irb_.CreateStore(result, old_shadow_frame_, kTBAARegister);
113721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
113821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return;
113921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
114021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
11418e950c117975d23f50ed7e32ca5db01a813c25d0TDYavoid GBCExpanderPass::Expand_SetVReg(llvm::Value* entry_idx,
11428e950c117975d23f50ed7e32ca5db01a813c25d0TDYa                                     llvm::Value* value) {
11438e950c117975d23f50ed7e32ca5db01a813c25d0TDYa  DCHECK(shadow_frame_ != NULL);
11448e950c117975d23f50ed7e32ca5db01a813c25d0TDYa
11458e950c117975d23f50ed7e32ca5db01a813c25d0TDYa  llvm::Value* gep_index[] = {
11468e950c117975d23f50ed7e32ca5db01a813c25d0TDYa    irb_.getInt32(0), // No pointer displacement
1147ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa    irb_.getInt32(1), // VRegs
11488e950c117975d23f50ed7e32ca5db01a813c25d0TDYa    entry_idx // Pointer field
11498e950c117975d23f50ed7e32ca5db01a813c25d0TDYa  };
11508e950c117975d23f50ed7e32ca5db01a813c25d0TDYa
11518e950c117975d23f50ed7e32ca5db01a813c25d0TDYa  llvm::Value* vreg_addr = irb_.CreateGEP(shadow_frame_, gep_index);
11528e950c117975d23f50ed7e32ca5db01a813c25d0TDYa
11538e950c117975d23f50ed7e32ca5db01a813c25d0TDYa  irb_.CreateStore(value,
11548e950c117975d23f50ed7e32ca5db01a813c25d0TDYa                   irb_.CreateBitCast(vreg_addr, value->getType()->getPointerTo()),
11558e950c117975d23f50ed7e32ca5db01a813c25d0TDYa                   kTBAAShadowFrame);
11568e950c117975d23f50ed7e32ca5db01a813c25d0TDYa  return;
11578e950c117975d23f50ed7e32ca5db01a813c25d0TDYa}
11588e950c117975d23f50ed7e32ca5db01a813c25d0TDYa
115921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_PopShadowFrame() {
1160bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  if (old_shadow_frame_ == NULL) {
1161bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao    return;
1162bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  }
116321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  rtb_.EmitPopShadowFrame(irb_.CreateLoad(old_shadow_frame_, kTBAARegister));
116421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return;
116521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
116621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
116721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_UpdateDexPC(llvm::Value* dex_pc_value) {
116821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  irb_.StoreToObjectOffset(shadow_frame_,
1169920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa                           art::ShadowFrame::DexPCOffset(),
117021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                           dex_pc_value,
117121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                           kTBAAShadowFrame);
117221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return;
117321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
117421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
117567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chienvoid GBCExpanderPass::InsertStackOverflowCheck(llvm::Function& func) {
11764028312f6f4b49fd69992daf28cd37dd32e79a47jeffhao  // All alloca instructions are generated in the first basic block of the
11774028312f6f4b49fd69992daf28cd37dd32e79a47jeffhao  // function, and there are no alloca instructions after the first non-alloca
11784028312f6f4b49fd69992daf28cd37dd32e79a47jeffhao  // instruction.
117921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
118067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  llvm::BasicBlock* first_basic_block = &func.front();
118167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
118267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  // Look for first non-alloca instruction
118367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  llvm::BasicBlock::iterator first_non_alloca = first_basic_block->begin();
118421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  while (llvm::isa<llvm::AllocaInst>(first_non_alloca)) {
118521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    ++first_non_alloca;
118621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  }
118721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
118867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  irb_.SetInsertPoint(first_non_alloca);
118967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
119021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // Insert stack overflow check codes before first_non_alloca (i.e., after all
119121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  // alloca instructions)
119267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  EmitStackOverflowCheck(&*first_non_alloca);
119367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
1194890ea89879ba555a08433146058d516575646c59TDYa  irb_.Runtime().EmitTestSuspend();
1195890ea89879ba555a08433146058d516575646c59TDYa
119667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  llvm::BasicBlock* next_basic_block = irb_.GetInsertBlock();
119767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  if (next_basic_block != first_basic_block) {
119867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    // Splice the rest of the instruction to the continuing basic block
119967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    next_basic_block->getInstList().splice(
120067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien        irb_.GetInsertPoint(), first_basic_block->getInstList(),
120167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien        first_non_alloca, first_basic_block->end());
120267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
120367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    // Rewrite the basic block
120467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    RewriteBasicBlock(next_basic_block);
120567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
120667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    // Update the phi-instructions in the successor basic block
120767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien    UpdatePhiInstruction(first_basic_block, irb_.GetInsertBlock());
120867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  }
120967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien
121067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  // We have changed the basic block
121167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien  changed_ = true;
121221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
121321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
12145e869b6560f918837cc6be3a50234deb2be46385TDYa// ==== High-level intrinsic expander ==========================================
12155e869b6560f918837cc6be3a50234deb2be46385TDYa
1216a1b2185820e6080864d18a35759cc046dc4ee578TDYallvm::Value* GBCExpanderPass::Expand_FPCompare(llvm::Value* src1_value,
1217a1b2185820e6080864d18a35759cc046dc4ee578TDYa                                               llvm::Value* src2_value,
1218a1b2185820e6080864d18a35759cc046dc4ee578TDYa                                               bool gt_bias) {
1219a1b2185820e6080864d18a35759cc046dc4ee578TDYa  llvm::Value* cmp_eq = irb_.CreateFCmpOEQ(src1_value, src2_value);
1220a1b2185820e6080864d18a35759cc046dc4ee578TDYa  llvm::Value* cmp_lt;
1221a1b2185820e6080864d18a35759cc046dc4ee578TDYa
1222a1b2185820e6080864d18a35759cc046dc4ee578TDYa  if (gt_bias) {
1223a1b2185820e6080864d18a35759cc046dc4ee578TDYa    cmp_lt = irb_.CreateFCmpOLT(src1_value, src2_value);
1224a1b2185820e6080864d18a35759cc046dc4ee578TDYa  } else {
1225a1b2185820e6080864d18a35759cc046dc4ee578TDYa    cmp_lt = irb_.CreateFCmpULT(src1_value, src2_value);
1226a1b2185820e6080864d18a35759cc046dc4ee578TDYa  }
1227a1b2185820e6080864d18a35759cc046dc4ee578TDYa
1228a1b2185820e6080864d18a35759cc046dc4ee578TDYa  return EmitCompareResultSelection(cmp_eq, cmp_lt);
1229a1b2185820e6080864d18a35759cc046dc4ee578TDYa}
1230a1b2185820e6080864d18a35759cc046dc4ee578TDYa
1231a1b2185820e6080864d18a35759cc046dc4ee578TDYallvm::Value* GBCExpanderPass::Expand_LongCompare(llvm::Value* src1_value, llvm::Value* src2_value) {
1232a1b2185820e6080864d18a35759cc046dc4ee578TDYa  llvm::Value* cmp_eq = irb_.CreateICmpEQ(src1_value, src2_value);
1233a1b2185820e6080864d18a35759cc046dc4ee578TDYa  llvm::Value* cmp_lt = irb_.CreateICmpSLT(src1_value, src2_value);
1234a1b2185820e6080864d18a35759cc046dc4ee578TDYa
1235a1b2185820e6080864d18a35759cc046dc4ee578TDYa  return EmitCompareResultSelection(cmp_eq, cmp_lt);
1236a1b2185820e6080864d18a35759cc046dc4ee578TDYa}
1237a1b2185820e6080864d18a35759cc046dc4ee578TDYa
1238a1b2185820e6080864d18a35759cc046dc4ee578TDYallvm::Value* GBCExpanderPass::EmitCompareResultSelection(llvm::Value* cmp_eq,
1239a1b2185820e6080864d18a35759cc046dc4ee578TDYa                                                         llvm::Value* cmp_lt) {
1240a1b2185820e6080864d18a35759cc046dc4ee578TDYa
1241a1b2185820e6080864d18a35759cc046dc4ee578TDYa  llvm::Constant* zero = irb_.getJInt(0);
1242a1b2185820e6080864d18a35759cc046dc4ee578TDYa  llvm::Constant* pos1 = irb_.getJInt(1);
1243a1b2185820e6080864d18a35759cc046dc4ee578TDYa  llvm::Constant* neg1 = irb_.getJInt(-1);
1244a1b2185820e6080864d18a35759cc046dc4ee578TDYa
1245a1b2185820e6080864d18a35759cc046dc4ee578TDYa  llvm::Value* result_lt = irb_.CreateSelect(cmp_lt, neg1, pos1);
1246a1b2185820e6080864d18a35759cc046dc4ee578TDYa  llvm::Value* result_eq = irb_.CreateSelect(cmp_eq, zero, result_lt);
1247a1b2185820e6080864d18a35759cc046dc4ee578TDYa
1248a1b2185820e6080864d18a35759cc046dc4ee578TDYa  return result_eq;
1249a1b2185820e6080864d18a35759cc046dc4ee578TDYa}
1250a1b2185820e6080864d18a35759cc046dc4ee578TDYa
125175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chienllvm::Value* GBCExpanderPass::Expand_IntegerShift(llvm::Value* src1_value,
125275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                                                  llvm::Value* src2_value,
125375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                                                  IntegerShiftKind kind,
125475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                                                  JType op_jty) {
125575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  DCHECK(op_jty == kInt || op_jty == kLong);
125675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
125775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  // Mask and zero-extend RHS properly
125875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  if (op_jty == kInt) {
125975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    src2_value = irb_.CreateAnd(src2_value, 0x1f);
126075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  } else {
126175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    llvm::Value* masked_src2_value = irb_.CreateAnd(src2_value, 0x3f);
126275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    src2_value = irb_.CreateZExt(masked_src2_value, irb_.getJLongTy());
126375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  }
126475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
126575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  // Create integer shift llvm instruction
126675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  switch (kind) {
126775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  case kIntegerSHL:
126875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    return irb_.CreateShl(src1_value, src2_value);
126975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
127075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  case kIntegerSHR:
127175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    return irb_.CreateAShr(src1_value, src2_value);
127275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
127375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  case kIntegerUSHR:
127475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    return irb_.CreateLShr(src1_value, src2_value);
127575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
127675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  default:
127775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    LOG(FATAL) << "Unknown integer shift kind: " << kind;
127875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    return NULL;
127975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  }
128075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien}
128175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
12825a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYallvm::Value* GBCExpanderPass::Expand_HLArrayGet(llvm::CallInst& call_inst,
12835a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa                                                JType elem_jty) {
12845a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
12855a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Value* array_addr = call_inst.getArgOperand(1);
12865a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Value* index_value = call_inst.getArgOperand(2);
1287920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  int opt_flags = LV2UInt(call_inst.getArgOperand(0));
12885a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
1289920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  if (!(opt_flags & MIR_IGNORE_NULL_CHECK)) {
1290920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    EmitGuard_NullPointerException(dex_pc, array_addr);
1291920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  }
1292920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  if (!(opt_flags & MIR_IGNORE_RANGE_CHECK)) {
1293920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    EmitGuard_ArrayIndexOutOfBoundsException(dex_pc, array_addr, index_value);
1294920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  }
12955a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
12965a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Value* array_elem_addr = EmitArrayGEP(array_addr, index_value, elem_jty);
12975a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
12985a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Value* array_elem_value = irb_.CreateLoad(array_elem_addr, kTBAAHeapArray, elem_jty);
12995a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13005a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  switch (elem_jty) {
13015a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  case kVoid:
13025a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    break;
13035a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13045a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  case kBoolean:
13055a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  case kChar:
13065a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    array_elem_value = irb_.CreateZExt(array_elem_value, irb_.getJType(elem_jty, kReg));
13075a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    break;
13085a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13095a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  case kByte:
13105a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  case kShort:
13115a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    array_elem_value = irb_.CreateSExt(array_elem_value, irb_.getJType(elem_jty, kReg));
13125a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    break;
13135a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13145a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  case kInt:
13155a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  case kLong:
13165a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  case kFloat:
13175a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  case kDouble:
13185a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  case kObject:
13195a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    break;
13205a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13215a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  default:
13225a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    LOG(FATAL) << "Unknown java type: " << elem_jty;
13235a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  }
13245a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13255a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  return array_elem_value;
13265a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa}
13275a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13285a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13295a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYavoid GBCExpanderPass::Expand_HLArrayPut(llvm::CallInst& call_inst,
13305a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa                                        JType elem_jty) {
13315a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
13325a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Value* new_value = call_inst.getArgOperand(1);
13335a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Value* array_addr = call_inst.getArgOperand(2);
13345a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Value* index_value = call_inst.getArgOperand(3);
1335920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  int opt_flags = LV2UInt(call_inst.getArgOperand(0));
13365a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
1337920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  if (!(opt_flags & MIR_IGNORE_NULL_CHECK)) {
1338920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    EmitGuard_NullPointerException(dex_pc, array_addr);
1339920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  }
1340920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  if (!(opt_flags & MIR_IGNORE_RANGE_CHECK)) {
1341920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    EmitGuard_ArrayIndexOutOfBoundsException(dex_pc, array_addr, index_value);
1342920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  }
13435a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13445a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  switch (elem_jty) {
13455a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  case kVoid:
13465a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    break;
13475a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13485a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  case kBoolean:
13495a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  case kChar:
1350bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  case kByte:
1351bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  case kShort:
13525a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    new_value = irb_.CreateTrunc(new_value, irb_.getJType(elem_jty, kArray));
13535a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    break;
13545a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13555a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  case kInt:
13565a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  case kLong:
13575a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  case kFloat:
13585a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  case kDouble:
13595a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  case kObject:
13605a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    break;
13615a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13625a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  default:
13635a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    LOG(FATAL) << "Unknown java type: " << elem_jty;
13645a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  }
13655a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13665a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Value* array_elem_addr = EmitArrayGEP(array_addr, index_value, elem_jty);
13675a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13685a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  if (elem_jty == kObject) { // If put an object, check the type, and mark GC card table.
13695a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    llvm::Function* runtime_func = irb_.GetRuntime(runtime_support::CheckPutArrayElement);
13705a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13715a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    irb_.CreateCall2(runtime_func, new_value, array_addr);
13725a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13735a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    EmitGuard_ExceptionLandingPad(dex_pc);
13745a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13755a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    EmitMarkGCCard(new_value, array_addr);
13765a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  }
13775a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13785a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  irb_.CreateStore(new_value, array_elem_addr, kTBAAHeapArray, elem_jty);
13795a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13805a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  return;
13815a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa}
13825a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
13835e869b6560f918837cc6be3a50234deb2be46385TDYallvm::Value* GBCExpanderPass::Expand_HLIGet(llvm::CallInst& call_inst,
13845e869b6560f918837cc6be3a50234deb2be46385TDYa                                            JType field_jty) {
13855e869b6560f918837cc6be3a50234deb2be46385TDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
13865e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::Value* object_addr = call_inst.getArgOperand(1);
13875e869b6560f918837cc6be3a50234deb2be46385TDYa  uint32_t field_idx = LV2UInt(call_inst.getArgOperand(2));
1388920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  int opt_flags = LV2UInt(call_inst.getArgOperand(0));
13895e869b6560f918837cc6be3a50234deb2be46385TDYa
1390920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  if (!(opt_flags & MIR_IGNORE_NULL_CHECK)) {
1391920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    EmitGuard_NullPointerException(dex_pc, object_addr);
1392920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  }
13935e869b6560f918837cc6be3a50234deb2be46385TDYa
13945e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::Value* field_value;
13955e869b6560f918837cc6be3a50234deb2be46385TDYa
13965e869b6560f918837cc6be3a50234deb2be46385TDYa  int field_offset;
13975e869b6560f918837cc6be3a50234deb2be46385TDYa  bool is_volatile;
13985e869b6560f918837cc6be3a50234deb2be46385TDYa  bool is_fast_path = compiler_->ComputeInstanceFieldInfo(
13995e869b6560f918837cc6be3a50234deb2be46385TDYa    field_idx, oat_compilation_unit_, field_offset, is_volatile, false);
14005e869b6560f918837cc6be3a50234deb2be46385TDYa
14015e869b6560f918837cc6be3a50234deb2be46385TDYa  if (!is_fast_path) {
14025e869b6560f918837cc6be3a50234deb2be46385TDYa    llvm::Function* runtime_func;
14035e869b6560f918837cc6be3a50234deb2be46385TDYa
14045e869b6560f918837cc6be3a50234deb2be46385TDYa    if (field_jty == kObject) {
14055e869b6560f918837cc6be3a50234deb2be46385TDYa      runtime_func = irb_.GetRuntime(runtime_support::GetObjectInstance);
14065e869b6560f918837cc6be3a50234deb2be46385TDYa    } else if (field_jty == kLong || field_jty == kDouble) {
14075e869b6560f918837cc6be3a50234deb2be46385TDYa      runtime_func = irb_.GetRuntime(runtime_support::Get64Instance);
14085e869b6560f918837cc6be3a50234deb2be46385TDYa    } else {
14095e869b6560f918837cc6be3a50234deb2be46385TDYa      runtime_func = irb_.GetRuntime(runtime_support::Get32Instance);
14105e869b6560f918837cc6be3a50234deb2be46385TDYa    }
14115e869b6560f918837cc6be3a50234deb2be46385TDYa
14125e869b6560f918837cc6be3a50234deb2be46385TDYa    llvm::ConstantInt* field_idx_value = irb_.getInt32(field_idx);
14135e869b6560f918837cc6be3a50234deb2be46385TDYa
14145e869b6560f918837cc6be3a50234deb2be46385TDYa    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
14155e869b6560f918837cc6be3a50234deb2be46385TDYa
14165e869b6560f918837cc6be3a50234deb2be46385TDYa    EmitUpdateDexPC(dex_pc);
14175e869b6560f918837cc6be3a50234deb2be46385TDYa
14185e869b6560f918837cc6be3a50234deb2be46385TDYa    field_value = irb_.CreateCall3(runtime_func, field_idx_value,
14195e869b6560f918837cc6be3a50234deb2be46385TDYa                                   method_object_addr, object_addr);
14205e869b6560f918837cc6be3a50234deb2be46385TDYa
14215e869b6560f918837cc6be3a50234deb2be46385TDYa    EmitGuard_ExceptionLandingPad(dex_pc);
14225e869b6560f918837cc6be3a50234deb2be46385TDYa
14235e869b6560f918837cc6be3a50234deb2be46385TDYa  } else {
14245e869b6560f918837cc6be3a50234deb2be46385TDYa    DCHECK_GE(field_offset, 0);
14255e869b6560f918837cc6be3a50234deb2be46385TDYa
14265e869b6560f918837cc6be3a50234deb2be46385TDYa    llvm::PointerType* field_type =
14275e869b6560f918837cc6be3a50234deb2be46385TDYa      irb_.getJType(field_jty, kField)->getPointerTo();
14285e869b6560f918837cc6be3a50234deb2be46385TDYa
14295e869b6560f918837cc6be3a50234deb2be46385TDYa    llvm::ConstantInt* field_offset_value = irb_.getPtrEquivInt(field_offset);
14305e869b6560f918837cc6be3a50234deb2be46385TDYa
14315e869b6560f918837cc6be3a50234deb2be46385TDYa    llvm::Value* field_addr =
14325e869b6560f918837cc6be3a50234deb2be46385TDYa      irb_.CreatePtrDisp(object_addr, field_offset_value, field_type);
14335e869b6560f918837cc6be3a50234deb2be46385TDYa
14345e869b6560f918837cc6be3a50234deb2be46385TDYa    // TODO: Check is_volatile.  We need to generate atomic load instruction
14355e869b6560f918837cc6be3a50234deb2be46385TDYa    // when is_volatile is true.
14365e869b6560f918837cc6be3a50234deb2be46385TDYa    field_value = irb_.CreateLoad(field_addr, kTBAAHeapInstance, field_jty);
14375e869b6560f918837cc6be3a50234deb2be46385TDYa  }
14385e869b6560f918837cc6be3a50234deb2be46385TDYa
14395e869b6560f918837cc6be3a50234deb2be46385TDYa  if (field_jty == kFloat || field_jty == kDouble) {
14405a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    field_value = irb_.CreateBitCast(field_value, irb_.getJType(field_jty, kAccurate));
14415e869b6560f918837cc6be3a50234deb2be46385TDYa  }
14425e869b6560f918837cc6be3a50234deb2be46385TDYa
14435e869b6560f918837cc6be3a50234deb2be46385TDYa  return field_value;
14445e869b6560f918837cc6be3a50234deb2be46385TDYa}
14455e869b6560f918837cc6be3a50234deb2be46385TDYa
14465e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::Expand_HLIPut(llvm::CallInst& call_inst,
14475e869b6560f918837cc6be3a50234deb2be46385TDYa                                    JType field_jty) {
14485e869b6560f918837cc6be3a50234deb2be46385TDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
1449bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  llvm::Value* new_value = call_inst.getArgOperand(1);
1450bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  llvm::Value* object_addr = call_inst.getArgOperand(2);
14515e869b6560f918837cc6be3a50234deb2be46385TDYa  uint32_t field_idx = LV2UInt(call_inst.getArgOperand(3));
1452920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  int opt_flags = LV2UInt(call_inst.getArgOperand(0));
14535e869b6560f918837cc6be3a50234deb2be46385TDYa
14545e869b6560f918837cc6be3a50234deb2be46385TDYa  if (field_jty == kFloat || field_jty == kDouble) {
14555a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    new_value = irb_.CreateBitCast(new_value, irb_.getJType(field_jty, kField));
14565e869b6560f918837cc6be3a50234deb2be46385TDYa  }
14575e869b6560f918837cc6be3a50234deb2be46385TDYa
1458920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  if (!(opt_flags & MIR_IGNORE_NULL_CHECK)) {
1459920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    EmitGuard_NullPointerException(dex_pc, object_addr);
1460920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  }
14615e869b6560f918837cc6be3a50234deb2be46385TDYa
14625e869b6560f918837cc6be3a50234deb2be46385TDYa  int field_offset;
14635e869b6560f918837cc6be3a50234deb2be46385TDYa  bool is_volatile;
14645e869b6560f918837cc6be3a50234deb2be46385TDYa  bool is_fast_path = compiler_->ComputeInstanceFieldInfo(
14655e869b6560f918837cc6be3a50234deb2be46385TDYa    field_idx, oat_compilation_unit_, field_offset, is_volatile, true);
14665e869b6560f918837cc6be3a50234deb2be46385TDYa
14675e869b6560f918837cc6be3a50234deb2be46385TDYa  if (!is_fast_path) {
14685e869b6560f918837cc6be3a50234deb2be46385TDYa    llvm::Function* runtime_func;
14695e869b6560f918837cc6be3a50234deb2be46385TDYa
14705e869b6560f918837cc6be3a50234deb2be46385TDYa    if (field_jty == kObject) {
14715e869b6560f918837cc6be3a50234deb2be46385TDYa      runtime_func = irb_.GetRuntime(runtime_support::SetObjectInstance);
14725e869b6560f918837cc6be3a50234deb2be46385TDYa    } else if (field_jty == kLong || field_jty == kDouble) {
14735e869b6560f918837cc6be3a50234deb2be46385TDYa      runtime_func = irb_.GetRuntime(runtime_support::Set64Instance);
14745e869b6560f918837cc6be3a50234deb2be46385TDYa    } else {
14755e869b6560f918837cc6be3a50234deb2be46385TDYa      runtime_func = irb_.GetRuntime(runtime_support::Set32Instance);
14765e869b6560f918837cc6be3a50234deb2be46385TDYa    }
14775e869b6560f918837cc6be3a50234deb2be46385TDYa
14785e869b6560f918837cc6be3a50234deb2be46385TDYa    llvm::Value* field_idx_value = irb_.getInt32(field_idx);
14795e869b6560f918837cc6be3a50234deb2be46385TDYa
14805e869b6560f918837cc6be3a50234deb2be46385TDYa    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
14815e869b6560f918837cc6be3a50234deb2be46385TDYa
14825e869b6560f918837cc6be3a50234deb2be46385TDYa    EmitUpdateDexPC(dex_pc);
14835e869b6560f918837cc6be3a50234deb2be46385TDYa
14845e869b6560f918837cc6be3a50234deb2be46385TDYa    irb_.CreateCall4(runtime_func, field_idx_value,
14855e869b6560f918837cc6be3a50234deb2be46385TDYa                     method_object_addr, object_addr, new_value);
14865e869b6560f918837cc6be3a50234deb2be46385TDYa
14875e869b6560f918837cc6be3a50234deb2be46385TDYa    EmitGuard_ExceptionLandingPad(dex_pc);
14885e869b6560f918837cc6be3a50234deb2be46385TDYa
14895e869b6560f918837cc6be3a50234deb2be46385TDYa  } else {
14905e869b6560f918837cc6be3a50234deb2be46385TDYa    DCHECK_GE(field_offset, 0);
14915e869b6560f918837cc6be3a50234deb2be46385TDYa
14925e869b6560f918837cc6be3a50234deb2be46385TDYa    llvm::PointerType* field_type =
14935e869b6560f918837cc6be3a50234deb2be46385TDYa      irb_.getJType(field_jty, kField)->getPointerTo();
14945e869b6560f918837cc6be3a50234deb2be46385TDYa
14955e869b6560f918837cc6be3a50234deb2be46385TDYa    llvm::Value* field_offset_value = irb_.getPtrEquivInt(field_offset);
14965e869b6560f918837cc6be3a50234deb2be46385TDYa
14975e869b6560f918837cc6be3a50234deb2be46385TDYa    llvm::Value* field_addr =
14985e869b6560f918837cc6be3a50234deb2be46385TDYa      irb_.CreatePtrDisp(object_addr, field_offset_value, field_type);
14995e869b6560f918837cc6be3a50234deb2be46385TDYa
15005e869b6560f918837cc6be3a50234deb2be46385TDYa    // TODO: Check is_volatile.  We need to generate atomic store instruction
15015e869b6560f918837cc6be3a50234deb2be46385TDYa    // when is_volatile is true.
15025e869b6560f918837cc6be3a50234deb2be46385TDYa    irb_.CreateStore(new_value, field_addr, kTBAAHeapInstance, field_jty);
15035e869b6560f918837cc6be3a50234deb2be46385TDYa
15045e869b6560f918837cc6be3a50234deb2be46385TDYa    if (field_jty == kObject) { // If put an object, mark the GC card table.
15055e869b6560f918837cc6be3a50234deb2be46385TDYa      EmitMarkGCCard(new_value, object_addr);
15065e869b6560f918837cc6be3a50234deb2be46385TDYa    }
15075e869b6560f918837cc6be3a50234deb2be46385TDYa  }
15085e869b6560f918837cc6be3a50234deb2be46385TDYa
15095e869b6560f918837cc6be3a50234deb2be46385TDYa  return;
15105e869b6560f918837cc6be3a50234deb2be46385TDYa}
15115e869b6560f918837cc6be3a50234deb2be46385TDYa
1512f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::EmitLoadConstantClass(uint32_t dex_pc,
1513f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                                                    uint32_t type_idx) {
1514bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  if (!compiler_->CanAccessTypeWithoutChecks(method_idx_, *dex_file_, type_idx)) {
1515f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Value* type_idx_value = irb_.getInt32(type_idx);
1516f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1517f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
1518f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1519f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
1520f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1521f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Function* runtime_func =
1522f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      irb_.GetRuntime(runtime_support::InitializeTypeAndVerifyAccess);
1523f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1524f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    EmitUpdateDexPC(dex_pc);
1525f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1526f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Value* type_object_addr =
1527f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      irb_.CreateCall3(runtime_func, type_idx_value, method_object_addr, thread_object_addr);
1528f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1529f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    EmitGuard_ExceptionLandingPad(dex_pc);
1530f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1531f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    return type_object_addr;
1532f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1533f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  } else {
1534f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // Try to load the class (type) object from the test cache.
1535f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Value* type_field_addr =
1536f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      EmitLoadDexCacheResolvedTypeFieldAddr(type_idx);
1537f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1538ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa    llvm::Value* type_object_addr = irb_.CreateLoad(type_field_addr, kTBAARuntimeInfo);
1539f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1540bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao    if (compiler_->CanAssumeTypeIsPresentInDexCache(*dex_file_, type_idx)) {
1541f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      return type_object_addr;
1542f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    }
1543f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1544f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::BasicBlock* block_original = irb_.GetInsertBlock();
1545f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1546f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // Test whether class (type) object is in the dex cache or not
1547f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Value* equal_null =
1548f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      irb_.CreateICmpEQ(type_object_addr, irb_.getJNull());
1549f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1550f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::BasicBlock* block_cont =
1551f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      CreateBasicBlockWithDexPC(dex_pc, "cont");
1552f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1553f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::BasicBlock* block_load_class =
1554f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      CreateBasicBlockWithDexPC(dex_pc, "load_class");
1555f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1556f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.CreateCondBr(equal_null, block_load_class, block_cont, kUnlikely);
1557f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1558f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // Failback routine to load the class object
1559f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.SetInsertPoint(block_load_class);
1560f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1561f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Function* runtime_func = irb_.GetRuntime(runtime_support::InitializeType);
1562f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1563f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Constant* type_idx_value = irb_.getInt32(type_idx);
1564f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1565f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
1566f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1567f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
1568f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1569f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    EmitUpdateDexPC(dex_pc);
1570f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1571f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Value* loaded_type_object_addr =
1572f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      irb_.CreateCall3(runtime_func, type_idx_value, method_object_addr, thread_object_addr);
1573f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1574f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    EmitGuard_ExceptionLandingPad(dex_pc);
1575f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1576f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::BasicBlock* block_after_load_class = irb_.GetInsertBlock();
1577f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1578f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.CreateBr(block_cont);
1579f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1580f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // Now the class object must be loaded
1581f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.SetInsertPoint(block_cont);
1582f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1583f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::PHINode* phi = irb_.CreatePHI(irb_.getJObjectTy(), 2);
1584f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1585f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    phi->addIncoming(type_object_addr, block_original);
1586f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    phi->addIncoming(loaded_type_object_addr, block_after_load_class);
1587f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1588f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    return phi;
1589f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  }
1590f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa}
1591f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
15925a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYallvm::Value* GBCExpanderPass::EmitLoadStaticStorage(uint32_t dex_pc,
15935a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa                                                    uint32_t type_idx) {
15945a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::BasicBlock* block_load_static =
15955a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    CreateBasicBlockWithDexPC(dex_pc, "load_static");
15965a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
15975a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::BasicBlock* block_cont = CreateBasicBlockWithDexPC(dex_pc, "cont");
15985a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
15995a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  // Load static storage from dex cache
16005a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Value* storage_field_addr =
16015a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    EmitLoadDexCacheStaticStorageFieldAddr(type_idx);
16025a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
1603ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  llvm::Value* storage_object_addr = irb_.CreateLoad(storage_field_addr, kTBAARuntimeInfo);
16045a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16055a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::BasicBlock* block_original = irb_.GetInsertBlock();
16065a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16075a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  // Test: Is the static storage of this class initialized?
16085a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Value* equal_null =
16095a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    irb_.CreateICmpEQ(storage_object_addr, irb_.getJNull());
16105a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16115a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  irb_.CreateCondBr(equal_null, block_load_static, block_cont, kUnlikely);
16125a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16135a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  // Failback routine to load the class object
16145a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  irb_.SetInsertPoint(block_load_static);
16155a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16165a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Function* runtime_func = irb_.GetRuntime(runtime_support::InitializeStaticStorage);
16175a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16185a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Constant* type_idx_value = irb_.getInt32(type_idx);
16195a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16205a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
16215a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16225a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
16235a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16245a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  EmitUpdateDexPC(dex_pc);
16255a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16265a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Value* loaded_storage_object_addr =
16275a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    irb_.CreateCall3(runtime_func, type_idx_value, method_object_addr, thread_object_addr);
16285a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16295a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  EmitGuard_ExceptionLandingPad(dex_pc);
16305a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16315a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::BasicBlock* block_after_load_static = irb_.GetInsertBlock();
16325a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16335a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  irb_.CreateBr(block_cont);
16345a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16355a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  // Now the class object must be loaded
16365a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  irb_.SetInsertPoint(block_cont);
16375a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16385a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::PHINode* phi = irb_.CreatePHI(irb_.getJObjectTy(), 2);
16395a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16405a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  phi->addIncoming(storage_object_addr, block_original);
16415a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  phi->addIncoming(loaded_storage_object_addr, block_after_load_static);
16425a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16435a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  return phi;
16445a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa}
16455a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16465a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYallvm::Value* GBCExpanderPass::Expand_HLSget(llvm::CallInst& call_inst,
16475a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa                                            JType field_jty) {
16485a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
16495a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  uint32_t field_idx = LV2UInt(call_inst.getArgOperand(0));
16505a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16515a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  int field_offset;
16525a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  int ssb_index;
16535a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  bool is_referrers_class;
16545a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  bool is_volatile;
16555a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16565a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  bool is_fast_path = compiler_->ComputeStaticFieldInfo(
16575a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    field_idx, oat_compilation_unit_, field_offset, ssb_index,
16585a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    is_referrers_class, is_volatile, false);
16595a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16605a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Value* static_field_value;
16615a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16625a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  if (!is_fast_path) {
16635a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    llvm::Function* runtime_func;
16645a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16655a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    if (field_jty == kObject) {
16665a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      runtime_func = irb_.GetRuntime(runtime_support::GetObjectStatic);
16675a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    } else if (field_jty == kLong || field_jty == kDouble) {
16685a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      runtime_func = irb_.GetRuntime(runtime_support::Get64Static);
16695a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    } else {
16705a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      runtime_func = irb_.GetRuntime(runtime_support::Get32Static);
16715a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    }
16725a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16735a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    llvm::Constant* field_idx_value = irb_.getInt32(field_idx);
16745a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16755a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
16765a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16775a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    EmitUpdateDexPC(dex_pc);
16785a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16795a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    static_field_value =
16805a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      irb_.CreateCall2(runtime_func, field_idx_value, method_object_addr);
16815a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16825a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    EmitGuard_ExceptionLandingPad(dex_pc);
16835a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16845a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  } else {
16855a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    DCHECK_GE(field_offset, 0);
16865a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16875a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    llvm::Value* static_storage_addr = NULL;
16885a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16895a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    if (is_referrers_class) {
16905a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      // Fast path, static storage base is this method's class
16915a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
16925a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
16935a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      static_storage_addr =
16945a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa        irb_.LoadFromObjectOffset(method_object_addr,
169598573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers                                  art::mirror::AbstractMethod::DeclaringClassOffset().Int32Value(),
16965a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa                                  irb_.getJObjectTy(),
16975a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa                                  kTBAAConstJObject);
16985a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    } else {
16995a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      // Medium path, static storage base in a different class which
17005a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      // requires checks that the other class is initialized
17015a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      DCHECK_GE(ssb_index, 0);
17025a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      static_storage_addr = EmitLoadStaticStorage(dex_pc, ssb_index);
17035a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    }
17045a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17055a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset);
17065a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17075a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    llvm::Value* static_field_addr =
17085a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value,
17095a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa                         irb_.getJType(field_jty, kField)->getPointerTo());
17105a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17115a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    // TODO: Check is_volatile.  We need to generate atomic load instruction
17125a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    // when is_volatile is true.
17135a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    static_field_value = irb_.CreateLoad(static_field_addr, kTBAAHeapStatic, field_jty);
17145a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  }
17155a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17165a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  if (field_jty == kFloat || field_jty == kDouble) {
17175a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    static_field_value =
17185a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa        irb_.CreateBitCast(static_field_value, irb_.getJType(field_jty, kAccurate));
17195a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  }
17205a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17215a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  return static_field_value;
17225a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa}
17235a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17245a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYavoid GBCExpanderPass::Expand_HLSput(llvm::CallInst& call_inst,
17255a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa                                    JType field_jty) {
17265a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
17275a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  uint32_t field_idx = LV2UInt(call_inst.getArgOperand(0));
17285a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  llvm::Value* new_value = call_inst.getArgOperand(1);
17295a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17305a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  if (field_jty == kFloat || field_jty == kDouble) {
17315a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    new_value = irb_.CreateBitCast(new_value, irb_.getJType(field_jty, kField));
17325a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  }
17335a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17345a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  int field_offset;
17355a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  int ssb_index;
17365a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  bool is_referrers_class;
17375a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  bool is_volatile;
17385a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17395a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  bool is_fast_path = compiler_->ComputeStaticFieldInfo(
17405a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    field_idx, oat_compilation_unit_, field_offset, ssb_index,
17415a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    is_referrers_class, is_volatile, true);
17425a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17435a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  if (!is_fast_path) {
17445a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    llvm::Function* runtime_func;
17455a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17465a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    if (field_jty == kObject) {
17475a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      runtime_func = irb_.GetRuntime(runtime_support::SetObjectStatic);
17485a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    } else if (field_jty == kLong || field_jty == kDouble) {
17495a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      runtime_func = irb_.GetRuntime(runtime_support::Set64Static);
17505a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    } else {
17515a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      runtime_func = irb_.GetRuntime(runtime_support::Set32Static);
17525a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    }
17535a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17545a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    llvm::Constant* field_idx_value = irb_.getInt32(field_idx);
17555a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17565a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
17575a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17585a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    EmitUpdateDexPC(dex_pc);
17595a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17605a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    irb_.CreateCall3(runtime_func, field_idx_value,
17615a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa                     method_object_addr, new_value);
17625a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17635a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    EmitGuard_ExceptionLandingPad(dex_pc);
17645a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17655a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  } else {
17665a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    DCHECK_GE(field_offset, 0);
17675a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17685a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    llvm::Value* static_storage_addr = NULL;
17695a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17705a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    if (is_referrers_class) {
17715a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      // Fast path, static storage base is this method's class
17725a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
17735a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17745a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      static_storage_addr =
17755a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa        irb_.LoadFromObjectOffset(method_object_addr,
177698573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers                                  art::mirror::AbstractMethod::DeclaringClassOffset().Int32Value(),
17775a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa                                  irb_.getJObjectTy(),
17785a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa                                  kTBAAConstJObject);
17795a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    } else {
17805a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      // Medium path, static storage base in a different class which
17815a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      // requires checks that the other class is initialized
17825a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      DCHECK_GE(ssb_index, 0);
17835a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      static_storage_addr = EmitLoadStaticStorage(dex_pc, ssb_index);
17845a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    }
17855a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17865a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset);
17875a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17885a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    llvm::Value* static_field_addr =
17895a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value,
17905a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa                         irb_.getJType(field_jty, kField)->getPointerTo());
17915a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17925a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    // TODO: Check is_volatile.  We need to generate atomic store instruction
17935a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    // when is_volatile is true.
17945a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    irb_.CreateStore(new_value, static_field_addr, kTBAAHeapStatic, field_jty);
17955a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
17965a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    if (field_jty == kObject) { // If put an object, mark the GC card table.
17975a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      EmitMarkGCCard(new_value, static_storage_addr);
17985a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa    }
17995a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  }
18005a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
18015a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa  return;
18025a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa}
18035a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa
1804f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_ConstString(llvm::CallInst& call_inst) {
1805f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
1806f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t string_idx = LV2UInt(call_inst.getArgOperand(0));
1807f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1808f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* string_field_addr = EmitLoadDexCacheStringFieldAddr(string_idx);
1809f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1810ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  llvm::Value* string_addr = irb_.CreateLoad(string_field_addr, kTBAARuntimeInfo);
1811f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1812bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  if (!compiler_->CanAssumeStringIsPresentInDexCache(*dex_file_, string_idx)) {
1813f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::BasicBlock* block_str_exist =
1814f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      CreateBasicBlockWithDexPC(dex_pc, "str_exist");
1815f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1816f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::BasicBlock* block_str_resolve =
1817f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      CreateBasicBlockWithDexPC(dex_pc, "str_resolve");
1818f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1819f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::BasicBlock* block_cont =
1820f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      CreateBasicBlockWithDexPC(dex_pc, "str_cont");
1821f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1822f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // Test: Is the string resolved and in the dex cache?
1823f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Value* equal_null = irb_.CreateICmpEQ(string_addr, irb_.getJNull());
1824f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1825f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.CreateCondBr(equal_null, block_str_resolve, block_str_exist, kUnlikely);
1826f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1827f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // String is resolved, go to next basic block.
1828f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.SetInsertPoint(block_str_exist);
1829f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.CreateBr(block_cont);
1830f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1831f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // String is not resolved yet, resolve it now.
1832f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.SetInsertPoint(block_str_resolve);
1833f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1834f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Function* runtime_func = irb_.GetRuntime(runtime_support::ResolveString);
1835f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1836f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
1837f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1838f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Value* string_idx_value = irb_.getInt32(string_idx);
1839f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1840f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    EmitUpdateDexPC(dex_pc);
1841f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1842f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Value* result = irb_.CreateCall2(runtime_func, method_object_addr,
1843f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                                           string_idx_value);
1844f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1845f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    EmitGuard_ExceptionLandingPad(dex_pc);
1846f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1847bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao    irb_.CreateBr(block_cont);
1848bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao
1849bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao
1850f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::BasicBlock* block_pre_cont = irb_.GetInsertBlock();
1851f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1852f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.SetInsertPoint(block_cont);
1853f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1854f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::PHINode* phi = irb_.CreatePHI(irb_.getJObjectTy(), 2);
1855f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1856f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    phi->addIncoming(string_addr, block_str_exist);
1857f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    phi->addIncoming(result, block_pre_cont);
1858f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1859f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    string_addr = phi;
1860f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  }
1861f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1862f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  return string_addr;
1863f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa}
1864f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1865f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_ConstClass(llvm::CallInst& call_inst) {
1866f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
1867f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0));
1868f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1869f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, type_idx);
1870f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1871f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  return type_object_addr;
1872f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa}
1873f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1874f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYavoid GBCExpanderPass::Expand_MonitorEnter(llvm::CallInst& call_inst) {
1875f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
1876f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* object_addr = call_inst.getArgOperand(1);
1877920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  int opt_flags = LV2UInt(call_inst.getArgOperand(0));
1878f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1879920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  if (!(opt_flags & MIR_IGNORE_NULL_CHECK)) {
1880920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    EmitGuard_NullPointerException(dex_pc, object_addr);
1881920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  }
1882f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1883ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa  EmitUpdateDexPC(dex_pc);
1884ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa
1885f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  irb_.Runtime().EmitLockObject(object_addr);
1886f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1887f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  return;
1888f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa}
1889f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1890f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYavoid GBCExpanderPass::Expand_MonitorExit(llvm::CallInst& call_inst) {
1891f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
1892f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* object_addr = call_inst.getArgOperand(1);
1893920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  int opt_flags = LV2UInt(call_inst.getArgOperand(0));
1894f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1895920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  if (!(opt_flags & MIR_IGNORE_NULL_CHECK)) {
1896920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    EmitGuard_NullPointerException(dex_pc, object_addr);
1897920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  }
1898f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1899f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  EmitUpdateDexPC(dex_pc);
1900f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1901f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  irb_.Runtime().EmitUnlockObject(object_addr);
1902f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1903f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  EmitGuard_ExceptionLandingPad(dex_pc);
1904f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1905f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  return;
1906f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa}
1907f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1908f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYavoid GBCExpanderPass::Expand_HLCheckCast(llvm::CallInst& call_inst) {
1909f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
1910f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0));
1911f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* object_addr = call_inst.getArgOperand(1);
1912f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1913f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::BasicBlock* block_test_class =
1914f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    CreateBasicBlockWithDexPC(dex_pc, "test_class");
1915f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1916f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::BasicBlock* block_test_sub_class =
1917f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    CreateBasicBlockWithDexPC(dex_pc, "test_sub_class");
1918f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1919f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::BasicBlock* block_cont =
1920f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    CreateBasicBlockWithDexPC(dex_pc, "checkcast_cont");
1921f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1922f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  // Test: Is the reference equal to null?  Act as no-op when it is null.
1923f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* equal_null = irb_.CreateICmpEQ(object_addr, irb_.getJNull());
1924f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1925f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  irb_.CreateCondBr(equal_null,
1926f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                    block_cont,
1927f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                    block_test_class);
1928f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1929f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  // Test: Is the object instantiated from the given class?
1930f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  irb_.SetInsertPoint(block_test_class);
1931f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, type_idx);
193298573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers  DCHECK_EQ(art::mirror::Object::ClassOffset().Int32Value(), 0);
1933f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1934f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::PointerType* jobject_ptr_ty = irb_.getJObjectTy();
1935f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1936f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* object_type_field_addr =
1937f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.CreateBitCast(object_addr, jobject_ptr_ty->getPointerTo());
1938f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1939f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* object_type_object_addr =
1940f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.CreateLoad(object_type_field_addr, kTBAAConstJObject);
1941f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1942f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* equal_class =
1943f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.CreateICmpEQ(type_object_addr, object_type_object_addr);
1944f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1945f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  irb_.CreateCondBr(equal_class,
1946f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                    block_cont,
1947f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                    block_test_sub_class);
1948f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1949f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  // Test: Is the object instantiated from the subclass of the given class?
1950f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  irb_.SetInsertPoint(block_test_sub_class);
1951f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1952f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  EmitUpdateDexPC(dex_pc);
1953f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1954f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  irb_.CreateCall2(irb_.GetRuntime(runtime_support::CheckCast),
1955f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                   type_object_addr, object_type_object_addr);
1956f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1957f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  EmitGuard_ExceptionLandingPad(dex_pc);
1958f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1959f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  irb_.CreateBr(block_cont);
1960f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1961f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  irb_.SetInsertPoint(block_cont);
1962f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1963f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  return;
1964f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa}
1965f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1966f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_InstanceOf(llvm::CallInst& call_inst) {
1967f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
1968f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0));
1969f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* object_addr = call_inst.getArgOperand(1);
1970f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1971f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::BasicBlock* block_nullp =
1972f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      CreateBasicBlockWithDexPC(dex_pc, "nullp");
1973f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1974f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::BasicBlock* block_test_class =
1975f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      CreateBasicBlockWithDexPC(dex_pc, "test_class");
1976f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1977f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::BasicBlock* block_class_equals =
1978f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      CreateBasicBlockWithDexPC(dex_pc, "class_eq");
1979f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1980f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::BasicBlock* block_test_sub_class =
1981f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      CreateBasicBlockWithDexPC(dex_pc, "test_sub_class");
1982f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1983f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::BasicBlock* block_cont =
1984f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      CreateBasicBlockWithDexPC(dex_pc, "instance_of_cont");
1985f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1986f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  // Overview of the following code :
1987f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  // We check for null, if so, then false, otherwise check for class == . If so
1988f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  // then true, otherwise do callout slowpath.
1989f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  //
1990f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  // Test: Is the reference equal to null?  Set 0 when it is null.
1991f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* equal_null = irb_.CreateICmpEQ(object_addr, irb_.getJNull());
1992f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1993f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  irb_.CreateCondBr(equal_null, block_nullp, block_test_class);
1994f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1995f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  irb_.SetInsertPoint(block_nullp);
1996f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  irb_.CreateBr(block_cont);
1997f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
1998f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  // Test: Is the object instantiated from the given class?
1999f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  irb_.SetInsertPoint(block_test_class);
2000f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, type_idx);
200198573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers  DCHECK_EQ(art::mirror::Object::ClassOffset().Int32Value(), 0);
2002f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2003f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::PointerType* jobject_ptr_ty = irb_.getJObjectTy();
2004f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2005f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* object_type_field_addr =
2006f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.CreateBitCast(object_addr, jobject_ptr_ty->getPointerTo());
2007f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2008f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* object_type_object_addr =
2009f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.CreateLoad(object_type_field_addr, kTBAAConstJObject);
2010f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2011f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* equal_class =
2012f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.CreateICmpEQ(type_object_addr, object_type_object_addr);
2013f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2014f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  irb_.CreateCondBr(equal_class, block_class_equals, block_test_sub_class);
2015f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2016f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  irb_.SetInsertPoint(block_class_equals);
2017f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  irb_.CreateBr(block_cont);
2018f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2019f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  // Test: Is the object instantiated from the subclass of the given class?
2020f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  irb_.SetInsertPoint(block_test_sub_class);
2021f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* result =
2022f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.CreateCall2(irb_.GetRuntime(runtime_support::IsAssignable),
2023f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                     type_object_addr, object_type_object_addr);
2024f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  irb_.CreateBr(block_cont);
2025f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2026f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  irb_.SetInsertPoint(block_cont);
2027f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2028f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::PHINode* phi = irb_.CreatePHI(irb_.getJIntTy(), 3);
2029f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2030f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  phi->addIncoming(irb_.getJInt(0), block_nullp);
2031f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  phi->addIncoming(irb_.getJInt(1), block_class_equals);
2032f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  phi->addIncoming(result, block_test_sub_class);
2033f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2034f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  return phi;
2035f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa}
2036f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2037f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_NewInstance(llvm::CallInst& call_inst) {
2038f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
2039f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0));
2040f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2041f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Function* runtime_func;
2042bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  if (compiler_->CanAccessInstantiableTypeWithoutChecks(method_idx_, *dex_file_, type_idx)) {
2043f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    runtime_func = irb_.GetRuntime(runtime_support::AllocObject);
2044f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  } else {
2045f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    runtime_func = irb_.GetRuntime(runtime_support::AllocObjectWithAccessCheck);
2046f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  }
2047f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2048f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Constant* type_index_value = irb_.getInt32(type_idx);
2049f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2050f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
2051f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2052f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
2053f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2054f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  EmitUpdateDexPC(dex_pc);
2055f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2056f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* object_addr =
2057f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.CreateCall3(runtime_func, type_index_value, method_object_addr, thread_object_addr);
2058f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2059f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  EmitGuard_ExceptionLandingPad(dex_pc);
2060f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2061f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  return object_addr;
2062f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa}
2063f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2064f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_HLInvoke(llvm::CallInst& call_inst) {
2065f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
2066920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  art::InvokeType invoke_type = static_cast<art::InvokeType>(LV2UInt(call_inst.getArgOperand(0)));
2067920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  bool is_static = (invoke_type == art::kStatic);
2068f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t callee_method_idx = LV2UInt(call_inst.getArgOperand(1));
2069920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  int opt_flags = LV2UInt(call_inst.getArgOperand(2));
2070f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2071f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  // Compute invoke related information for compiler decision
2072f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  int vtable_idx = -1;
2073f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uintptr_t direct_code = 0;
2074f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uintptr_t direct_method = 0;
2075f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  bool is_fast_path = compiler_->
2076f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    ComputeInvokeInfo(callee_method_idx, oat_compilation_unit_,
2077f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                      invoke_type, vtable_idx, direct_code, direct_method);
2078f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2079f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  // Load *this* actual parameter
2080f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* this_addr = NULL;
2081f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2082f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  if (!is_static) {
2083f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // Test: Is *this* parameter equal to null?
2084f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    this_addr = call_inst.getArgOperand(3);
2085f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  }
2086f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2087f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  // Load the method object
2088f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* callee_method_object_addr = NULL;
2089f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2090f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  if (!is_fast_path) {
2091f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    callee_method_object_addr =
2092f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      EmitCallRuntimeForCalleeMethodObjectAddr(callee_method_idx, invoke_type,
2093f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                                               this_addr, dex_pc, is_fast_path);
2094f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2095920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    if (!is_static && !(opt_flags & MIR_IGNORE_NULL_CHECK)) {
2096f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      EmitGuard_NullPointerException(dex_pc, this_addr);
2097f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    }
2098f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  } else {
2099920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    if (!is_static && !(opt_flags & MIR_IGNORE_NULL_CHECK)) {
2100f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      EmitGuard_NullPointerException(dex_pc, this_addr);
2101f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    }
2102f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2103f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    switch (invoke_type) {
2104920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case art::kStatic:
2105920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case art::kDirect:
2106f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      if (direct_method != 0u &&
2107f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa          direct_method != static_cast<uintptr_t>(-1)) {
2108f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa        callee_method_object_addr =
2109f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa          irb_.CreateIntToPtr(irb_.getPtrEquivInt(direct_method),
2110f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                              irb_.getJObjectTy());
2111f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      } else {
2112f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa        callee_method_object_addr =
2113f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa          EmitLoadSDCalleeMethodObjectAddr(callee_method_idx);
2114f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      }
2115f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      break;
2116f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2117920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case art::kVirtual:
2118f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      DCHECK(vtable_idx != -1);
2119f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      callee_method_object_addr =
2120f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa        EmitLoadVirtualCalleeMethodObjectAddr(vtable_idx, this_addr);
2121f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      break;
2122f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2123920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case art::kSuper:
2124f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      LOG(FATAL) << "invoke-super should be promoted to invoke-direct in "
2125f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                    "the fast path.";
2126f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      break;
2127f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2128920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case art::kInterface:
2129f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      callee_method_object_addr =
2130f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa        EmitCallRuntimeForCalleeMethodObjectAddr(callee_method_idx,
2131f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                                                 invoke_type, this_addr,
2132f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                                                 dex_pc, is_fast_path);
2133f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      break;
2134f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    }
2135f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  }
2136f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2137f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  // Load the actual parameter
2138f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  std::vector<llvm::Value*> args;
2139f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2140f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  args.push_back(callee_method_object_addr); // method object for callee
2141f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2142f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  for (uint32_t i = 3; i < call_inst.getNumArgOperands(); ++i) {
2143f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    args.push_back(call_inst.getArgOperand(i));
2144f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  }
2145f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2146f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* code_addr;
2147f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  if (direct_code != 0u &&
2148f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      direct_code != static_cast<uintptr_t>(-1)) {
2149f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    code_addr =
2150f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      irb_.CreateIntToPtr(irb_.getPtrEquivInt(direct_code),
2151f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                          GetFunctionType(callee_method_idx, is_static)->getPointerTo());
2152f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  } else {
2153f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    code_addr =
2154f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      irb_.LoadFromObjectOffset(callee_method_object_addr,
215598573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers                                art::mirror::AbstractMethod::GetCodeOffset().Int32Value(),
2156f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                                GetFunctionType(callee_method_idx, is_static)->getPointerTo(),
2157ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa                                kTBAARuntimeInfo);
2158f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  }
2159f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2160f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  // Invoke callee
2161f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  EmitUpdateDexPC(dex_pc);
2162f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* retval = irb_.CreateCall(code_addr, args);
2163f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  EmitGuard_ExceptionLandingPad(dex_pc);
2164f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2165f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  return retval;
2166f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa}
2167f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2168f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_OptArrayLength(llvm::CallInst& call_inst) {
2169f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
2170f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  // Get the array object address
2171f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* array_addr = call_inst.getArgOperand(1);
2172920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  int opt_flags = LV2UInt(call_inst.getArgOperand(0));
2173f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2174920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  if (!(opt_flags & MIR_IGNORE_NULL_CHECK)) {
2175920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    EmitGuard_NullPointerException(dex_pc, array_addr);
2176920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  }
2177f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2178f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  // Get the array length and store it to the register
2179f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  return EmitLoadArrayLength(array_addr);
2180f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa}
2181f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2182f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_NewArray(llvm::CallInst& call_inst) {
2183f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
2184f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0));
2185f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* length = call_inst.getArgOperand(1);
2186f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2187f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  return EmitAllocNewArray(dex_pc, length, type_idx, false);
2188f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa}
2189f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2190f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_HLFilledNewArray(llvm::CallInst& call_inst) {
2191f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
2192f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t type_idx = LV2UInt(call_inst.getArgOperand(1));
2193f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t length = call_inst.getNumArgOperands() - 3;
2194f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2195f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* object_addr =
2196f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    EmitAllocNewArray(dex_pc, irb_.getInt32(length), type_idx, true);
2197f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2198f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  if (length > 0) {
2199f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // Check for the element type
2200f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    uint32_t type_desc_len = 0;
2201f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    const char* type_desc =
2202f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      dex_file_->StringByTypeIdx(type_idx, &type_desc_len);
2203f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2204f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    DCHECK_GE(type_desc_len, 2u); // should be guaranteed by verifier
2205f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    DCHECK_EQ(type_desc[0], '['); // should be guaranteed by verifier
2206f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    bool is_elem_int_ty = (type_desc[1] == 'I');
2207f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2208f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    uint32_t alignment;
2209f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Constant* elem_size;
2210f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::PointerType* field_type;
2211f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2212f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // NOTE: Currently filled-new-array only supports 'L', '[', and 'I'
2213f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // as the element, thus we are only checking 2 cases: primitive int and
2214f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // non-primitive type.
2215f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    if (is_elem_int_ty) {
2216f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      alignment = sizeof(int32_t);
2217f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      elem_size = irb_.getPtrEquivInt(sizeof(int32_t));
2218f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      field_type = irb_.getJIntTy()->getPointerTo();
2219f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    } else {
2220f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      alignment = irb_.getSizeOfPtrEquivInt();
2221f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      elem_size = irb_.getSizeOfPtrEquivIntValue();
2222f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      field_type = irb_.getJObjectTy()->getPointerTo();
2223f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    }
2224f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2225f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Value* data_field_offset =
222698573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers      irb_.getPtrEquivInt(art::mirror::Array::DataOffset(alignment).Int32Value());
2227f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2228f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Value* data_field_addr =
2229f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      irb_.CreatePtrDisp(object_addr, data_field_offset, field_type);
2230f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2231f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // TODO: Tune this code.  Currently we are generating one instruction for
2232f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // one element which may be very space consuming.  Maybe changing to use
2233f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // memcpy may help; however, since we can't guarantee that the alloca of
2234f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // dalvik register are continuous, we can't perform such optimization yet.
2235f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    for (uint32_t i = 0; i < length; ++i) {
2236f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      llvm::Value* reg_value = call_inst.getArgOperand(i+3);
2237f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2238f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      irb_.CreateStore(reg_value, data_field_addr, kTBAAHeapArray);
2239f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2240f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      data_field_addr =
2241f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa        irb_.CreatePtrDisp(data_field_addr, elem_size, field_type);
2242f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    }
2243f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  }
2244f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2245f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  return object_addr;
2246f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa}
2247f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2248f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYavoid GBCExpanderPass::Expand_HLFillArrayData(llvm::CallInst& call_inst) {
2249f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
2250f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  int32_t payload_offset = static_cast<int32_t>(dex_pc) +
2251f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                           LV2SInt(call_inst.getArgOperand(0));
2252f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* array_addr = call_inst.getArgOperand(1);
2253f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2254920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  const art::Instruction::ArrayDataPayload* payload =
2255920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    reinterpret_cast<const art::Instruction::ArrayDataPayload*>(
2256f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa        code_item_->insns_ + payload_offset);
2257f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2258f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  if (payload->element_count == 0) {
2259f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // When the number of the elements in the payload is zero, we don't have
2260f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // to copy any numbers.  However, we should check whether the array object
2261f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // address is equal to null or not.
2262f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    EmitGuard_NullPointerException(dex_pc, array_addr);
2263f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  } else {
2264f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // To save the code size, we are going to call the runtime function to
2265f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // copy the content from DexFile.
2266f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2267f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    // NOTE: We will check for the NullPointerException in the runtime.
2268f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2269f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Function* runtime_func = irb_.GetRuntime(runtime_support::FillArrayData);
2270f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2271f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
2272f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2273f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    EmitUpdateDexPC(dex_pc);
2274f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2275f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.CreateCall4(runtime_func,
2276f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                     method_object_addr, irb_.getInt32(dex_pc),
2277f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                     array_addr, irb_.getInt32(payload_offset));
2278f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2279f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    EmitGuard_ExceptionLandingPad(dex_pc);
2280f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  }
2281f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2282f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  return;
2283f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa}
2284f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2285f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::EmitAllocNewArray(uint32_t dex_pc,
2286f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                                                llvm::Value* array_length_value,
2287f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                                                uint32_t type_idx,
2288f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                                                bool is_filled_new_array) {
2289f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Function* runtime_func;
2290f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2291f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  bool skip_access_check =
2292bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao    compiler_->CanAccessTypeWithoutChecks(method_idx_, *dex_file_, type_idx);
2293f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2294f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2295f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  if (is_filled_new_array) {
2296f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    runtime_func = skip_access_check ?
2297f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      irb_.GetRuntime(runtime_support::CheckAndAllocArray) :
2298f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      irb_.GetRuntime(runtime_support::CheckAndAllocArrayWithAccessCheck);
2299f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  } else {
2300f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    runtime_func = skip_access_check ?
2301f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      irb_.GetRuntime(runtime_support::AllocArray) :
2302f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      irb_.GetRuntime(runtime_support::AllocArrayWithAccessCheck);
2303f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  }
2304f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2305f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Constant* type_index_value = irb_.getInt32(type_idx);
2306f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2307f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
2308f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2309f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
2310f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2311f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  EmitUpdateDexPC(dex_pc);
2312f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2313f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* object_addr =
2314f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.CreateCall4(runtime_func, type_index_value, method_object_addr,
2315f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                     array_length_value, thread_object_addr);
2316f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2317f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  EmitGuard_ExceptionLandingPad(dex_pc);
2318f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2319f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  return object_addr;
2320f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa}
2321f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2322f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::
2323f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYaEmitCallRuntimeForCalleeMethodObjectAddr(uint32_t callee_method_idx,
2324920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa                                         art::InvokeType invoke_type,
2325f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                                         llvm::Value* this_addr,
2326f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                                         uint32_t dex_pc,
2327f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                                         bool is_fast_path) {
2328f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2329f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Function* runtime_func = NULL;
2330f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2331f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  switch (invoke_type) {
2332920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  case art::kStatic:
2333f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    runtime_func = irb_.GetRuntime(runtime_support::FindStaticMethodWithAccessCheck);
2334f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    break;
2335f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2336920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  case art::kDirect:
2337f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    runtime_func = irb_.GetRuntime(runtime_support::FindDirectMethodWithAccessCheck);
2338f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    break;
2339f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2340920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  case art::kVirtual:
2341f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    runtime_func = irb_.GetRuntime(runtime_support::FindVirtualMethodWithAccessCheck);
2342f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    break;
2343f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2344920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  case art::kSuper:
2345f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    runtime_func = irb_.GetRuntime(runtime_support::FindSuperMethodWithAccessCheck);
2346f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    break;
2347f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2348920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  case art::kInterface:
2349f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    if (is_fast_path) {
2350f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      runtime_func = irb_.GetRuntime(runtime_support::FindInterfaceMethod);
2351f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    } else {
2352f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      runtime_func = irb_.GetRuntime(runtime_support::FindInterfaceMethodWithAccessCheck);
2353f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    }
2354f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    break;
2355f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  }
2356f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2357f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* callee_method_idx_value = irb_.getInt32(callee_method_idx);
2358f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2359f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  if (this_addr == NULL) {
2360920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    DCHECK_EQ(invoke_type, art::kStatic);
2361f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    this_addr = irb_.getJNull();
2362f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  }
2363f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2364f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* caller_method_object_addr = EmitLoadMethodObjectAddr();
2365f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2366f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
2367f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2368f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  EmitUpdateDexPC(dex_pc);
2369f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2370f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  llvm::Value* callee_method_object_addr =
2371f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    irb_.CreateCall4(runtime_func,
2372f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                     callee_method_idx_value,
2373f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                     this_addr,
2374f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                     caller_method_object_addr,
2375f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                     thread_object_addr);
2376f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2377f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  EmitGuard_ExceptionLandingPad(dex_pc);
2378f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2379f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa  return callee_method_object_addr;
2380f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa}
2381f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
23825e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::EmitMarkGCCard(llvm::Value* value, llvm::Value* target_addr) {
23835e869b6560f918837cc6be3a50234deb2be46385TDYa  // Using runtime support, let the target can override by InlineAssembly.
23845e869b6560f918837cc6be3a50234deb2be46385TDYa  irb_.Runtime().EmitMarkGCCard(value, target_addr);
23855e869b6560f918837cc6be3a50234deb2be46385TDYa}
23865e869b6560f918837cc6be3a50234deb2be46385TDYa
23875e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::EmitUpdateDexPC(uint32_t dex_pc) {
2388bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  if (shadow_frame_ == NULL) {
2389bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao    return;
2390bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  }
23915e869b6560f918837cc6be3a50234deb2be46385TDYa  irb_.StoreToObjectOffset(shadow_frame_,
2392920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa                           art::ShadowFrame::DexPCOffset(),
23935e869b6560f918837cc6be3a50234deb2be46385TDYa                           irb_.getInt32(dex_pc),
23945e869b6560f918837cc6be3a50234deb2be46385TDYa                           kTBAAShadowFrame);
23955e869b6560f918837cc6be3a50234deb2be46385TDYa}
23965e869b6560f918837cc6be3a50234deb2be46385TDYa
23975e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::EmitGuard_DivZeroException(uint32_t dex_pc,
23985e869b6560f918837cc6be3a50234deb2be46385TDYa                                                 llvm::Value* denominator,
23995e869b6560f918837cc6be3a50234deb2be46385TDYa                                                 JType op_jty) {
24005e869b6560f918837cc6be3a50234deb2be46385TDYa  DCHECK(op_jty == kInt || op_jty == kLong) << op_jty;
24015e869b6560f918837cc6be3a50234deb2be46385TDYa
24025e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::Constant* zero = irb_.getJZero(op_jty);
24035e869b6560f918837cc6be3a50234deb2be46385TDYa
24045e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::Value* equal_zero = irb_.CreateICmpEQ(denominator, zero);
24055e869b6560f918837cc6be3a50234deb2be46385TDYa
24065e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::BasicBlock* block_exception = CreateBasicBlockWithDexPC(dex_pc, "div0");
24075e869b6560f918837cc6be3a50234deb2be46385TDYa
24085e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::BasicBlock* block_continue = CreateBasicBlockWithDexPC(dex_pc, "cont");
24095e869b6560f918837cc6be3a50234deb2be46385TDYa
24105e869b6560f918837cc6be3a50234deb2be46385TDYa  irb_.CreateCondBr(equal_zero, block_exception, block_continue, kUnlikely);
24115e869b6560f918837cc6be3a50234deb2be46385TDYa
24125e869b6560f918837cc6be3a50234deb2be46385TDYa  irb_.SetInsertPoint(block_exception);
24135e869b6560f918837cc6be3a50234deb2be46385TDYa  EmitUpdateDexPC(dex_pc);
24145e869b6560f918837cc6be3a50234deb2be46385TDYa  irb_.CreateCall(irb_.GetRuntime(runtime_support::ThrowDivZeroException));
24155e869b6560f918837cc6be3a50234deb2be46385TDYa  EmitBranchExceptionLandingPad(dex_pc);
24165e869b6560f918837cc6be3a50234deb2be46385TDYa
24175e869b6560f918837cc6be3a50234deb2be46385TDYa  irb_.SetInsertPoint(block_continue);
24185e869b6560f918837cc6be3a50234deb2be46385TDYa}
24195e869b6560f918837cc6be3a50234deb2be46385TDYa
24205e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::EmitGuard_NullPointerException(uint32_t dex_pc,
24215e869b6560f918837cc6be3a50234deb2be46385TDYa                                                     llvm::Value* object) {
24225e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::Value* equal_null = irb_.CreateICmpEQ(object, irb_.getJNull());
24235e869b6560f918837cc6be3a50234deb2be46385TDYa
24245e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::BasicBlock* block_exception =
24255e869b6560f918837cc6be3a50234deb2be46385TDYa    CreateBasicBlockWithDexPC(dex_pc, "nullp");
24265e869b6560f918837cc6be3a50234deb2be46385TDYa
24275e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::BasicBlock* block_continue =
24285e869b6560f918837cc6be3a50234deb2be46385TDYa    CreateBasicBlockWithDexPC(dex_pc, "cont");
24295e869b6560f918837cc6be3a50234deb2be46385TDYa
24305e869b6560f918837cc6be3a50234deb2be46385TDYa  irb_.CreateCondBr(equal_null, block_exception, block_continue, kUnlikely);
24315e869b6560f918837cc6be3a50234deb2be46385TDYa
24325e869b6560f918837cc6be3a50234deb2be46385TDYa  irb_.SetInsertPoint(block_exception);
24335e869b6560f918837cc6be3a50234deb2be46385TDYa  EmitUpdateDexPC(dex_pc);
24345e869b6560f918837cc6be3a50234deb2be46385TDYa  irb_.CreateCall(irb_.GetRuntime(runtime_support::ThrowNullPointerException),
24355e869b6560f918837cc6be3a50234deb2be46385TDYa                  irb_.getInt32(dex_pc));
24365e869b6560f918837cc6be3a50234deb2be46385TDYa  EmitBranchExceptionLandingPad(dex_pc);
24375e869b6560f918837cc6be3a50234deb2be46385TDYa
24385e869b6560f918837cc6be3a50234deb2be46385TDYa  irb_.SetInsertPoint(block_continue);
24395e869b6560f918837cc6be3a50234deb2be46385TDYa}
24405e869b6560f918837cc6be3a50234deb2be46385TDYa
24415e869b6560f918837cc6be3a50234deb2be46385TDYavoid
24425e869b6560f918837cc6be3a50234deb2be46385TDYaGBCExpanderPass::EmitGuard_ArrayIndexOutOfBoundsException(uint32_t dex_pc,
24435e869b6560f918837cc6be3a50234deb2be46385TDYa                                                          llvm::Value* array,
24445e869b6560f918837cc6be3a50234deb2be46385TDYa                                                          llvm::Value* index) {
24455e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::Value* array_len = EmitLoadArrayLength(array);
24465e869b6560f918837cc6be3a50234deb2be46385TDYa
24475e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::Value* cmp = irb_.CreateICmpUGE(index, array_len);
24485e869b6560f918837cc6be3a50234deb2be46385TDYa
24495e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::BasicBlock* block_exception =
24505e869b6560f918837cc6be3a50234deb2be46385TDYa    CreateBasicBlockWithDexPC(dex_pc, "overflow");
24515e869b6560f918837cc6be3a50234deb2be46385TDYa
24525e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::BasicBlock* block_continue =
24535e869b6560f918837cc6be3a50234deb2be46385TDYa    CreateBasicBlockWithDexPC(dex_pc, "cont");
24545e869b6560f918837cc6be3a50234deb2be46385TDYa
24555e869b6560f918837cc6be3a50234deb2be46385TDYa  irb_.CreateCondBr(cmp, block_exception, block_continue, kUnlikely);
24565e869b6560f918837cc6be3a50234deb2be46385TDYa
24575e869b6560f918837cc6be3a50234deb2be46385TDYa  irb_.SetInsertPoint(block_exception);
24585e869b6560f918837cc6be3a50234deb2be46385TDYa
24595e869b6560f918837cc6be3a50234deb2be46385TDYa  EmitUpdateDexPC(dex_pc);
24605e869b6560f918837cc6be3a50234deb2be46385TDYa  irb_.CreateCall2(irb_.GetRuntime(runtime_support::ThrowIndexOutOfBounds), index, array_len);
24615e869b6560f918837cc6be3a50234deb2be46385TDYa  EmitBranchExceptionLandingPad(dex_pc);
24625e869b6560f918837cc6be3a50234deb2be46385TDYa
24635e869b6560f918837cc6be3a50234deb2be46385TDYa  irb_.SetInsertPoint(block_continue);
24645e869b6560f918837cc6be3a50234deb2be46385TDYa}
24655e869b6560f918837cc6be3a50234deb2be46385TDYa
24665e869b6560f918837cc6be3a50234deb2be46385TDYallvm::FunctionType* GBCExpanderPass::GetFunctionType(uint32_t method_idx,
24675e869b6560f918837cc6be3a50234deb2be46385TDYa                                                     bool is_static) {
24685e869b6560f918837cc6be3a50234deb2be46385TDYa  // Get method signature
2469920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  art::DexFile::MethodId const& method_id = dex_file_->GetMethodId(method_idx);
24705e869b6560f918837cc6be3a50234deb2be46385TDYa
24715e869b6560f918837cc6be3a50234deb2be46385TDYa  uint32_t shorty_size;
24725e869b6560f918837cc6be3a50234deb2be46385TDYa  const char* shorty = dex_file_->GetMethodShorty(method_id, &shorty_size);
24735e869b6560f918837cc6be3a50234deb2be46385TDYa  CHECK_GE(shorty_size, 1u);
24745e869b6560f918837cc6be3a50234deb2be46385TDYa
24755e869b6560f918837cc6be3a50234deb2be46385TDYa  // Get return type
2476bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao
2477bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  char ret_shorty = shorty[0];
247826f10eed520942d3db754c31941e457048475f61buzbee  ret_shorty = art::RemapShorty(ret_shorty);
2479bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  llvm::Type* ret_type = irb_.getJType(ret_shorty, kAccurate);
24805e869b6560f918837cc6be3a50234deb2be46385TDYa
24815e869b6560f918837cc6be3a50234deb2be46385TDYa  // Get argument type
24825e869b6560f918837cc6be3a50234deb2be46385TDYa  std::vector<llvm::Type*> args_type;
24835e869b6560f918837cc6be3a50234deb2be46385TDYa
24845e869b6560f918837cc6be3a50234deb2be46385TDYa  args_type.push_back(irb_.getJObjectTy()); // method object pointer
24855e869b6560f918837cc6be3a50234deb2be46385TDYa
24865e869b6560f918837cc6be3a50234deb2be46385TDYa  if (!is_static) {
24875e869b6560f918837cc6be3a50234deb2be46385TDYa    args_type.push_back(irb_.getJType('L', kAccurate)); // "this" object pointer
24885e869b6560f918837cc6be3a50234deb2be46385TDYa  }
24895e869b6560f918837cc6be3a50234deb2be46385TDYa
24905e869b6560f918837cc6be3a50234deb2be46385TDYa  for (uint32_t i = 1; i < shorty_size; ++i) {
249126f10eed520942d3db754c31941e457048475f61buzbee    char shorty_type = art::RemapShorty(shorty[i]);
2492f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    args_type.push_back(irb_.getJType(shorty_type, kAccurate));
24935e869b6560f918837cc6be3a50234deb2be46385TDYa  }
24945e869b6560f918837cc6be3a50234deb2be46385TDYa
24955e869b6560f918837cc6be3a50234deb2be46385TDYa  return llvm::FunctionType::get(ret_type, args_type, false);
24965e869b6560f918837cc6be3a50234deb2be46385TDYa}
24975e869b6560f918837cc6be3a50234deb2be46385TDYa
24985e869b6560f918837cc6be3a50234deb2be46385TDYa
24995e869b6560f918837cc6be3a50234deb2be46385TDYallvm::BasicBlock* GBCExpanderPass::
25005e869b6560f918837cc6be3a50234deb2be46385TDYaCreateBasicBlockWithDexPC(uint32_t dex_pc, const char* postfix) {
25015e869b6560f918837cc6be3a50234deb2be46385TDYa  std::string name;
25025e869b6560f918837cc6be3a50234deb2be46385TDYa
25035e869b6560f918837cc6be3a50234deb2be46385TDYa#if !defined(NDEBUG)
2504920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  art::StringAppendF(&name, "B%04x.%s", dex_pc, postfix);
25055e869b6560f918837cc6be3a50234deb2be46385TDYa#endif
25065e869b6560f918837cc6be3a50234deb2be46385TDYa
25075e869b6560f918837cc6be3a50234deb2be46385TDYa  return llvm::BasicBlock::Create(context_, name, func_);
25085e869b6560f918837cc6be3a50234deb2be46385TDYa}
25095e869b6560f918837cc6be3a50234deb2be46385TDYa
25105e869b6560f918837cc6be3a50234deb2be46385TDYallvm::BasicBlock* GBCExpanderPass::GetBasicBlock(uint32_t dex_pc) {
25115e869b6560f918837cc6be3a50234deb2be46385TDYa  DCHECK(dex_pc < code_item_->insns_size_in_code_units_);
2512bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  CHECK(basic_blocks_[dex_pc] != NULL);
25135e869b6560f918837cc6be3a50234deb2be46385TDYa  return basic_blocks_[dex_pc];
25145e869b6560f918837cc6be3a50234deb2be46385TDYa}
25155e869b6560f918837cc6be3a50234deb2be46385TDYa
25165e869b6560f918837cc6be3a50234deb2be46385TDYaint32_t GBCExpanderPass::GetTryItemOffset(uint32_t dex_pc) {
25175e869b6560f918837cc6be3a50234deb2be46385TDYa  int32_t min = 0;
25185e869b6560f918837cc6be3a50234deb2be46385TDYa  int32_t max = code_item_->tries_size_ - 1;
25195e869b6560f918837cc6be3a50234deb2be46385TDYa
25205e869b6560f918837cc6be3a50234deb2be46385TDYa  while (min <= max) {
25215e869b6560f918837cc6be3a50234deb2be46385TDYa    int32_t mid = min + (max - min) / 2;
25225e869b6560f918837cc6be3a50234deb2be46385TDYa
2523920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    const art::DexFile::TryItem* ti = art::DexFile::GetTryItems(*code_item_, mid);
25245e869b6560f918837cc6be3a50234deb2be46385TDYa    uint32_t start = ti->start_addr_;
25255e869b6560f918837cc6be3a50234deb2be46385TDYa    uint32_t end = start + ti->insn_count_;
25265e869b6560f918837cc6be3a50234deb2be46385TDYa
25275e869b6560f918837cc6be3a50234deb2be46385TDYa    if (dex_pc < start) {
25285e869b6560f918837cc6be3a50234deb2be46385TDYa      max = mid - 1;
25295e869b6560f918837cc6be3a50234deb2be46385TDYa    } else if (dex_pc >= end) {
25305e869b6560f918837cc6be3a50234deb2be46385TDYa      min = mid + 1;
25315e869b6560f918837cc6be3a50234deb2be46385TDYa    } else {
25325e869b6560f918837cc6be3a50234deb2be46385TDYa      return mid; // found
25335e869b6560f918837cc6be3a50234deb2be46385TDYa    }
25345e869b6560f918837cc6be3a50234deb2be46385TDYa  }
25355e869b6560f918837cc6be3a50234deb2be46385TDYa
25365e869b6560f918837cc6be3a50234deb2be46385TDYa  return -1; // not found
25375e869b6560f918837cc6be3a50234deb2be46385TDYa}
25385e869b6560f918837cc6be3a50234deb2be46385TDYa
25395e869b6560f918837cc6be3a50234deb2be46385TDYallvm::BasicBlock* GBCExpanderPass::GetLandingPadBasicBlock(uint32_t dex_pc) {
25405e869b6560f918837cc6be3a50234deb2be46385TDYa  // Find the try item for this address in this method
25415e869b6560f918837cc6be3a50234deb2be46385TDYa  int32_t ti_offset = GetTryItemOffset(dex_pc);
25425e869b6560f918837cc6be3a50234deb2be46385TDYa
25435e869b6560f918837cc6be3a50234deb2be46385TDYa  if (ti_offset == -1) {
25445e869b6560f918837cc6be3a50234deb2be46385TDYa    return NULL; // No landing pad is available for this address.
25455e869b6560f918837cc6be3a50234deb2be46385TDYa  }
25465e869b6560f918837cc6be3a50234deb2be46385TDYa
25475e869b6560f918837cc6be3a50234deb2be46385TDYa  // Check for the existing landing pad basic block
25485e869b6560f918837cc6be3a50234deb2be46385TDYa  DCHECK_GT(basic_block_landing_pads_.size(), static_cast<size_t>(ti_offset));
25495e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::BasicBlock* block_lpad = basic_block_landing_pads_[ti_offset];
25505e869b6560f918837cc6be3a50234deb2be46385TDYa
25515e869b6560f918837cc6be3a50234deb2be46385TDYa  if (block_lpad) {
25525e869b6560f918837cc6be3a50234deb2be46385TDYa    // We have generated landing pad for this try item already.  Return the
25535e869b6560f918837cc6be3a50234deb2be46385TDYa    // same basic block.
25545e869b6560f918837cc6be3a50234deb2be46385TDYa    return block_lpad;
25555e869b6560f918837cc6be3a50234deb2be46385TDYa  }
25565e869b6560f918837cc6be3a50234deb2be46385TDYa
25575e869b6560f918837cc6be3a50234deb2be46385TDYa  // Get try item from code item
2558920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  const art::DexFile::TryItem* ti = art::DexFile::GetTryItems(*code_item_, ti_offset);
25595e869b6560f918837cc6be3a50234deb2be46385TDYa
25605e869b6560f918837cc6be3a50234deb2be46385TDYa  std::string lpadname;
25615e869b6560f918837cc6be3a50234deb2be46385TDYa
25625e869b6560f918837cc6be3a50234deb2be46385TDYa#if !defined(NDEBUG)
2563920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  art::StringAppendF(&lpadname, "lpad%d_%04x_to_%04x", ti_offset, ti->start_addr_, ti->handler_off_);
25645e869b6560f918837cc6be3a50234deb2be46385TDYa#endif
25655e869b6560f918837cc6be3a50234deb2be46385TDYa
25665e869b6560f918837cc6be3a50234deb2be46385TDYa  // Create landing pad basic block
25675e869b6560f918837cc6be3a50234deb2be46385TDYa  block_lpad = llvm::BasicBlock::Create(context_, lpadname, func_);
25685e869b6560f918837cc6be3a50234deb2be46385TDYa
25695e869b6560f918837cc6be3a50234deb2be46385TDYa  // Change IRBuilder insert point
25705e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP();
25715e869b6560f918837cc6be3a50234deb2be46385TDYa  irb_.SetInsertPoint(block_lpad);
25725e869b6560f918837cc6be3a50234deb2be46385TDYa
25735e869b6560f918837cc6be3a50234deb2be46385TDYa  // Find catch block with matching type
25745e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
25755e869b6560f918837cc6be3a50234deb2be46385TDYa
25765e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::Value* ti_offset_value = irb_.getInt32(ti_offset);
25775e869b6560f918837cc6be3a50234deb2be46385TDYa
25785e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::Value* catch_handler_index_value =
25795e869b6560f918837cc6be3a50234deb2be46385TDYa    irb_.CreateCall2(irb_.GetRuntime(runtime_support::FindCatchBlock),
25805e869b6560f918837cc6be3a50234deb2be46385TDYa                     method_object_addr, ti_offset_value);
25815e869b6560f918837cc6be3a50234deb2be46385TDYa
25825e869b6560f918837cc6be3a50234deb2be46385TDYa  // Switch instruction (Go to unwind basic block by default)
25835e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::SwitchInst* sw =
25845e869b6560f918837cc6be3a50234deb2be46385TDYa    irb_.CreateSwitch(catch_handler_index_value, GetUnwindBasicBlock());
25855e869b6560f918837cc6be3a50234deb2be46385TDYa
25865e869b6560f918837cc6be3a50234deb2be46385TDYa  // Cases with matched catch block
2587920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa  art::CatchHandlerIterator iter(*code_item_, ti->start_addr_);
25885e869b6560f918837cc6be3a50234deb2be46385TDYa
25895e869b6560f918837cc6be3a50234deb2be46385TDYa  for (uint32_t c = 0; iter.HasNext(); iter.Next(), ++c) {
25905e869b6560f918837cc6be3a50234deb2be46385TDYa    sw->addCase(irb_.getInt32(c), GetBasicBlock(iter.GetHandlerAddress()));
25915e869b6560f918837cc6be3a50234deb2be46385TDYa  }
25925e869b6560f918837cc6be3a50234deb2be46385TDYa
25935e869b6560f918837cc6be3a50234deb2be46385TDYa  // Restore the orignal insert point for IRBuilder
25945e869b6560f918837cc6be3a50234deb2be46385TDYa  irb_.restoreIP(irb_ip_original);
25955e869b6560f918837cc6be3a50234deb2be46385TDYa
25965e869b6560f918837cc6be3a50234deb2be46385TDYa  // Cache this landing pad
25975e869b6560f918837cc6be3a50234deb2be46385TDYa  DCHECK_GT(basic_block_landing_pads_.size(), static_cast<size_t>(ti_offset));
25985e869b6560f918837cc6be3a50234deb2be46385TDYa  basic_block_landing_pads_[ti_offset] = block_lpad;
25995e869b6560f918837cc6be3a50234deb2be46385TDYa
26005e869b6560f918837cc6be3a50234deb2be46385TDYa  return block_lpad;
26015e869b6560f918837cc6be3a50234deb2be46385TDYa}
26025e869b6560f918837cc6be3a50234deb2be46385TDYa
26035e869b6560f918837cc6be3a50234deb2be46385TDYallvm::BasicBlock* GBCExpanderPass::GetUnwindBasicBlock() {
26045e869b6560f918837cc6be3a50234deb2be46385TDYa  // Check the existing unwinding baisc block block
26055e869b6560f918837cc6be3a50234deb2be46385TDYa  if (basic_block_unwind_ != NULL) {
26065e869b6560f918837cc6be3a50234deb2be46385TDYa    return basic_block_unwind_;
26075e869b6560f918837cc6be3a50234deb2be46385TDYa  }
26085e869b6560f918837cc6be3a50234deb2be46385TDYa
26095e869b6560f918837cc6be3a50234deb2be46385TDYa  // Create new basic block for unwinding
26105e869b6560f918837cc6be3a50234deb2be46385TDYa  basic_block_unwind_ =
26115e869b6560f918837cc6be3a50234deb2be46385TDYa    llvm::BasicBlock::Create(context_, "exception_unwind", func_);
26125e869b6560f918837cc6be3a50234deb2be46385TDYa
26135e869b6560f918837cc6be3a50234deb2be46385TDYa  // Change IRBuilder insert point
26145e869b6560f918837cc6be3a50234deb2be46385TDYa  llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP();
26155e869b6560f918837cc6be3a50234deb2be46385TDYa  irb_.SetInsertPoint(basic_block_unwind_);
26165e869b6560f918837cc6be3a50234deb2be46385TDYa
26175e869b6560f918837cc6be3a50234deb2be46385TDYa  // Pop the shadow frame
26185e869b6560f918837cc6be3a50234deb2be46385TDYa  Expand_PopShadowFrame();
26195e869b6560f918837cc6be3a50234deb2be46385TDYa
26205e869b6560f918837cc6be3a50234deb2be46385TDYa  // Emit the code to return default value (zero) for the given return type.
26215e869b6560f918837cc6be3a50234deb2be46385TDYa  char ret_shorty = oat_compilation_unit_->GetShorty()[0];
262226f10eed520942d3db754c31941e457048475f61buzbee  ret_shorty = art::RemapShorty(ret_shorty);
26235e869b6560f918837cc6be3a50234deb2be46385TDYa  if (ret_shorty == 'V') {
26245e869b6560f918837cc6be3a50234deb2be46385TDYa    irb_.CreateRetVoid();
26255e869b6560f918837cc6be3a50234deb2be46385TDYa  } else {
26265e869b6560f918837cc6be3a50234deb2be46385TDYa    irb_.CreateRet(irb_.getJZero(ret_shorty));
26275e869b6560f918837cc6be3a50234deb2be46385TDYa  }
26285e869b6560f918837cc6be3a50234deb2be46385TDYa
26295e869b6560f918837cc6be3a50234deb2be46385TDYa  // Restore the orignal insert point for IRBuilder
26305e869b6560f918837cc6be3a50234deb2be46385TDYa  irb_.restoreIP(irb_ip_original);
26315e869b6560f918837cc6be3a50234deb2be46385TDYa
26325e869b6560f918837cc6be3a50234deb2be46385TDYa  return basic_block_unwind_;
26335e869b6560f918837cc6be3a50234deb2be46385TDYa}
26345e869b6560f918837cc6be3a50234deb2be46385TDYa
26355e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::EmitBranchExceptionLandingPad(uint32_t dex_pc) {
26365e869b6560f918837cc6be3a50234deb2be46385TDYa  if (llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc)) {
263755e5e6c5702e3f1f68bd83ae741af769740d9a74TDYa    landing_pad_phi_mapping_[lpad].push_back(std::make_pair(current_bb_->getUniquePredecessor(),
2638aa55887fd30484a77e7775dfbcddbee883ce6380TDYa                                                            irb_.GetInsertBlock()));
26395e869b6560f918837cc6be3a50234deb2be46385TDYa    irb_.CreateBr(lpad);
26405e869b6560f918837cc6be3a50234deb2be46385TDYa  } else {
26415e869b6560f918837cc6be3a50234deb2be46385TDYa    irb_.CreateBr(GetUnwindBasicBlock());
26425e869b6560f918837cc6be3a50234deb2be46385TDYa  }
26435e869b6560f918837cc6be3a50234deb2be46385TDYa}
26445e869b6560f918837cc6be3a50234deb2be46385TDYa
26455e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::EmitGuard_ExceptionLandingPad(uint32_t dex_pc) {
26469a14265c911b2e63bec51a814b8b6fd157745b57Jeff Hao  llvm::Value* exception_pending = irb_.Runtime().EmitIsExceptionPending();
2647a1ae861c673ab5160a2a7afee2ada806cb61966bjeffhao
26489a14265c911b2e63bec51a814b8b6fd157745b57Jeff Hao  llvm::BasicBlock* block_cont = CreateBasicBlockWithDexPC(dex_pc, "cont");
26495e869b6560f918837cc6be3a50234deb2be46385TDYa
26505e869b6560f918837cc6be3a50234deb2be46385TDYa  if (llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc)) {
265155e5e6c5702e3f1f68bd83ae741af769740d9a74TDYa    landing_pad_phi_mapping_[lpad].push_back(std::make_pair(current_bb_->getUniquePredecessor(),
2652aa55887fd30484a77e7775dfbcddbee883ce6380TDYa                                                            irb_.GetInsertBlock()));
26539a14265c911b2e63bec51a814b8b6fd157745b57Jeff Hao    irb_.CreateCondBr(exception_pending, lpad, block_cont, kUnlikely);
26545e869b6560f918837cc6be3a50234deb2be46385TDYa  } else {
26559a14265c911b2e63bec51a814b8b6fd157745b57Jeff Hao    irb_.CreateCondBr(exception_pending, GetUnwindBasicBlock(), block_cont, kUnlikely);
26565e869b6560f918837cc6be3a50234deb2be46385TDYa  }
26575e869b6560f918837cc6be3a50234deb2be46385TDYa
26585e869b6560f918837cc6be3a50234deb2be46385TDYa  irb_.SetInsertPoint(block_cont);
26595e869b6560f918837cc6be3a50234deb2be46385TDYa}
26605e869b6560f918837cc6be3a50234deb2be46385TDYa
266121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value*
266221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::ExpandIntrinsic(IntrinsicHelper::IntrinsicId intr_id,
266321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                                 llvm::CallInst& call_inst) {
266421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  switch (intr_id) {
266521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    //==- Thread -----------------------------------------------------------==//
266621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::GetCurrentThread: {
2667b672d1e48b6e02bb69c7cd9bcfa7509c81514c07TDYa      return irb_.Runtime().EmitGetCurrentThread();
266821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
266975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::CheckSuspend: {
2670ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa      Expand_TestSuspend(call_inst);
2671890ea89879ba555a08433146058d516575646c59TDYa      return NULL;
2672890ea89879ba555a08433146058d516575646c59TDYa    }
2673890ea89879ba555a08433146058d516575646c59TDYa    case IntrinsicHelper::TestSuspend: {
2674d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien      Expand_TestSuspend(call_inst);
267575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
267675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
267721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::MarkGCCard: {
26789a129457c233b653c7a8f65c963509267252b0a7TDYa      Expand_MarkGCCard(call_inst);
26799a129457c233b653c7a8f65c963509267252b0a7TDYa      return NULL;
268021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
268175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
268221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    //==- Exception --------------------------------------------------------==//
268321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ThrowException: {
268421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::ThrowException, call_inst);
268521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
2686f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    case IntrinsicHelper::HLThrowException: {
2687f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
2688f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2689f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      EmitUpdateDexPC(dex_pc);
2690f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2691f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      irb_.CreateCall(irb_.GetRuntime(runtime_support::ThrowException),
2692f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa                      call_inst.getArgOperand(0));
2693f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa
2694f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      EmitGuard_ExceptionLandingPad(dex_pc);
2695f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      return NULL;
2696f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    }
269721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::GetException: {
2698823433dbf4afec17169d5ca738031af5b374e140TDYa      return irb_.Runtime().EmitGetAndClearException();
269921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
270021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::IsExceptionPending: {
270121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return irb_.Runtime().EmitIsExceptionPending();
270221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
270321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::FindCatchBlock: {
270421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::FindCatchBlock, call_inst);
270521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
270621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ThrowDivZeroException: {
270721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::ThrowDivZeroException, call_inst);
270821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
270921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ThrowNullPointerException: {
271021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::ThrowNullPointerException, call_inst);
271121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
271221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ThrowIndexOutOfBounds: {
271321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::ThrowIndexOutOfBounds, call_inst);
271421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
271575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
271675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    //==- Const String -----------------------------------------------------==//
271775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::ConstString: {
2718f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      return Expand_ConstString(call_inst);
271975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
272021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::LoadStringFromDexCache: {
272121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_LoadStringFromDexCache(call_inst.getArgOperand(0));
272221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
272321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ResolveString: {
272421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::ResolveString, call_inst);
272521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
272675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
272775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    //==- Const Class ------------------------------------------------------==//
272875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::ConstClass: {
2729f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      return Expand_ConstClass(call_inst);
273075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
273121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InitializeTypeAndVerifyAccess: {
273221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::InitializeTypeAndVerifyAccess, call_inst);
273321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
273421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::LoadTypeFromDexCache: {
273521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_LoadTypeFromDexCache(call_inst.getArgOperand(0));
273621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
273721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InitializeType: {
273821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::InitializeType, call_inst);
273921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
274075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
274121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    //==- Lock -------------------------------------------------------------==//
274221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::LockObject: {
274321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_LockObject(call_inst.getArgOperand(0));
274421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
274521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
274621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::UnlockObject: {
274721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_UnlockObject(call_inst.getArgOperand(0));
274821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
274921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
275075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
275121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    //==- Cast -------------------------------------------------------------==//
275221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::CheckCast: {
275321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::CheckCast, call_inst);
275421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
275575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLCheckCast: {
2756f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      Expand_HLCheckCast(call_inst);
275775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
275875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
275921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::IsAssignable: {
276021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::IsAssignable, call_inst);
276121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
276275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
276321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    //==- Alloc ------------------------------------------------------------==//
276421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::AllocObject: {
276521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::AllocObject, call_inst);
276621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
276721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::AllocObjectWithAccessCheck: {
276821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::AllocObjectWithAccessCheck, call_inst);
276921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
277075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
277175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    //==- Instance ---------------------------------------------------------==//
277275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::NewInstance: {
2773f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      return Expand_NewInstance(call_inst);
277475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
277575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::InstanceOf: {
2776f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      return Expand_InstanceOf(call_inst);
277775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
277875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
277921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    //==- Array ------------------------------------------------------------==//
278075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::NewArray: {
2781f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      return Expand_NewArray(call_inst);
278275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
278375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::OptArrayLength: {
2784f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      return Expand_OptArrayLength(call_inst);
278575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
278621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ArrayLength: {
278721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return EmitLoadArrayLength(call_inst.getArgOperand(0));
278821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
278921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::AllocArray: {
279021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::AllocArray, call_inst);
279121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
279221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::AllocArrayWithAccessCheck: {
279321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::AllocArrayWithAccessCheck,
279421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst);
279521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
279621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::CheckAndAllocArray: {
279721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::CheckAndAllocArray, call_inst);
279821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
279921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::CheckAndAllocArrayWithAccessCheck: {
280021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::CheckAndAllocArrayWithAccessCheck,
280121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst);
280221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
280321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ArrayGet: {
280421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_ArrayGet(call_inst.getArgOperand(0),
280521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
280621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kInt);
280721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
280821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ArrayGetWide: {
280921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_ArrayGet(call_inst.getArgOperand(0),
281021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
281121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kLong);
281221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
281321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ArrayGetObject: {
281421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_ArrayGet(call_inst.getArgOperand(0),
281521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
281621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kObject);
281721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
281821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ArrayGetBoolean: {
281921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_ArrayGet(call_inst.getArgOperand(0),
282021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
282121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kBoolean);
282221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
282321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ArrayGetByte: {
282421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_ArrayGet(call_inst.getArgOperand(0),
282521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
282621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kByte);
282721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
282821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ArrayGetChar: {
282921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_ArrayGet(call_inst.getArgOperand(0),
283021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
283121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kChar);
283221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
283321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ArrayGetShort: {
283421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_ArrayGet(call_inst.getArgOperand(0),
283521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
283621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kShort);
283721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
283821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ArrayPut: {
283921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_ArrayPut(call_inst.getArgOperand(0),
284021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
284121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
284221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kInt);
284321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
284421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
284521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ArrayPutWide: {
284621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_ArrayPut(call_inst.getArgOperand(0),
284721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
284821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
284921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kLong);
285021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
285121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
285221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ArrayPutObject: {
285321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_ArrayPut(call_inst.getArgOperand(0),
285421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
285521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
285621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kObject);
285721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
285821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
285921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ArrayPutBoolean: {
286021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_ArrayPut(call_inst.getArgOperand(0),
286121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
286221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
286321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kBoolean);
286421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
286521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
286621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ArrayPutByte: {
286721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_ArrayPut(call_inst.getArgOperand(0),
286821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
286921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
287021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kByte);
287121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
287221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
287321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ArrayPutChar: {
287421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_ArrayPut(call_inst.getArgOperand(0),
287521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
287621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
287721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kChar);
287821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
287921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
288021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::ArrayPutShort: {
288121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_ArrayPut(call_inst.getArgOperand(0),
288221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
288321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
288421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kShort);
288521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
288621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
288721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::CheckPutArrayElement: {
288821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::CheckPutArrayElement, call_inst);
288921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
289021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::FilledNewArray: {
289121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_FilledNewArray(call_inst);
289221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
289321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
289421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::FillArrayData: {
289521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::FillArrayData, call_inst);
289621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
289775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLFillArrayData: {
2898f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      Expand_HLFillArrayData(call_inst);
289975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
290075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
290175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLFilledNewArray: {
2902f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      return Expand_HLFilledNewArray(call_inst);
290375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
290475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
290521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    //==- Instance Field ---------------------------------------------------==//
290621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldGet:
290721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldGetBoolean:
290821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldGetByte:
290921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldGetChar:
291021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldGetShort: {
291121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::Get32Instance, call_inst);
291221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
291321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldGetWide: {
291421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::Get64Instance, call_inst);
291521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
291621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldGetObject: {
291721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::GetObjectInstance, call_inst);
291821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
291921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldGetFast: {
292021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_IGetFast(call_inst.getArgOperand(0),
292121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
292221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(2),
292321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kInt);
292421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
292521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldGetWideFast: {
292621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_IGetFast(call_inst.getArgOperand(0),
292721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
292821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(2),
292921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kLong);
293021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
293121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldGetObjectFast: {
293221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_IGetFast(call_inst.getArgOperand(0),
293321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
293421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(2),
293521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kObject);
293621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
293721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldGetBooleanFast: {
293821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_IGetFast(call_inst.getArgOperand(0),
293921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
294021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(2),
294121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kBoolean);
294221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
294321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldGetByteFast: {
294421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_IGetFast(call_inst.getArgOperand(0),
294521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
294621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(2),
294721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kByte);
294821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
294921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldGetCharFast: {
295021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_IGetFast(call_inst.getArgOperand(0),
295121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
295221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(2),
295321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kChar);
295421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
295521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldGetShortFast: {
295621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_IGetFast(call_inst.getArgOperand(0),
295721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
295821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(2),
295921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kShort);
296021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
296121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldPut:
296221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldPutBoolean:
296321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldPutByte:
296421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldPutChar:
296521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldPutShort: {
296621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::Set32Instance, call_inst);
296721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
296821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldPutWide: {
296921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::Set64Instance, call_inst);
297021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
297121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldPutObject: {
297221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::SetObjectInstance, call_inst);
297321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
297421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldPutFast: {
297521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_IPutFast(call_inst.getArgOperand(0),
297621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
297721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
297821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(3),
297921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kInt);
298021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
298121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
298221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldPutWideFast: {
298321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_IPutFast(call_inst.getArgOperand(0),
298421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
298521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
298621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(3),
298721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kLong);
298821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
298921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
299021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldPutObjectFast: {
299121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_IPutFast(call_inst.getArgOperand(0),
299221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
299321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
299421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(3),
299521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kObject);
299621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
299721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
299821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldPutBooleanFast: {
299921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_IPutFast(call_inst.getArgOperand(0),
300021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
300121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
300221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(3),
300321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kBoolean);
300421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
300521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
300621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldPutByteFast: {
300721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_IPutFast(call_inst.getArgOperand(0),
300821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
300921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
301021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(3),
301121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kByte);
301221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
301321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
301421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldPutCharFast: {
301521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_IPutFast(call_inst.getArgOperand(0),
301621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
301721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
301821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(3),
301921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kChar);
302021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
302121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
302221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InstanceFieldPutShortFast: {
302321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_IPutFast(call_inst.getArgOperand(0),
302421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
302521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
302621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(3),
302721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kShort);
302821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
302921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
303075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
303121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    //==- Static Field -----------------------------------------------------==//
303221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldGet:
303321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldGetBoolean:
303421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldGetByte:
303521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldGetChar:
303621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldGetShort: {
303721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::Get32Static, call_inst);
303821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
303921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldGetWide: {
304021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::Get64Static, call_inst);
304121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
304221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldGetObject: {
304321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::GetObjectStatic, call_inst);
304421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
304521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldGetFast: {
304621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_SGetFast(call_inst.getArgOperand(0),
304721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
304821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(2),
304921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kInt);
305021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
305121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldGetWideFast: {
305221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_SGetFast(call_inst.getArgOperand(0),
305321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
305421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(2),
305521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kLong);
305621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
305721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldGetObjectFast: {
305821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_SGetFast(call_inst.getArgOperand(0),
305921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
306021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(2),
306121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kObject);
306221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
306321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldGetBooleanFast: {
306421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_SGetFast(call_inst.getArgOperand(0),
306521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
306621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(2),
306721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kBoolean);
306821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
306921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldGetByteFast: {
307021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_SGetFast(call_inst.getArgOperand(0),
307121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
307221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(2),
307321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kByte);
307421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
307521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldGetCharFast: {
307621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_SGetFast(call_inst.getArgOperand(0),
307721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
307821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(2),
307921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kChar);
308021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
308121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldGetShortFast: {
308221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_SGetFast(call_inst.getArgOperand(0),
308321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(1),
308421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             call_inst.getArgOperand(2),
308521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                             kShort);
308621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
308721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldPut:
308821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldPutBoolean:
308921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldPutByte:
309021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldPutChar:
309121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldPutShort: {
309221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::Set32Static, call_inst);
309321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
309421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldPutWide: {
309521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::Set64Static, call_inst);
309621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
309721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldPutObject: {
309821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::SetObjectStatic, call_inst);
309921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
310021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldPutFast: {
310121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_SPutFast(call_inst.getArgOperand(0),
310221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
310321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
310421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(3),
310521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kInt);
310621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
310721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
310821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldPutWideFast: {
310921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_SPutFast(call_inst.getArgOperand(0),
311021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
311121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
311221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(3),
311321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kLong);
311421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
311521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
311621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldPutObjectFast: {
311721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_SPutFast(call_inst.getArgOperand(0),
311821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
311921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
312021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(3),
312121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kObject);
312221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
312321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
312421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldPutBooleanFast: {
312521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_SPutFast(call_inst.getArgOperand(0),
312621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
312721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
312821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(3),
312921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kBoolean);
313021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
313121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
313221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldPutByteFast: {
313321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_SPutFast(call_inst.getArgOperand(0),
313421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
313521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
313621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(3),
313721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kByte);
313821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
313921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
314021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldPutCharFast: {
314121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_SPutFast(call_inst.getArgOperand(0),
314221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
314321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
314421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(3),
314521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kChar);
314621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
314721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
314821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::StaticFieldPutShortFast: {
314921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_SPutFast(call_inst.getArgOperand(0),
315021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(1),
315121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(2),
315221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      call_inst.getArgOperand(3),
315321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                      kShort);
315421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
315521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
315621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::LoadDeclaringClassSSB: {
315721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_LoadDeclaringClassSSB(call_inst.getArgOperand(0));
315821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
315921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::LoadClassSSBFromDexCache: {
316021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_LoadClassSSBFromDexCache(call_inst.getArgOperand(0));
316121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
316221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InitializeAndLoadClassSSB: {
316321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::InitializeStaticStorage, call_inst);
316421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
316575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
316675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    //==- High-level Array -------------------------------------------------==//
316775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLArrayGet: {
31685a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      return Expand_HLArrayGet(call_inst, kInt);
316975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
317075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLArrayGetBoolean: {
31715a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      return Expand_HLArrayGet(call_inst, kBoolean);
317275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
317375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLArrayGetByte: {
31745a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      return Expand_HLArrayGet(call_inst, kByte);
317575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
317675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLArrayGetChar: {
31775a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      return Expand_HLArrayGet(call_inst, kChar);
317875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
317975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLArrayGetShort: {
31805a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      return Expand_HLArrayGet(call_inst, kShort);
318175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
318275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLArrayGetFloat: {
31835a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      return Expand_HLArrayGet(call_inst, kFloat);
318475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
318575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLArrayGetWide: {
31865a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      return Expand_HLArrayGet(call_inst, kLong);
318775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
318875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLArrayGetDouble: {
31895a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      return Expand_HLArrayGet(call_inst, kDouble);
319075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
319175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLArrayGetObject: {
31925a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      return Expand_HLArrayGet(call_inst, kObject);
319375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
319475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLArrayPut: {
31955a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      Expand_HLArrayPut(call_inst, kInt);
319675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
319775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
319875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLArrayPutBoolean: {
31995a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      Expand_HLArrayPut(call_inst, kBoolean);
320075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
320175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
320275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLArrayPutByte: {
32035a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      Expand_HLArrayPut(call_inst, kByte);
320475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
320575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
320675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLArrayPutChar: {
32075a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      Expand_HLArrayPut(call_inst, kChar);
320875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
320975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
321075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLArrayPutShort: {
32115a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      Expand_HLArrayPut(call_inst, kShort);
321275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
321375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
321475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLArrayPutFloat: {
32155a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      Expand_HLArrayPut(call_inst, kFloat);
321675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
321775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
321875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLArrayPutWide: {
32195a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      Expand_HLArrayPut(call_inst, kLong);
322075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
322175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
322275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLArrayPutDouble: {
32235a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      Expand_HLArrayPut(call_inst, kDouble);
322475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
322575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
322675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLArrayPutObject: {
32275a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      Expand_HLArrayPut(call_inst, kObject);
322875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
322975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
323075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
323175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    //==- High-level Instance ----------------------------------------------==//
323275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLIGet: {
32335e869b6560f918837cc6be3a50234deb2be46385TDYa      return Expand_HLIGet(call_inst, kInt);
323475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
323575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLIGetBoolean: {
32365e869b6560f918837cc6be3a50234deb2be46385TDYa      return Expand_HLIGet(call_inst, kBoolean);
323775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
323875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLIGetByte: {
32395e869b6560f918837cc6be3a50234deb2be46385TDYa      return Expand_HLIGet(call_inst, kByte);
324075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
324175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLIGetChar: {
32425e869b6560f918837cc6be3a50234deb2be46385TDYa      return Expand_HLIGet(call_inst, kChar);
324375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
324475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLIGetShort: {
32455e869b6560f918837cc6be3a50234deb2be46385TDYa      return Expand_HLIGet(call_inst, kShort);
324675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
324775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLIGetFloat: {
32485e869b6560f918837cc6be3a50234deb2be46385TDYa      return Expand_HLIGet(call_inst, kFloat);
324975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
325075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLIGetWide: {
32515e869b6560f918837cc6be3a50234deb2be46385TDYa      return Expand_HLIGet(call_inst, kLong);
325275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
325375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLIGetDouble: {
32545e869b6560f918837cc6be3a50234deb2be46385TDYa      return Expand_HLIGet(call_inst, kDouble);
325575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
325675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLIGetObject: {
32575e869b6560f918837cc6be3a50234deb2be46385TDYa      return Expand_HLIGet(call_inst, kObject);
325875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
325975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLIPut: {
32605e869b6560f918837cc6be3a50234deb2be46385TDYa      Expand_HLIPut(call_inst, kInt);
326175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
326275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
326375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLIPutBoolean: {
32645e869b6560f918837cc6be3a50234deb2be46385TDYa      Expand_HLIPut(call_inst, kBoolean);
326575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
326675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
326775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLIPutByte: {
32685e869b6560f918837cc6be3a50234deb2be46385TDYa      Expand_HLIPut(call_inst, kByte);
326975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
327075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
327175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLIPutChar: {
32725e869b6560f918837cc6be3a50234deb2be46385TDYa      Expand_HLIPut(call_inst, kChar);
327375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
327475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
327575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLIPutShort: {
32765e869b6560f918837cc6be3a50234deb2be46385TDYa      Expand_HLIPut(call_inst, kShort);
327775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
327875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
327975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLIPutFloat: {
32805e869b6560f918837cc6be3a50234deb2be46385TDYa      Expand_HLIPut(call_inst, kFloat);
328175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
328275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
328375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLIPutWide: {
32845e869b6560f918837cc6be3a50234deb2be46385TDYa      Expand_HLIPut(call_inst, kLong);
328575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
328675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
328775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLIPutDouble: {
32885e869b6560f918837cc6be3a50234deb2be46385TDYa      Expand_HLIPut(call_inst, kDouble);
328975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
329075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
329175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLIPutObject: {
32925e869b6560f918837cc6be3a50234deb2be46385TDYa      Expand_HLIPut(call_inst, kObject);
329375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
329475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
329575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
329675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    //==- High-level Invoke ------------------------------------------------==//
3297f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    case IntrinsicHelper::HLInvokeVoid:
3298f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    case IntrinsicHelper::HLInvokeObj:
3299f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    case IntrinsicHelper::HLInvokeInt:
3300f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    case IntrinsicHelper::HLInvokeFloat:
3301f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa    case IntrinsicHelper::HLInvokeLong:
330275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLInvokeDouble: {
3303f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      return Expand_HLInvoke(call_inst);
330475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
330575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
330621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    //==- Invoke -----------------------------------------------------------==//
330721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::FindStaticMethodWithAccessCheck: {
330821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::FindStaticMethodWithAccessCheck, call_inst);
330921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
331021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::FindDirectMethodWithAccessCheck: {
331121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::FindDirectMethodWithAccessCheck, call_inst);
331221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
331321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::FindVirtualMethodWithAccessCheck: {
331421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::FindVirtualMethodWithAccessCheck, call_inst);
331521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
331621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::FindSuperMethodWithAccessCheck: {
331721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::FindSuperMethodWithAccessCheck, call_inst);
331821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
331921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::FindInterfaceMethodWithAccessCheck: {
332021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::FindInterfaceMethodWithAccessCheck, call_inst);
332121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
332221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::GetSDCalleeMethodObjAddrFast: {
332321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_GetSDCalleeMethodObjAddrFast(call_inst.getArgOperand(0));
332421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
332521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::GetVirtualCalleeMethodObjAddrFast: {
332621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_GetVirtualCalleeMethodObjAddrFast(
332721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao                call_inst.getArgOperand(0), call_inst.getArgOperand(1));
332821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
332921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::GetInterfaceCalleeMethodObjAddrFast: {
333021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::FindInterfaceMethod, call_inst);
333121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
333221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InvokeRetVoid:
333321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InvokeRetBoolean:
333421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InvokeRetByte:
333521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InvokeRetChar:
333621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InvokeRetShort:
333721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InvokeRetInt:
333821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InvokeRetLong:
333921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InvokeRetFloat:
334021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InvokeRetDouble:
334121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::InvokeRetObject: {
334221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return Expand_Invoke(call_inst);
334321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
334475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
334521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    //==- Math -------------------------------------------------------------==//
334621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::DivInt: {
33474ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa      return Expand_DivRem(call_inst, /* is_div */true, kInt);
334821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
334921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::RemInt: {
33504ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa      return Expand_DivRem(call_inst, /* is_div */false, kInt);
335121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
335221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::DivLong: {
33534ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa      return Expand_DivRem(call_inst, /* is_div */true, kLong);
335421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
335521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::RemLong: {
33564ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa      return Expand_DivRem(call_inst, /* is_div */false, kLong);
335721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
335821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::D2L: {
335921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::art_d2l, call_inst);
336021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
336121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::D2I: {
336221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::art_d2i, call_inst);
336321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
336421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::F2L: {
336521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::art_f2l, call_inst);
336621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
336721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::F2I: {
336821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return ExpandToRuntime(runtime_support::art_f2i, call_inst);
336921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
337075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
337175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    //==- High-level Static ------------------------------------------------==//
337275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLSget: {
33735a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      return Expand_HLSget(call_inst, kInt);
337475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
337575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLSgetBoolean: {
33765a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      return Expand_HLSget(call_inst, kBoolean);
337775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
337875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLSgetByte: {
33795a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      return Expand_HLSget(call_inst, kByte);
338075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
338175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLSgetChar: {
33825a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      return Expand_HLSget(call_inst, kChar);
338375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
338475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLSgetShort: {
33855a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      return Expand_HLSget(call_inst, kShort);
338675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
338775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLSgetFloat: {
33885a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      return Expand_HLSget(call_inst, kFloat);
338975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
339075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLSgetWide: {
33915a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      return Expand_HLSget(call_inst, kLong);
339275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
339375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLSgetDouble: {
33945a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      return Expand_HLSget(call_inst, kDouble);
339575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
339675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLSgetObject: {
33975a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      return Expand_HLSget(call_inst, kObject);
339875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
339975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLSput: {
34005a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      Expand_HLSput(call_inst, kInt);
340175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
340275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
340375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLSputBoolean: {
34045a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      Expand_HLSput(call_inst, kBoolean);
340575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
340675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
340775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLSputByte: {
34085a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      Expand_HLSput(call_inst, kByte);
340975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
341075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
341175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLSputChar: {
34125a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      Expand_HLSput(call_inst, kChar);
341375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
341475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
341575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLSputShort: {
34165a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      Expand_HLSput(call_inst, kShort);
341775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
341875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
341975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLSputFloat: {
34205a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      Expand_HLSput(call_inst, kFloat);
342175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
342275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
342375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLSputWide: {
34245a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      Expand_HLSput(call_inst, kLong);
342575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
342675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
342775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLSputDouble: {
34285a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      Expand_HLSput(call_inst, kDouble);
342975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
343075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
343175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::HLSputObject: {
34325a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa      Expand_HLSput(call_inst, kObject);
343375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
343475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
343575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
343675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    //==- High-level Monitor -----------------------------------------------==//
343775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::MonitorEnter: {
3438f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      Expand_MonitorEnter(call_inst);
343975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
344075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
344175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::MonitorExit: {
3442f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa      Expand_MonitorExit(call_inst);
344375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
344475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
344575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
344621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    //==- Shadow Frame -----------------------------------------------------==//
344721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::AllocaShadowFrame: {
3448ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa      Expand_AllocaShadowFrame(call_inst.getArgOperand(0));
344921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
345021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
34518e950c117975d23f50ed7e32ca5db01a813c25d0TDYa    case IntrinsicHelper::SetVReg: {
34528e950c117975d23f50ed7e32ca5db01a813c25d0TDYa      Expand_SetVReg(call_inst.getArgOperand(0),
34538e950c117975d23f50ed7e32ca5db01a813c25d0TDYa                     call_inst.getArgOperand(1));
34548e950c117975d23f50ed7e32ca5db01a813c25d0TDYa      return NULL;
34558e950c117975d23f50ed7e32ca5db01a813c25d0TDYa    }
345621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::PopShadowFrame: {
345721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_PopShadowFrame();
345821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
345921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
346021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    case IntrinsicHelper::UpdateDexPC: {
346121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      Expand_UpdateDexPC(call_inst.getArgOperand(0));
346221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao      return NULL;
346321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
3464a1b2185820e6080864d18a35759cc046dc4ee578TDYa
346575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    //==- Comparison -------------------------------------------------------==//
3466a1b2185820e6080864d18a35759cc046dc4ee578TDYa    case IntrinsicHelper::CmplFloat:
3467a1b2185820e6080864d18a35759cc046dc4ee578TDYa    case IntrinsicHelper::CmplDouble: {
346875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return Expand_FPCompare(call_inst.getArgOperand(0),
346975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                              call_inst.getArgOperand(1),
347075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                              false);
3471a1b2185820e6080864d18a35759cc046dc4ee578TDYa    }
3472a1b2185820e6080864d18a35759cc046dc4ee578TDYa    case IntrinsicHelper::CmpgFloat:
3473a1b2185820e6080864d18a35759cc046dc4ee578TDYa    case IntrinsicHelper::CmpgDouble: {
347475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return Expand_FPCompare(call_inst.getArgOperand(0),
347575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                              call_inst.getArgOperand(1),
347675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                              true);
3477a1b2185820e6080864d18a35759cc046dc4ee578TDYa    }
3478a1b2185820e6080864d18a35759cc046dc4ee578TDYa    case IntrinsicHelper::CmpLong: {
347975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return Expand_LongCompare(call_inst.getArgOperand(0),
348075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                                call_inst.getArgOperand(1));
348175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
348275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
348375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    //==- Const ------------------------------------------------------------==//
3484920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case IntrinsicHelper::ConstInt:
3485920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case IntrinsicHelper::ConstLong: {
3486d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien      return call_inst.getArgOperand(0);
348775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
3488920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case IntrinsicHelper::ConstFloat: {
3489d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien      return irb_.CreateBitCast(call_inst.getArgOperand(0),
3490d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien                                irb_.getJFloatTy());
349175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
3492920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case IntrinsicHelper::ConstDouble: {
3493d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien      return irb_.CreateBitCast(call_inst.getArgOperand(0),
3494d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien                                irb_.getJDoubleTy());
3495d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien    }
3496920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case IntrinsicHelper::ConstObj: {
3497bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao      CHECK(LV2UInt(call_inst.getArgOperand(0)) == 0);
3498bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao      return irb_.getJNull();
3499a1b2185820e6080864d18a35759cc046dc4ee578TDYa    }
350075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
350175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    //==- Method Info ------------------------------------------------------==//
3502920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case IntrinsicHelper::MethodInfo: {
3503b259652a72293b4bd3c346bb0e40fb8a7f878fa2Shih-wei Liao      // Nothing to be done, because MethodInfo carries optional hints that are
3504b259652a72293b4bd3c346bb0e40fb8a7f878fa2Shih-wei Liao      // not needed by the portable path.
350575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return NULL;
350675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
350775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
350875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    //==- Copy -------------------------------------------------------------==//
3509920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case IntrinsicHelper::CopyInt:
3510920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case IntrinsicHelper::CopyFloat:
3511920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case IntrinsicHelper::CopyLong:
3512920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case IntrinsicHelper::CopyDouble:
3513920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case IntrinsicHelper::CopyObj: {
3514d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien      return call_inst.getArgOperand(0);
351575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
351675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
351775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    //==- Shift ------------------------------------------------------------==//
3518920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case IntrinsicHelper::SHLLong: {
351975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return Expand_IntegerShift(call_inst.getArgOperand(0),
352075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                                 call_inst.getArgOperand(1),
352175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                                 kIntegerSHL, kLong);
3522a1b2185820e6080864d18a35759cc046dc4ee578TDYa    }
3523920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case IntrinsicHelper::SHRLong: {
352475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return Expand_IntegerShift(call_inst.getArgOperand(0),
352575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                                 call_inst.getArgOperand(1),
352675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                                 kIntegerSHR, kLong);
3527a1b2185820e6080864d18a35759cc046dc4ee578TDYa    }
3528920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case IntrinsicHelper::USHRLong: {
352975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return Expand_IntegerShift(call_inst.getArgOperand(0),
353075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                                 call_inst.getArgOperand(1),
353175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                                 kIntegerUSHR, kLong);
3532a1b2185820e6080864d18a35759cc046dc4ee578TDYa    }
3533920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case IntrinsicHelper::SHLInt: {
353475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return Expand_IntegerShift(call_inst.getArgOperand(0),
353575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                                 call_inst.getArgOperand(1),
353675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                                 kIntegerSHL, kInt);
3537a1b2185820e6080864d18a35759cc046dc4ee578TDYa    }
3538920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case IntrinsicHelper::SHRInt: {
353975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return Expand_IntegerShift(call_inst.getArgOperand(0),
354075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                                 call_inst.getArgOperand(1),
354175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                                 kIntegerSHR, kInt);
3542a1b2185820e6080864d18a35759cc046dc4ee578TDYa    }
3543920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa    case IntrinsicHelper::USHRInt: {
354475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return Expand_IntegerShift(call_inst.getArgOperand(0),
354575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                                 call_inst.getArgOperand(1),
354675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                                 kIntegerUSHR, kInt);
3547a1b2185820e6080864d18a35759cc046dc4ee578TDYa    }
354821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
354975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    //==- Conversion -------------------------------------------------------==//
355075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::IntToChar: {
355175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return irb_.CreateZExt(irb_.CreateTrunc(call_inst.getArgOperand(0), irb_.getJCharTy()),
355275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                             irb_.getJIntTy());
355375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
355475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::IntToShort: {
355575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return irb_.CreateSExt(irb_.CreateTrunc(call_inst.getArgOperand(0), irb_.getJShortTy()),
355675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                             irb_.getJIntTy());
355721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao    }
355875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::IntToByte: {
355975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      return irb_.CreateSExt(irb_.CreateTrunc(call_inst.getArgOperand(0), irb_.getJByteTy()),
356075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien                             irb_.getJIntTy());
356175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    }
356275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien
356387caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa    //==- Exception --------------------------------------------------------==//
356487caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa    case IntrinsicHelper::CatchTargets: {
356555e5e6c5702e3f1f68bd83ae741af769740d9a74TDYa      UpdatePhiInstruction(current_bb_, irb_.GetInsertBlock());
356687caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa      llvm::SwitchInst* si = llvm::dyn_cast<llvm::SwitchInst>(call_inst.getNextNode());
356787caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa      CHECK(si != NULL);
356887caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa      irb_.CreateBr(si->getDefaultDest());
356987caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa      si->eraseFromParent();
357087caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa      return call_inst.getArgOperand(0);
357187caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa    }
357287caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa
357375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    //==- Unknown Cases ----------------------------------------------------==//
357475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::MaxIntrinsicId:
357575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    case IntrinsicHelper::UnknownId:
357675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien    //default:
357775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      // NOTE: "default" is intentionally commented so that C/C++ compiler will
357875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      // give some warning on unmatched cases.
357975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      // NOTE: We should not implement these cases.
358075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien      break;
358121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  }
358275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien  UNIMPLEMENTED(FATAL) << "Unexpected GBC intrinsic: " << static_cast<int>(intr_id);
358321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return NULL;
358421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
358521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
358621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} // anonymous namespace
358721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
358821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaonamespace art {
3589b259652a72293b4bd3c346bb0e40fb8a7f878fa2Shih-wei Liao
359021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaonamespace compiler_llvm {
359121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
359221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::FunctionPass*
359321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoCreateGBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb) {
359421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao  return new GBCExpanderPass(intrinsic_helper, irb);
359521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}
359621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao
3597bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liaollvm::FunctionPass*
3598bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei LiaoCreateGBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb,
3599bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao                      Compiler* compiler, OatCompilationUnit* oat_compilation_unit) {
3600bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  if (compiler != NULL) {
3601bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao    return new GBCExpanderPass(intrinsic_helper, irb,
3602bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao                               compiler, oat_compilation_unit);
3603bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  } else {
3604bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao    return new GBCExpanderPass(intrinsic_helper, irb);
3605bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao  }
3606bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao}
3607bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao
360821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} // namespace compiler_llvm
360921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} // namespace art
3610