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