gbc_expander.cc revision 9a14265c911b2e63bec51a814b8b6fd157745b57
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" 225e869b6560f918837cc6be3a50234deb2be46385TDYa#include "oat_compilation_unit.h" 2321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include "object.h" 2421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include "thread.h" 255e869b6560f918837cc6be3a50234deb2be46385TDYa#include "verifier/method_verifier.h" 2621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 27efc6369224b036a1fb77849f7ae65b3492c832c0buzbee#include "compiler/compiler_ir.h" 28449a49bedfb72f0d5643977a99346935f1b33c55buzbee#include "compiler/codegen/codegen.h" 29920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYausing art::kMIRIgnoreNullCheck; 30920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYausing art::kMIRIgnoreRangeCheck; 31920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa 3221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include <llvm/ADT/STLExtras.h> 3321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include <llvm/Intrinsics.h> 34d36a2aceeb17b2b1745fc64a8f1dfc77425d43deLogan Chien#include <llvm/Metadata.h> 3521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include <llvm/Pass.h> 3621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include <llvm/Support/CFG.h> 3721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include <llvm/Support/InstIterator.h> 3821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 3921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include <vector> 40aa55887fd30484a77e7775dfbcddbee883ce6380TDYa#include <map> 41aa55887fd30484a77e7775dfbcddbee883ce6380TDYa#include <utility> 4221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 43920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYausing namespace art::compiler_llvm; 4421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 4521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaousing art::greenland::IntrinsicHelper; 4621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 47b259652a72293b4bd3c346bb0e40fb8a7f878fa2Shih-wei Liaonamespace art { 4826f10eed520942d3db754c31941e457048475f61buzbeeextern char RemapShorty(char shortyType); 49b259652a72293b4bd3c346bb0e40fb8a7f878fa2Shih-wei Liao}; 50b259652a72293b4bd3c346bb0e40fb8a7f878fa2Shih-wei Liao 5121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaonamespace { 5221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 5321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaoclass GBCExpanderPass : public llvm::FunctionPass { 5421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao private: 5521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao const IntrinsicHelper& intrinsic_helper_; 5621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao IRBuilder& irb_; 5721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 5821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::LLVMContext& context_; 5921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao RuntimeSupportBuilder& rtb_; 6021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 6121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao private: 6221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::AllocaInst* shadow_frame_; 6321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* old_shadow_frame_; 6421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 6521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao private: 66920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::Compiler* compiler_; 675e869b6560f918837cc6be3a50234deb2be46385TDYa 68920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa const art::DexFile* dex_file_; 69920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa const art::DexFile::CodeItem* code_item_; 705e869b6560f918837cc6be3a50234deb2be46385TDYa 71920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::OatCompilationUnit* oat_compilation_unit_; 725e869b6560f918837cc6be3a50234deb2be46385TDYa 735e869b6560f918837cc6be3a50234deb2be46385TDYa uint32_t method_idx_; 745e869b6560f918837cc6be3a50234deb2be46385TDYa 755e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Function* func_; 765e869b6560f918837cc6be3a50234deb2be46385TDYa 775e869b6560f918837cc6be3a50234deb2be46385TDYa std::vector<llvm::BasicBlock*> basic_blocks_; 785e869b6560f918837cc6be3a50234deb2be46385TDYa 795e869b6560f918837cc6be3a50234deb2be46385TDYa std::vector<llvm::BasicBlock*> basic_block_landing_pads_; 8055e5e6c5702e3f1f68bd83ae741af769740d9a74TDYa llvm::BasicBlock* current_bb_; 81aa55887fd30484a77e7775dfbcddbee883ce6380TDYa std::map<llvm::BasicBlock*, std::vector<std::pair<llvm::BasicBlock*, llvm::BasicBlock*> > > 82aa55887fd30484a77e7775dfbcddbee883ce6380TDYa landing_pad_phi_mapping_; 835e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* basic_block_unwind_; 845e869b6560f918837cc6be3a50234deb2be46385TDYa 8567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien bool changed_; 8667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 875e869b6560f918837cc6be3a50234deb2be46385TDYa private: 8821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //---------------------------------------------------------------------------- 8975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien // Constant for GBC expansion 9075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //---------------------------------------------------------------------------- 9175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien enum IntegerShiftKind { 9275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien kIntegerSHL, 9375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien kIntegerSHR, 9475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien kIntegerUSHR, 9575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien }; 9675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 9775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien private: 9875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //---------------------------------------------------------------------------- 9921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Helper function for GBC expansion 10021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //---------------------------------------------------------------------------- 10121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 10221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* ExpandToRuntime(runtime_support::RuntimeId rt, 10321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::CallInst& inst); 10421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 1055e869b6560f918837cc6be3a50234deb2be46385TDYa uint64_t LV2UInt(llvm::Value* lv) { 1065e869b6560f918837cc6be3a50234deb2be46385TDYa return llvm::cast<llvm::ConstantInt>(lv)->getZExtValue(); 1075e869b6560f918837cc6be3a50234deb2be46385TDYa } 1085e869b6560f918837cc6be3a50234deb2be46385TDYa 1095e869b6560f918837cc6be3a50234deb2be46385TDYa int64_t LV2SInt(llvm::Value* lv) { 1105e869b6560f918837cc6be3a50234deb2be46385TDYa return llvm::cast<llvm::ConstantInt>(lv)->getSExtValue(); 1115e869b6560f918837cc6be3a50234deb2be46385TDYa } 1125e869b6560f918837cc6be3a50234deb2be46385TDYa 11321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao private: 11421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // TODO: Almost all Emit* are directly copy-n-paste from MethodCompiler. 11521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Refactor these utility functions from MethodCompiler to avoid forking. 11621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 11767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien void EmitStackOverflowCheck(llvm::Instruction* first_non_alloca); 11867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 11967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien void RewriteFunction(); 12067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 12167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien void RewriteBasicBlock(llvm::BasicBlock* original_block); 12267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 12367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien void UpdatePhiInstruction(llvm::BasicBlock* old_basic_block, 12467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock* new_basic_block); 12567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 12621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 12721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //---------------------------------------------------------------------------- 12821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Dex cache code generation helper function 12921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //---------------------------------------------------------------------------- 130920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa llvm::Value* EmitLoadDexCacheAddr(art::MemberOffset dex_cache_offset); 13121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 13221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* EmitLoadDexCacheStaticStorageFieldAddr(uint32_t type_idx); 13321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 13421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* EmitLoadDexCacheResolvedTypeFieldAddr(uint32_t type_idx); 13521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 13621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* EmitLoadDexCacheResolvedMethodFieldAddr(uint32_t method_idx); 13721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 13821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* EmitLoadDexCacheStringFieldAddr(uint32_t string_idx); 13921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 14021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //---------------------------------------------------------------------------- 14121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Code generation helper function 14221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //---------------------------------------------------------------------------- 14321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* EmitLoadMethodObjectAddr(); 14421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 14521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* EmitLoadArrayLength(llvm::Value* array); 14621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 14721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* EmitLoadSDCalleeMethodObjectAddr(uint32_t callee_method_idx); 14821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 14921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* EmitLoadVirtualCalleeMethodObjectAddr(int vtable_idx, 15021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* this_addr); 15121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 15221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* EmitArrayGEP(llvm::Value* array_addr, 15321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* index_value, 15421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType elem_jty); 15521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 15621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao private: 15721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //---------------------------------------------------------------------------- 15821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Expand Greenland intrinsics 15921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //---------------------------------------------------------------------------- 16021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao void Expand_TestSuspend(llvm::CallInst& call_inst); 16121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 1629a129457c233b653c7a8f65c963509267252b0a7TDYa void Expand_MarkGCCard(llvm::CallInst& call_inst); 1639a129457c233b653c7a8f65c963509267252b0a7TDYa 16421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* Expand_LoadStringFromDexCache(llvm::Value* string_idx_value); 16521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 16621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* Expand_LoadTypeFromDexCache(llvm::Value* type_idx_value); 16721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 16821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao void Expand_LockObject(llvm::Value* obj); 16921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 17021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao void Expand_UnlockObject(llvm::Value* obj); 17121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 17221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* Expand_ArrayGet(llvm::Value* array_addr, 17321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* index_value, 17421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType elem_jty); 17521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 17621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao void Expand_ArrayPut(llvm::Value* new_value, 17721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* array_addr, 17821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* index_value, 17921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType elem_jty); 18021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 18121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao void Expand_FilledNewArray(llvm::CallInst& call_inst); 18221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 18321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* Expand_IGetFast(llvm::Value* field_offset_value, 18421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* is_volatile_value, 18521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* object_addr, 18621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType field_jty); 18721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 18821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao void Expand_IPutFast(llvm::Value* field_offset_value, 18921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* is_volatile_value, 19021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* object_addr, 19121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* new_value, 19221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType field_jty); 19321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 19421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* Expand_SGetFast(llvm::Value* static_storage_addr, 19521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* field_offset_value, 19621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* is_volatile_value, 19721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType field_jty); 19821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 19921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao void Expand_SPutFast(llvm::Value* static_storage_addr, 20021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* field_offset_value, 20121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* is_volatile_value, 20221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* new_value, 20321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType field_jty); 20421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 20521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* Expand_LoadDeclaringClassSSB(llvm::Value* method_object_addr); 20621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 20721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* Expand_LoadClassSSBFromDexCache(llvm::Value* type_idx_value); 20821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 20921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* 21021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_GetSDCalleeMethodObjAddrFast(llvm::Value* callee_method_idx_value); 21121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 21221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* 21321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_GetVirtualCalleeMethodObjAddrFast(llvm::Value* vtable_idx_value, 21421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* this_addr); 21521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 21621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* Expand_Invoke(llvm::CallInst& call_inst); 21721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 2184ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa llvm::Value* Expand_DivRem(llvm::CallInst& call_inst, bool is_div, JType op_jty); 21921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 220ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa void Expand_AllocaShadowFrame(llvm::Value* num_vregs_value); 22121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 2228e950c117975d23f50ed7e32ca5db01a813c25d0TDYa void Expand_SetVReg(llvm::Value* entry_idx, llvm::Value* obj); 2238e950c117975d23f50ed7e32ca5db01a813c25d0TDYa 22421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao void Expand_PopShadowFrame(); 22521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 22621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao void Expand_UpdateDexPC(llvm::Value* dex_pc_value); 22721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 228a1b2185820e6080864d18a35759cc046dc4ee578TDYa //---------------------------------------------------------------------------- 229a1b2185820e6080864d18a35759cc046dc4ee578TDYa // Quick 230a1b2185820e6080864d18a35759cc046dc4ee578TDYa //---------------------------------------------------------------------------- 231a1b2185820e6080864d18a35759cc046dc4ee578TDYa 232a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* Expand_FPCompare(llvm::Value* src1_value, 233a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* src2_value, 234a1b2185820e6080864d18a35759cc046dc4ee578TDYa bool gt_bias); 235a1b2185820e6080864d18a35759cc046dc4ee578TDYa 236a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* Expand_LongCompare(llvm::Value* src1_value, llvm::Value* src2_value); 237a1b2185820e6080864d18a35759cc046dc4ee578TDYa 238a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* EmitCompareResultSelection(llvm::Value* cmp_eq, 239a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* cmp_lt); 240a1b2185820e6080864d18a35759cc046dc4ee578TDYa 241f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* EmitLoadConstantClass(uint32_t dex_pc, uint32_t type_idx); 2425a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* EmitLoadStaticStorage(uint32_t dex_pc, uint32_t type_idx); 2435a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 2445e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* Expand_HLIGet(llvm::CallInst& call_inst, JType field_jty); 2455e869b6560f918837cc6be3a50234deb2be46385TDYa void Expand_HLIPut(llvm::CallInst& call_inst, JType field_jty); 2465e869b6560f918837cc6be3a50234deb2be46385TDYa 2475a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* Expand_HLSget(llvm::CallInst& call_inst, JType field_jty); 2485a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa void Expand_HLSput(llvm::CallInst& call_inst, JType field_jty); 2495a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 2505a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* Expand_HLArrayGet(llvm::CallInst& call_inst, JType field_jty); 2515a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa void Expand_HLArrayPut(llvm::CallInst& call_inst, JType field_jty); 2525a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 253f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* Expand_ConstString(llvm::CallInst& call_inst); 254f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* Expand_ConstClass(llvm::CallInst& call_inst); 255f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 256f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa void Expand_MonitorEnter(llvm::CallInst& call_inst); 257f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa void Expand_MonitorExit(llvm::CallInst& call_inst); 258f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 259f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa void Expand_HLCheckCast(llvm::CallInst& call_inst); 260f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* Expand_InstanceOf(llvm::CallInst& call_inst); 261f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 262f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* Expand_NewInstance(llvm::CallInst& call_inst); 263f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 264f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* Expand_HLInvoke(llvm::CallInst& call_inst); 265f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 266f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* Expand_OptArrayLength(llvm::CallInst& call_inst); 267f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* Expand_NewArray(llvm::CallInst& call_inst); 268f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* Expand_HLFilledNewArray(llvm::CallInst& call_inst); 269f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa void Expand_HLFillArrayData(llvm::CallInst& call_inst); 270f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 271f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* EmitAllocNewArray(uint32_t dex_pc, 272f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* array_length_value, 273f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_idx, 274f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa bool is_filled_new_array); 275f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 276f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* EmitCallRuntimeForCalleeMethodObjectAddr(uint32_t callee_method_idx, 277920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::InvokeType invoke_type, 278f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* this_addr, 279f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc, 280f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa bool is_fast_path); 281f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2825e869b6560f918837cc6be3a50234deb2be46385TDYa void EmitMarkGCCard(llvm::Value* value, llvm::Value* target_addr); 2835e869b6560f918837cc6be3a50234deb2be46385TDYa 2845e869b6560f918837cc6be3a50234deb2be46385TDYa void EmitUpdateDexPC(uint32_t dex_pc); 2855e869b6560f918837cc6be3a50234deb2be46385TDYa 2865e869b6560f918837cc6be3a50234deb2be46385TDYa void EmitGuard_DivZeroException(uint32_t dex_pc, 2875e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* denominator, 2885e869b6560f918837cc6be3a50234deb2be46385TDYa JType op_jty); 2895e869b6560f918837cc6be3a50234deb2be46385TDYa 2905e869b6560f918837cc6be3a50234deb2be46385TDYa void EmitGuard_NullPointerException(uint32_t dex_pc, 2915e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* object); 2925e869b6560f918837cc6be3a50234deb2be46385TDYa 2935e869b6560f918837cc6be3a50234deb2be46385TDYa void EmitGuard_ArrayIndexOutOfBoundsException(uint32_t dex_pc, 2945e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* array, 2955e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* index); 2965e869b6560f918837cc6be3a50234deb2be46385TDYa 2975e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::FunctionType* GetFunctionType(uint32_t method_idx, bool is_static); 2985e869b6560f918837cc6be3a50234deb2be46385TDYa 2995e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* GetBasicBlock(uint32_t dex_pc); 3005e869b6560f918837cc6be3a50234deb2be46385TDYa 3015e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* CreateBasicBlockWithDexPC(uint32_t dex_pc, 3025e869b6560f918837cc6be3a50234deb2be46385TDYa const char* postfix); 3035e869b6560f918837cc6be3a50234deb2be46385TDYa 3045e869b6560f918837cc6be3a50234deb2be46385TDYa int32_t GetTryItemOffset(uint32_t dex_pc); 3055e869b6560f918837cc6be3a50234deb2be46385TDYa 3065e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* GetLandingPadBasicBlock(uint32_t dex_pc); 3075e869b6560f918837cc6be3a50234deb2be46385TDYa 3085e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* GetUnwindBasicBlock(); 3095e869b6560f918837cc6be3a50234deb2be46385TDYa 3105e869b6560f918837cc6be3a50234deb2be46385TDYa void EmitGuard_ExceptionLandingPad(uint32_t dex_pc); 3115e869b6560f918837cc6be3a50234deb2be46385TDYa 3125e869b6560f918837cc6be3a50234deb2be46385TDYa void EmitBranchExceptionLandingPad(uint32_t dex_pc); 3135e869b6560f918837cc6be3a50234deb2be46385TDYa 31475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //---------------------------------------------------------------------------- 31575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien // Expand Arithmetic Helper Intrinsics 31675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //---------------------------------------------------------------------------- 31775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 31875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien llvm::Value* Expand_IntegerShift(llvm::Value* src1_value, 31975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien llvm::Value* src2_value, 32075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien IntegerShiftKind kind, 32175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien JType op_jty); 32275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 32321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao public: 32421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao static char ID; 32521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 32621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao GBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb) 32721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao : llvm::FunctionPass(ID), intrinsic_helper_(intrinsic_helper), irb_(irb), 328e5b8f8b3eaef9871b8cea42cc8e98548754ac051Logan Chien context_(irb.getContext()), rtb_(irb.Runtime()), 3298e950c117975d23f50ed7e32ca5db01a813c25d0TDYa shadow_frame_(NULL), old_shadow_frame_(NULL), 330bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao compiler_(NULL), dex_file_(NULL), code_item_(NULL), 33167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien oat_compilation_unit_(NULL), method_idx_(-1u), func_(NULL), 33267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien changed_(false) 33321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao { } 33421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 335bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao GBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb, 336920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::Compiler* compiler, art::OatCompilationUnit* oat_compilation_unit) 337bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao : llvm::FunctionPass(ID), intrinsic_helper_(intrinsic_helper), irb_(irb), 338bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao context_(irb.getContext()), rtb_(irb.Runtime()), 3398e950c117975d23f50ed7e32ca5db01a813c25d0TDYa shadow_frame_(NULL), old_shadow_frame_(NULL), 340bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao compiler_(compiler), 341bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao dex_file_(oat_compilation_unit->GetDexFile()), 342bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao code_item_(oat_compilation_unit->GetCodeItem()), 343bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao oat_compilation_unit_(oat_compilation_unit), 344bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao method_idx_(oat_compilation_unit->GetDexMethodIndex()), 345bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao func_(NULL), changed_(false) 346bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao { } 347bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao 34821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao bool runOnFunction(llvm::Function& func); 34921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 35021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao private: 35167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien void InsertStackOverflowCheck(llvm::Function& func); 35221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 35321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* ExpandIntrinsic(IntrinsicHelper::IntrinsicId intr_id, 35421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::CallInst& call_inst); 35521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 35621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}; 35721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 35821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaochar GBCExpanderPass::ID = 0; 35921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 36021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaobool GBCExpanderPass::runOnFunction(llvm::Function& func) { 361b672d1e48b6e02bb69c7cd9bcfa7509c81514c07TDYa // Runtime support or stub 362b672d1e48b6e02bb69c7cd9bcfa7509c81514c07TDYa if (func.getName().startswith("art_") || func.getName().startswith("Art")) { 363b672d1e48b6e02bb69c7cd9bcfa7509c81514c07TDYa return false; 364b672d1e48b6e02bb69c7cd9bcfa7509c81514c07TDYa } 36521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 36667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Setup rewrite context 36767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien shadow_frame_ = NULL; 36867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien old_shadow_frame_ = NULL; 36967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien func_ = &func; 37067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien changed_ = false; // Assume unchanged 37121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 372c531cefbfb5394413122e9f57d211ba436cff012buzbee#if defined(ART_USE_PORTABLE_COMPILER) 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#endif 386bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao 38767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Insert stack overflow check 38867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien InsertStackOverflowCheck(func); // TODO: Use intrinsic. 38921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 39067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Rewrite the intrinsics 39167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien RewriteFunction(); 39221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 39367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien VERIFY_LLVM_FUNCTION(func); 39421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 39567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien return changed_; 39667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien} 39767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 39867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chienvoid GBCExpanderPass::RewriteBasicBlock(llvm::BasicBlock* original_block) { 39967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock* curr_basic_block = original_block; 40067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 40167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock::iterator inst_iter = original_block->begin(); 40267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock::iterator inst_end = original_block->end(); 40367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 40467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien while (inst_iter != inst_end) { 40567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::CallInst* call_inst = llvm::dyn_cast<llvm::CallInst>(inst_iter); 40667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien IntrinsicHelper::IntrinsicId intr_id = IntrinsicHelper::UnknownId; 40767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 40867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien if (call_inst) { 40967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::Function* callee_func = call_inst->getCalledFunction(); 41067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien intr_id = intrinsic_helper_.GetIntrinsicId(callee_func); 41121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 41221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 41367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien if (intr_id == IntrinsicHelper::UnknownId) { 41467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // This is not intrinsic call. Skip this instruction. 41567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien ++inst_iter; 41667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien continue; 41767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien } 41821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 41967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Rewrite the intrinsic and change the function 42067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien changed_ = true; 42167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien irb_.SetInsertPoint(inst_iter); 42221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 42367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Expand the intrinsic 42467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien if (llvm::Value* new_value = ExpandIntrinsic(intr_id, *call_inst)) { 42567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien inst_iter->replaceAllUsesWith(new_value); 42667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien } 42721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 42867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Remove the old intrinsic call instruction 42967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock::iterator old_inst = inst_iter++; 43067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien old_inst->eraseFromParent(); 43167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 43267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Splice the instruction to the new basic block 43367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock* next_basic_block = irb_.GetInsertBlock(); 43467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien if (next_basic_block != curr_basic_block) { 43567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien next_basic_block->getInstList().splice( 43667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien irb_.GetInsertPoint(), curr_basic_block->getInstList(), 43767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien inst_iter, inst_end); 43867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien curr_basic_block = next_basic_block; 43967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien inst_end = curr_basic_block->end(); 44067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien } 44167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien } 44267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien} 44321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 44421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 44567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chienvoid GBCExpanderPass::RewriteFunction() { 44667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien size_t num_basic_blocks = func_->getBasicBlockList().size(); 44767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // NOTE: We are not using (bb_iter != bb_end) as the for-loop condition, 44867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // because we will create new basic block while expanding the intrinsics. 44967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // We only want to iterate through the input basic blocks. 45021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 451aa55887fd30484a77e7775dfbcddbee883ce6380TDYa landing_pad_phi_mapping_.clear(); 452aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 45367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien for (llvm::Function::iterator bb_iter = func_->begin(); 45467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien num_basic_blocks > 0; ++bb_iter, --num_basic_blocks) { 455627d8c4ae50f22f628fe6a768f2924ee7e0029deShih-wei Liao // Set insert point to current basic block. 456627d8c4ae50f22f628fe6a768f2924ee7e0029deShih-wei Liao irb_.SetInsertPoint(bb_iter); 45767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 45855e5e6c5702e3f1f68bd83ae741af769740d9a74TDYa current_bb_ = bb_iter; 459aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 46067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Rewrite the basic block 46167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien RewriteBasicBlock(bb_iter); 46267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 46367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Update the phi-instructions in the successor basic block 46467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock* last_block = irb_.GetInsertBlock(); 46567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien if (last_block != bb_iter) { 46667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien UpdatePhiInstruction(bb_iter, last_block); 46721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 46867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien } 469aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 470aa55887fd30484a77e7775dfbcddbee883ce6380TDYa typedef std::map<llvm::PHINode*, llvm::PHINode*> HandlerPHIMap; 471aa55887fd30484a77e7775dfbcddbee883ce6380TDYa HandlerPHIMap handler_phi; 472aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // Iterate every used landing pad basic block 473aa55887fd30484a77e7775dfbcddbee883ce6380TDYa for (size_t i = 0, ei = basic_block_landing_pads_.size(); i != ei; ++i) { 474aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::BasicBlock* lbb = basic_block_landing_pads_[i]; 475aa55887fd30484a77e7775dfbcddbee883ce6380TDYa if (lbb == NULL) { 476aa55887fd30484a77e7775dfbcddbee883ce6380TDYa continue; 477aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 478aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 479aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::TerminatorInst* term_inst = lbb->getTerminator(); 480aa55887fd30484a77e7775dfbcddbee883ce6380TDYa std::vector<std::pair<llvm::BasicBlock*, llvm::BasicBlock*> >& rewrite_pair 481aa55887fd30484a77e7775dfbcddbee883ce6380TDYa = landing_pad_phi_mapping_[lbb]; 482aa55887fd30484a77e7775dfbcddbee883ce6380TDYa irb_.SetInsertPoint(lbb->begin()); 483aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 484aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // Iterate every succeeding basic block (catch block) 485aa55887fd30484a77e7775dfbcddbee883ce6380TDYa for (unsigned succ_iter = 0, succ_end = term_inst->getNumSuccessors(); 486aa55887fd30484a77e7775dfbcddbee883ce6380TDYa succ_iter != succ_end; ++succ_iter) { 487aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::BasicBlock* succ_basic_block = term_inst->getSuccessor(succ_iter); 488aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 489aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // Iterate every phi instructions in the succeeding basic block 490aa55887fd30484a77e7775dfbcddbee883ce6380TDYa for (llvm::BasicBlock::iterator 491aa55887fd30484a77e7775dfbcddbee883ce6380TDYa inst_iter = succ_basic_block->begin(), 492aa55887fd30484a77e7775dfbcddbee883ce6380TDYa inst_end = succ_basic_block->end(); 493aa55887fd30484a77e7775dfbcddbee883ce6380TDYa inst_iter != inst_end; ++inst_iter) { 494aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::PHINode *phi = llvm::dyn_cast<llvm::PHINode>(inst_iter); 495aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 496aa55887fd30484a77e7775dfbcddbee883ce6380TDYa if (!phi) { 497aa55887fd30484a77e7775dfbcddbee883ce6380TDYa break; // Meet non-phi instruction. Done. 498aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 499aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 500aa55887fd30484a77e7775dfbcddbee883ce6380TDYa if (handler_phi[phi] == NULL) { 501aa55887fd30484a77e7775dfbcddbee883ce6380TDYa handler_phi[phi] = llvm::PHINode::Create(phi->getType(), 1); 502aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 503aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 504aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // Create new_phi in landing pad 505aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::PHINode* new_phi = irb_.CreatePHI(phi->getType(), rewrite_pair.size()); 506aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // Insert all incoming value into new_phi by rewrite_pair 507aa55887fd30484a77e7775dfbcddbee883ce6380TDYa for (size_t j = 0, ej = rewrite_pair.size(); j != ej; ++j) { 508aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::BasicBlock* old_bb = rewrite_pair[j].first; 509aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::BasicBlock* new_bb = rewrite_pair[j].second; 510aa55887fd30484a77e7775dfbcddbee883ce6380TDYa new_phi->addIncoming(phi->getIncomingValueForBlock(old_bb), new_bb); 511aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 512aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // Delete all incoming value from phi by rewrite_pair 513aa55887fd30484a77e7775dfbcddbee883ce6380TDYa for (size_t j = 0, ej = rewrite_pair.size(); j != ej; ++j) { 514aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::BasicBlock* old_bb = rewrite_pair[j].first; 515aa55887fd30484a77e7775dfbcddbee883ce6380TDYa int old_bb_idx = phi->getBasicBlockIndex(old_bb); 516aa55887fd30484a77e7775dfbcddbee883ce6380TDYa if (old_bb_idx >= 0) { 517aa55887fd30484a77e7775dfbcddbee883ce6380TDYa phi->removeIncomingValue(old_bb_idx, false); 518aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 519aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 520aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // Insert new_phi into new handler phi 521aa55887fd30484a77e7775dfbcddbee883ce6380TDYa handler_phi[phi]->addIncoming(new_phi, lbb); 522aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 523aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 524aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 525aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 526aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // Replace all handler phi 527aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // We can't just use the old handler phi, because some exception edges will disappear after we 528aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // compute fast-path. 529aa55887fd30484a77e7775dfbcddbee883ce6380TDYa for (HandlerPHIMap::iterator it = handler_phi.begin(); it != handler_phi.end(); ++it) { 530aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::PHINode* old_phi = it->first; 531aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::PHINode* new_phi = it->second; 532aa55887fd30484a77e7775dfbcddbee883ce6380TDYa new_phi->insertBefore(old_phi); 533aa55887fd30484a77e7775dfbcddbee883ce6380TDYa old_phi->replaceAllUsesWith(new_phi); 534aa55887fd30484a77e7775dfbcddbee883ce6380TDYa old_phi->eraseFromParent(); 535aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 53667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien} 53721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 53867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chienvoid GBCExpanderPass::UpdatePhiInstruction(llvm::BasicBlock* old_basic_block, 53967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock* new_basic_block) { 54067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::TerminatorInst* term_inst = new_basic_block->getTerminator(); 54167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 54267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien if (!term_inst) { 54367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien return; // No terminating instruction in new_basic_block. Nothing to do. 54421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 54521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 54667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Iterate every succeeding basic block 54767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien for (unsigned succ_iter = 0, succ_end = term_inst->getNumSuccessors(); 54867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien succ_iter != succ_end; ++succ_iter) { 54967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock* succ_basic_block = term_inst->getSuccessor(succ_iter); 55067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 55167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Iterate every phi instructions in the succeeding basic block 55267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien for (llvm::BasicBlock::iterator 55367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien inst_iter = succ_basic_block->begin(), 55467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien inst_end = succ_basic_block->end(); 55567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien inst_iter != inst_end; ++inst_iter) { 55667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::PHINode *phi = llvm::dyn_cast<llvm::PHINode>(inst_iter); 55721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 55867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien if (!phi) { 55967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien break; // Meet non-phi instruction. Done. 56067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien } 56167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 56267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Update the incoming block of this phi instruction 56367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien for (llvm::PHINode::block_iterator 56467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien ibb_iter = phi->block_begin(), ibb_end = phi->block_end(); 56567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien ibb_iter != ibb_end; ++ibb_iter) { 56667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien if (*ibb_iter == old_basic_block) { 56767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien *ibb_iter = new_basic_block; 56867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien } 56921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 57021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 57121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 57221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 57321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 57421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::ExpandToRuntime(runtime_support::RuntimeId rt, 57521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::CallInst& inst) { 57621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Some GBC intrinsic can directly replace with IBC runtime. "Directly" means 57721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // the arguments passed to the GBC intrinsic are as the same as IBC runtime 57821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // function, therefore only called function is needed to change. 57921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao unsigned num_args = inst.getNumArgOperands(); 58021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 58121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao if (num_args <= 0) { 58221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.CreateCall(irb_.GetRuntime(rt)); 58321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } else { 58421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao std::vector<llvm::Value*> args; 58521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao for (unsigned i = 0; i < num_args; i++) { 58621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao args.push_back(inst.getArgOperand(i)); 58721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 58821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 58921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.CreateCall(irb_.GetRuntime(rt), args); 59021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 59121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 59221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 59367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chienvoid 59421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::EmitStackOverflowCheck(llvm::Instruction* first_non_alloca) { 59521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Function* func = first_non_alloca->getParent()->getParent(); 59621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Module* module = func->getParent(); 59721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 59821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Call llvm intrinsic function to get frame address. 59921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Function* frameaddress = 60021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Intrinsic::getDeclaration(module, llvm::Intrinsic::frameaddress); 60121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 60221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // The type of llvm::frameaddress is: i8* @llvm.frameaddress(i32) 60321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* frame_address = irb_.CreateCall(frameaddress, irb_.getInt32(0)); 60421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 60521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Cast i8* to int 60621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao frame_address = irb_.CreatePtrToInt(frame_address, irb_.getPtrEquivIntTy()); 60721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 60821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Get thread.stack_end_ 60921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* stack_end = 610920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa irb_.Runtime().EmitLoadFromThreadOffset(art::Thread::StackEndOffset().Int32Value(), 61121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getPtrEquivIntTy(), 61221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kTBAARuntimeInfo); 61321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 61421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Check the frame address < thread.stack_end_ ? 61521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* is_stack_overflow = irb_.CreateICmpULT(frame_address, stack_end); 61621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 61721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::BasicBlock* block_exception = 61821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::BasicBlock::Create(context_, "stack_overflow", func); 61921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 62021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::BasicBlock* block_continue = 62121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::BasicBlock::Create(context_, "stack_overflow_cont", func); 62221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 62321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateCondBr(is_stack_overflow, block_exception, block_continue, kUnlikely); 62421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 62521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // If stack overflow, throw exception. 62621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.SetInsertPoint(block_exception); 62721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateCall(irb_.GetRuntime(runtime_support::ThrowStackOverflowException)); 62821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 62921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Unwind. 63021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Type* ret_type = func->getReturnType(); 63121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao if (ret_type->isVoidTy()) { 63221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateRetVoid(); 63321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } else { 63421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // The return value is ignored when there's an exception. MethodCompiler 63521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // returns zero value under the the corresponding return type in this case. 63621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // GBCExpander returns LLVM undef value here for brevity 63721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateRet(llvm::UndefValue::get(ret_type)); 63821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 63921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 64021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.SetInsertPoint(block_continue); 64121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 64221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 643920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYallvm::Value* GBCExpanderPass::EmitLoadDexCacheAddr(art::MemberOffset offset) { 64421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 64521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 64621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.LoadFromObjectOffset(method_object_addr, 64721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao offset.Int32Value(), 64821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getJObjectTy(), 64921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kTBAAConstJObject); 65021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 65121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 65221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* 65321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::EmitLoadDexCacheStaticStorageFieldAddr(uint32_t type_idx) { 65421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* static_storage_dex_cache_addr = 65566f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier EmitLoadDexCacheAddr(art::AbstractMethod::DexCacheInitializedStaticStorageOffset()); 65621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 65721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* type_idx_value = irb_.getPtrEquivInt(type_idx); 65821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 65921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return EmitArrayGEP(static_storage_dex_cache_addr, type_idx_value, kObject); 66021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 66121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 66221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* 66321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::EmitLoadDexCacheResolvedTypeFieldAddr(uint32_t type_idx) { 66421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* resolved_type_dex_cache_addr = 66566f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier EmitLoadDexCacheAddr(art::AbstractMethod::DexCacheResolvedTypesOffset()); 66621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 66721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* type_idx_value = irb_.getPtrEquivInt(type_idx); 66821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 66921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return EmitArrayGEP(resolved_type_dex_cache_addr, type_idx_value, kObject); 67021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 67121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 67221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass:: 67321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoEmitLoadDexCacheResolvedMethodFieldAddr(uint32_t method_idx) { 67421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* resolved_method_dex_cache_addr = 67566f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier EmitLoadDexCacheAddr(art::AbstractMethod::DexCacheResolvedMethodsOffset()); 67621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 67721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* method_idx_value = irb_.getPtrEquivInt(method_idx); 67821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 67921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return EmitArrayGEP(resolved_method_dex_cache_addr, method_idx_value, kObject); 68021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 68121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 68221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass:: 68321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoEmitLoadDexCacheStringFieldAddr(uint32_t string_idx) { 68421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* string_dex_cache_addr = 68566f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier EmitLoadDexCacheAddr(art::AbstractMethod::DexCacheStringsOffset()); 68621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 68721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* string_idx_value = irb_.getPtrEquivInt(string_idx); 68821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 68921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return EmitArrayGEP(string_dex_cache_addr, string_idx_value, kObject); 69021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 69121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 69221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::EmitLoadMethodObjectAddr() { 69321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Function* parent_func = irb_.GetInsertBlock()->getParent(); 69421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return parent_func->arg_begin(); 69521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 69621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 69721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::EmitLoadArrayLength(llvm::Value* array) { 69821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Load array length 69921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.LoadFromObjectOffset(array, 700920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::Array::LengthOffset().Int32Value(), 70121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getJIntTy(), 70221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kTBAAConstJObject); 70321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 70421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 70521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 70621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* 70721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::EmitLoadSDCalleeMethodObjectAddr(uint32_t callee_method_idx) { 70821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* callee_method_object_field_addr = 70921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao EmitLoadDexCacheResolvedMethodFieldAddr(callee_method_idx); 71021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 711ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa return irb_.CreateLoad(callee_method_object_field_addr, kTBAARuntimeInfo); 71221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 71321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 71421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass:: 71521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoEmitLoadVirtualCalleeMethodObjectAddr(int vtable_idx, llvm::Value* this_addr) { 71621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Load class object of *this* pointer 71721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* class_object_addr = 71821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.LoadFromObjectOffset(this_addr, 719920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::Object::ClassOffset().Int32Value(), 72021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getJObjectTy(), 72121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kTBAAConstJObject); 72221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 72321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Load vtable address 72421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* vtable_addr = 72521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.LoadFromObjectOffset(class_object_addr, 726920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::Class::VTableOffset().Int32Value(), 72721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getJObjectTy(), 72821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kTBAAConstJObject); 72921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 73021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Load callee method object 73121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* vtable_idx_value = 73221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getPtrEquivInt(static_cast<uint64_t>(vtable_idx)); 73321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 73421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* method_field_addr = 73521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao EmitArrayGEP(vtable_addr, vtable_idx_value, kObject); 73621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 73721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.CreateLoad(method_field_addr, kTBAAConstJObject); 73821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 73921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 74021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao// Emit Array GetElementPtr 74121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::EmitArrayGEP(llvm::Value* array_addr, 74221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* index_value, 74321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType elem_jty) { 74421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 74521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao int data_offset; 74621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao if (elem_jty == kLong || elem_jty == kDouble || 747920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa (elem_jty == kObject && sizeof(uint64_t) == sizeof(art::Object*))) { 748920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa data_offset = art::Array::DataOffset(sizeof(int64_t)).Int32Value(); 74921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } else { 750920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa data_offset = art::Array::DataOffset(sizeof(int32_t)).Int32Value(); 75121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 75221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 75321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Constant* data_offset_value = 75421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getPtrEquivInt(data_offset); 75521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 75621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Type* elem_type = irb_.getJType(elem_jty, kArray); 75721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 75821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* array_data_addr = 75921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreatePtrDisp(array_addr, data_offset_value, 76021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao elem_type->getPointerTo()); 76121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 76221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.CreateGEP(array_data_addr, index_value); 76321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 76421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 76521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_TestSuspend(llvm::CallInst& call_inst) { 766ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 767ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa 768ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa llvm::Value* suspend_count = 769ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa irb_.Runtime().EmitLoadFromThreadOffset(art::Thread::ThreadFlagsOffset().Int32Value(), 770ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa irb_.getInt16Ty(), 771ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa kTBAARuntimeInfo); 772ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa llvm::Value* is_suspend = irb_.CreateICmpNE(suspend_count, irb_.getInt16(0)); 773ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa 774ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa llvm::BasicBlock* basic_block_suspend = CreateBasicBlockWithDexPC(dex_pc, "suspend"); 775ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa llvm::BasicBlock* basic_block_cont = CreateBasicBlockWithDexPC(dex_pc, "suspend_cont"); 776ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa 777ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa irb_.CreateCondBr(is_suspend, basic_block_suspend, basic_block_cont, kUnlikely); 778ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa 779ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa irb_.SetInsertPoint(basic_block_suspend); 780ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa if (dex_pc != art::DexFile::kDexNoIndex) { 781ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa EmitUpdateDexPC(dex_pc); 782ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa } 78321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.Runtime().EmitTestSuspend(); 784ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa irb_.CreateBr(basic_block_cont); 785ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa 786ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa irb_.SetInsertPoint(basic_block_cont); 78721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 78821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 78921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 7909a129457c233b653c7a8f65c963509267252b0a7TDYavoid GBCExpanderPass::Expand_MarkGCCard(llvm::CallInst& call_inst) { 7919a129457c233b653c7a8f65c963509267252b0a7TDYa irb_.Runtime().EmitMarkGCCard(call_inst.getArgOperand(0), call_inst.getArgOperand(1)); 7929a129457c233b653c7a8f65c963509267252b0a7TDYa return; 7939a129457c233b653c7a8f65c963509267252b0a7TDYa} 7949a129457c233b653c7a8f65c963509267252b0a7TDYa 79521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* 79621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::Expand_LoadStringFromDexCache(llvm::Value* string_idx_value) { 79721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao uint32_t string_idx = 79821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(string_idx_value)->getZExtValue(); 79921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 80021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* string_field_addr = EmitLoadDexCacheStringFieldAddr(string_idx); 80121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 802ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa return irb_.CreateLoad(string_field_addr, kTBAARuntimeInfo); 80321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 80421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 80521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* 80621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::Expand_LoadTypeFromDexCache(llvm::Value* type_idx_value) { 80721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao uint32_t type_idx = 80821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(type_idx_value)->getZExtValue(); 80921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 81021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* type_field_addr = 81121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao EmitLoadDexCacheResolvedTypeFieldAddr(type_idx); 81221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 813ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa return irb_.CreateLoad(type_field_addr, kTBAARuntimeInfo); 81421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 81521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 81621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_LockObject(llvm::Value* obj) { 81721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao rtb_.EmitLockObject(obj); 81821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 81921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 82021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 82121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_UnlockObject(llvm::Value* obj) { 82221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao rtb_.EmitUnlockObject(obj); 82321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 82421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 82521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 82621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::Expand_ArrayGet(llvm::Value* array_addr, 82721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* index_value, 82821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType elem_jty) { 82921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* array_elem_addr = 83021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao EmitArrayGEP(array_addr, index_value, elem_jty); 83121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 83221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.CreateLoad(array_elem_addr, kTBAAHeapArray, elem_jty); 83321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 83421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 83521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_ArrayPut(llvm::Value* new_value, 83621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* array_addr, 83721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* index_value, 83821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType elem_jty) { 83921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* array_elem_addr = 84021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao EmitArrayGEP(array_addr, index_value, elem_jty); 84121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 84221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateStore(new_value, array_elem_addr, kTBAAHeapArray, elem_jty); 84321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 84421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 84521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 84621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 84721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_FilledNewArray(llvm::CallInst& call_inst) { 84821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Most of the codes refer to MethodCompiler::EmitInsn_FilledNewArray 84921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* array = call_inst.getArgOperand(0); 85021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 85121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao uint32_t element_jty = 85221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(call_inst.getArgOperand(1))->getZExtValue(); 85321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 85421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao DCHECK(call_inst.getNumArgOperands() > 2); 85521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao unsigned num_elements = (call_inst.getNumArgOperands() - 2); 85621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 85721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao bool is_elem_int_ty = (static_cast<JType>(element_jty) == kInt); 85821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 85921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao uint32_t alignment; 86021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Constant* elem_size; 86121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::PointerType* field_type; 86221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 86321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // NOTE: Currently filled-new-array only supports 'L', '[', and 'I' 86421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // as the element, thus we are only checking 2 cases: primitive int and 86521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // non-primitive type. 86621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao if (is_elem_int_ty) { 86721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao alignment = sizeof(int32_t); 86821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao elem_size = irb_.getPtrEquivInt(sizeof(int32_t)); 86921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao field_type = irb_.getJIntTy()->getPointerTo(); 87021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } else { 87121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao alignment = irb_.getSizeOfPtrEquivInt(); 87221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao elem_size = irb_.getSizeOfPtrEquivIntValue(); 87321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao field_type = irb_.getJObjectTy()->getPointerTo(); 87421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 87521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 87621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* data_field_offset = 877920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa irb_.getPtrEquivInt(art::Array::DataOffset(alignment).Int32Value()); 87821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 87921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* data_field_addr = 88021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreatePtrDisp(array, data_field_offset, field_type); 88121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 88221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao for (unsigned i = 0; i < num_elements; ++i) { 88321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Values to fill the array begin at the 3rd argument 88421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* reg_value = call_inst.getArgOperand(2 + i); 88521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 88621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateStore(reg_value, data_field_addr, kTBAAHeapArray); 88721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 88821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao data_field_addr = 88921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreatePtrDisp(data_field_addr, elem_size, field_type); 89021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 89121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 89221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 89321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 89421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 89521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::Expand_IGetFast(llvm::Value* field_offset_value, 89621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* /*is_volatile_value*/, 89721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* object_addr, 89821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType field_jty) { 89921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao int field_offset = 90021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue(); 90121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 90221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao DCHECK_GE(field_offset, 0); 90321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 90421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::PointerType* field_type = 90521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getJType(field_jty, kField)->getPointerTo(); 90621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 90721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao field_offset_value = irb_.getPtrEquivInt(field_offset); 90821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 90921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* field_addr = 91021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreatePtrDisp(object_addr, field_offset_value, field_type); 91121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 91221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // TODO: Check is_volatile. We need to generate atomic load instruction 91321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // when is_volatile is true. 91421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.CreateLoad(field_addr, kTBAAHeapInstance, field_jty); 91521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 91621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 91721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_IPutFast(llvm::Value* field_offset_value, 91821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* /* is_volatile_value */, 91921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* object_addr, 92021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* new_value, 92121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType field_jty) { 92221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao int field_offset = 92321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue(); 92421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 92521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao DCHECK_GE(field_offset, 0); 92621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 92721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::PointerType* field_type = 92821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getJType(field_jty, kField)->getPointerTo(); 92921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 93021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao field_offset_value = irb_.getPtrEquivInt(field_offset); 93121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 93221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* field_addr = 93321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreatePtrDisp(object_addr, field_offset_value, field_type); 93421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 93521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // TODO: Check is_volatile. We need to generate atomic store instruction 93621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // when is_volatile is true. 93721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateStore(new_value, field_addr, kTBAAHeapInstance, field_jty); 93821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 93921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 94021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 94121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 94221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::Expand_SGetFast(llvm::Value* static_storage_addr, 94321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* field_offset_value, 94421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* /*is_volatile_value*/, 94521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType field_jty) { 94621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao int field_offset = 94721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue(); 94821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 94921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao DCHECK_GE(field_offset, 0); 95021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 95121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset); 95221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 95321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* static_field_addr = 95421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value, 95521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getJType(field_jty, kField)->getPointerTo()); 95621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 95721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // TODO: Check is_volatile. We need to generate atomic store instruction 95821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // when is_volatile is true. 95921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.CreateLoad(static_field_addr, kTBAAHeapStatic, field_jty); 96021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 96121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 96221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_SPutFast(llvm::Value* static_storage_addr, 96321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* field_offset_value, 96421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* /* is_volatile_value */, 96521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* new_value, 96621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType field_jty) { 96721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao int field_offset = 96821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue(); 96921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 97021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao DCHECK_GE(field_offset, 0); 97121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 97221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset); 97321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 97421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* static_field_addr = 97521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value, 97621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getJType(field_jty, kField)->getPointerTo()); 97721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 97821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // TODO: Check is_volatile. We need to generate atomic store instruction 97921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // when is_volatile is true. 98021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateStore(new_value, static_field_addr, kTBAAHeapStatic, field_jty); 98121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 98221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 98321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 98421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 98521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* 98621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::Expand_LoadDeclaringClassSSB(llvm::Value* method_object_addr) { 98721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.LoadFromObjectOffset(method_object_addr, 98866f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier art::AbstractMethod::DeclaringClassOffset().Int32Value(), 98921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getJObjectTy(), 99021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kTBAAConstJObject); 99121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 99221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 99321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* 99421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::Expand_LoadClassSSBFromDexCache(llvm::Value* type_idx_value) { 99521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao uint32_t type_idx = 99621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(type_idx_value)->getZExtValue(); 99721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 99821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* storage_field_addr = 99921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao EmitLoadDexCacheStaticStorageFieldAddr(type_idx); 100021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 1001ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa return irb_.CreateLoad(storage_field_addr, kTBAARuntimeInfo); 100221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 100321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 100421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* 100521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::Expand_GetSDCalleeMethodObjAddrFast(llvm::Value* callee_method_idx_value) { 100621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao uint32_t callee_method_idx = 100721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(callee_method_idx_value)->getZExtValue(); 100821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 100921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return EmitLoadSDCalleeMethodObjectAddr(callee_method_idx); 101021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 101121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 101221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::Expand_GetVirtualCalleeMethodObjAddrFast( 101321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* vtable_idx_value, 101421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* this_addr) { 101521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao int vtable_idx = 101621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(vtable_idx_value)->getSExtValue(); 101721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 101821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return EmitLoadVirtualCalleeMethodObjectAddr(vtable_idx, this_addr); 101921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 102021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 102121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::Expand_Invoke(llvm::CallInst& call_inst) { 102221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Most of the codes refer to MethodCompiler::EmitInsn_Invoke 102321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* callee_method_object_addr = call_inst.getArgOperand(0); 102421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao unsigned num_args = call_inst.getNumArgOperands(); 102521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Type* ret_type = call_inst.getType(); 102621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 102721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Determine the function type of the callee method 102821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao std::vector<llvm::Type*> args_type; 102921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao std::vector<llvm::Value*> args; 103021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao for (unsigned i = 0; i < num_args; i++) { 103121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao args.push_back(call_inst.getArgOperand(i)); 103221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao args_type.push_back(args[i]->getType()); 103321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 103421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 103521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::FunctionType* callee_method_type = 103621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::FunctionType::get(ret_type, args_type, false); 103721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 103821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* code_addr = 103921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.LoadFromObjectOffset(callee_method_object_addr, 104066f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier art::AbstractMethod::GetCodeOffset().Int32Value(), 104121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao callee_method_type->getPointerTo(), 1042ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa kTBAARuntimeInfo); 104321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 104421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Invoke callee 104521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* retval = irb_.CreateCall(code_addr, args); 104621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 104721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return retval; 104821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 104921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 10504ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYallvm::Value* GBCExpanderPass::Expand_DivRem(llvm::CallInst& call_inst, 105121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao bool is_div, JType op_jty) { 10524ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa llvm::Value* dividend = call_inst.getArgOperand(0); 10534ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa llvm::Value* divisor = call_inst.getArgOperand(1); 1054c531cefbfb5394413122e9f57d211ba436cff012buzbee#if defined(ART_USE_PORTABLE_COMPILER) 10554ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 10564ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa EmitGuard_DivZeroException(dex_pc, divisor, op_jty); 10574ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa#endif 105821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Most of the codes refer to MethodCompiler::EmitIntDivRemResultComputation 105921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 106021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Check the special case: MININT / -1 = MININT 106121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // That case will cause overflow, which is undefined behavior in llvm. 106221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // So we check the divisor is -1 or not, if the divisor is -1, we do 106321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // the special path to avoid undefined behavior. 106421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Type* op_type = irb_.getJType(op_jty, kAccurate); 106521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* zero = irb_.getJZero(op_jty); 106621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* neg_one = llvm::ConstantInt::getSigned(op_type, -1); 106721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 10685e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Function* parent = irb_.GetInsertBlock()->getParent(); 106921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::BasicBlock* eq_neg_one = llvm::BasicBlock::Create(context_, "", parent); 107021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::BasicBlock* ne_neg_one = llvm::BasicBlock::Create(context_, "", parent); 107121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::BasicBlock* neg_one_cont = 107221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::BasicBlock::Create(context_, "", parent); 107321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 107421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* is_equal_neg_one = irb_.CreateICmpEQ(divisor, neg_one); 107521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateCondBr(is_equal_neg_one, eq_neg_one, ne_neg_one, kUnlikely); 107621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 107721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // If divisor == -1 107821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.SetInsertPoint(eq_neg_one); 107921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* eq_result; 108021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao if (is_div) { 108121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // We can just change from "dividend div -1" to "neg dividend". The sub 108221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // don't care the sign/unsigned because of two's complement representation. 108321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // And the behavior is what we want: 108421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // -(2^n) (2^n)-1 108521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // MININT < k <= MAXINT -> mul k -1 = -k 108621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // MININT == k -> mul k -1 = k 108721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // 108821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // LLVM use sub to represent 'neg' 108921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao eq_result = irb_.CreateSub(zero, dividend); 109021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } else { 109121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Everything modulo -1 will be 0. 109221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao eq_result = zero; 109321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 109421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateBr(neg_one_cont); 109521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 109621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // If divisor != -1, just do the division. 109721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.SetInsertPoint(ne_neg_one); 109821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* ne_result; 109921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao if (is_div) { 110021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao ne_result = irb_.CreateSDiv(dividend, divisor); 110121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } else { 110221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao ne_result = irb_.CreateSRem(dividend, divisor); 110321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 110421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateBr(neg_one_cont); 110521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 110621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.SetInsertPoint(neg_one_cont); 110721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::PHINode* result = irb_.CreatePHI(op_type, 2); 110821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao result->addIncoming(eq_result, eq_neg_one); 110921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao result->addIncoming(ne_result, ne_neg_one); 111021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 111121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return result; 111221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 111321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 1114ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYavoid GBCExpanderPass::Expand_AllocaShadowFrame(llvm::Value* num_vregs_value) { 111521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Most of the codes refer to MethodCompiler::EmitPrologueAllocShadowFrame and 111621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // MethodCompiler::EmitPushShadowFrame 11178e950c117975d23f50ed7e32ca5db01a813c25d0TDYa uint16_t num_vregs = 11188e950c117975d23f50ed7e32ca5db01a813c25d0TDYa llvm::cast<llvm::ConstantInt>(num_vregs_value)->getZExtValue(); 111921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 112021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::StructType* shadow_frame_type = 1121ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa irb_.getShadowFrameTy(num_vregs); 112221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 112321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao shadow_frame_ = irb_.CreateAlloca(shadow_frame_type); 112421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 112521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Alloca a pointer to old shadow frame 112621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao old_shadow_frame_ = 112721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateAlloca(shadow_frame_type->getElementType(0)->getPointerTo()); 112821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 112921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Push the shadow frame 113021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 113121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 113221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* shadow_frame_upcast = 113321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateConstGEP2_32(shadow_frame_, 0, 0); 113421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 113521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* result = rtb_.EmitPushShadowFrame(shadow_frame_upcast, 113621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao method_object_addr, 11378e950c117975d23f50ed7e32ca5db01a813c25d0TDYa num_vregs); 113821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 113921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateStore(result, old_shadow_frame_, kTBAARegister); 114021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 114121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 114221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 114321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 11448e950c117975d23f50ed7e32ca5db01a813c25d0TDYavoid GBCExpanderPass::Expand_SetVReg(llvm::Value* entry_idx, 11458e950c117975d23f50ed7e32ca5db01a813c25d0TDYa llvm::Value* value) { 11468e950c117975d23f50ed7e32ca5db01a813c25d0TDYa DCHECK(shadow_frame_ != NULL); 11478e950c117975d23f50ed7e32ca5db01a813c25d0TDYa 11488e950c117975d23f50ed7e32ca5db01a813c25d0TDYa llvm::Value* gep_index[] = { 11498e950c117975d23f50ed7e32ca5db01a813c25d0TDYa irb_.getInt32(0), // No pointer displacement 1150ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa irb_.getInt32(1), // VRegs 11518e950c117975d23f50ed7e32ca5db01a813c25d0TDYa entry_idx // Pointer field 11528e950c117975d23f50ed7e32ca5db01a813c25d0TDYa }; 11538e950c117975d23f50ed7e32ca5db01a813c25d0TDYa 11548e950c117975d23f50ed7e32ca5db01a813c25d0TDYa llvm::Value* vreg_addr = irb_.CreateGEP(shadow_frame_, gep_index); 11558e950c117975d23f50ed7e32ca5db01a813c25d0TDYa 11568e950c117975d23f50ed7e32ca5db01a813c25d0TDYa irb_.CreateStore(value, 11578e950c117975d23f50ed7e32ca5db01a813c25d0TDYa irb_.CreateBitCast(vreg_addr, value->getType()->getPointerTo()), 11588e950c117975d23f50ed7e32ca5db01a813c25d0TDYa kTBAAShadowFrame); 11598e950c117975d23f50ed7e32ca5db01a813c25d0TDYa return; 11608e950c117975d23f50ed7e32ca5db01a813c25d0TDYa} 11618e950c117975d23f50ed7e32ca5db01a813c25d0TDYa 116221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_PopShadowFrame() { 1163c531cefbfb5394413122e9f57d211ba436cff012buzbee#if defined(ART_USE_PORTABLE_COMPILER) 1164bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao if (old_shadow_frame_ == NULL) { 1165bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao return; 1166bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao } 1167bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao#endif 116821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao rtb_.EmitPopShadowFrame(irb_.CreateLoad(old_shadow_frame_, kTBAARegister)); 116921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 117021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 117121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 117221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_UpdateDexPC(llvm::Value* dex_pc_value) { 117321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.StoreToObjectOffset(shadow_frame_, 1174920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::ShadowFrame::DexPCOffset(), 117521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao dex_pc_value, 117621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kTBAAShadowFrame); 117721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 117821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 117921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 118067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chienvoid GBCExpanderPass::InsertStackOverflowCheck(llvm::Function& func) { 11814028312f6f4b49fd69992daf28cd37dd32e79a47jeffhao // All alloca instructions are generated in the first basic block of the 11824028312f6f4b49fd69992daf28cd37dd32e79a47jeffhao // function, and there are no alloca instructions after the first non-alloca 11834028312f6f4b49fd69992daf28cd37dd32e79a47jeffhao // instruction. 118421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 118567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock* first_basic_block = &func.front(); 118667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 118767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Look for first non-alloca instruction 118867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock::iterator first_non_alloca = first_basic_block->begin(); 118921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao while (llvm::isa<llvm::AllocaInst>(first_non_alloca)) { 119021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao ++first_non_alloca; 119121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 119221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 119367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien irb_.SetInsertPoint(first_non_alloca); 119467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 119521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Insert stack overflow check codes before first_non_alloca (i.e., after all 119621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // alloca instructions) 119767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien EmitStackOverflowCheck(&*first_non_alloca); 119867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 1199c531cefbfb5394413122e9f57d211ba436cff012buzbee#if defined(ART_USE_PORTABLE_COMPILER) 1200890ea89879ba555a08433146058d516575646c59TDYa irb_.Runtime().EmitTestSuspend(); 1201890ea89879ba555a08433146058d516575646c59TDYa#endif 1202890ea89879ba555a08433146058d516575646c59TDYa 120367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock* next_basic_block = irb_.GetInsertBlock(); 120467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien if (next_basic_block != first_basic_block) { 120567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Splice the rest of the instruction to the continuing basic block 120667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien next_basic_block->getInstList().splice( 120767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien irb_.GetInsertPoint(), first_basic_block->getInstList(), 120867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien first_non_alloca, first_basic_block->end()); 120967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 121067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Rewrite the basic block 121167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien RewriteBasicBlock(next_basic_block); 121267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 121367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Update the phi-instructions in the successor basic block 121467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien UpdatePhiInstruction(first_basic_block, irb_.GetInsertBlock()); 121567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien } 121667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 121767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // We have changed the basic block 121867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien changed_ = true; 121921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 122021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 12215e869b6560f918837cc6be3a50234deb2be46385TDYa// ==== High-level intrinsic expander ========================================== 12225e869b6560f918837cc6be3a50234deb2be46385TDYa 1223a1b2185820e6080864d18a35759cc046dc4ee578TDYallvm::Value* GBCExpanderPass::Expand_FPCompare(llvm::Value* src1_value, 1224a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* src2_value, 1225a1b2185820e6080864d18a35759cc046dc4ee578TDYa bool gt_bias) { 1226a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* cmp_eq = irb_.CreateFCmpOEQ(src1_value, src2_value); 1227a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* cmp_lt; 1228a1b2185820e6080864d18a35759cc046dc4ee578TDYa 1229a1b2185820e6080864d18a35759cc046dc4ee578TDYa if (gt_bias) { 1230a1b2185820e6080864d18a35759cc046dc4ee578TDYa cmp_lt = irb_.CreateFCmpOLT(src1_value, src2_value); 1231a1b2185820e6080864d18a35759cc046dc4ee578TDYa } else { 1232a1b2185820e6080864d18a35759cc046dc4ee578TDYa cmp_lt = irb_.CreateFCmpULT(src1_value, src2_value); 1233a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 1234a1b2185820e6080864d18a35759cc046dc4ee578TDYa 1235a1b2185820e6080864d18a35759cc046dc4ee578TDYa return EmitCompareResultSelection(cmp_eq, cmp_lt); 1236a1b2185820e6080864d18a35759cc046dc4ee578TDYa} 1237a1b2185820e6080864d18a35759cc046dc4ee578TDYa 1238a1b2185820e6080864d18a35759cc046dc4ee578TDYallvm::Value* GBCExpanderPass::Expand_LongCompare(llvm::Value* src1_value, llvm::Value* src2_value) { 1239a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* cmp_eq = irb_.CreateICmpEQ(src1_value, src2_value); 1240a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* cmp_lt = irb_.CreateICmpSLT(src1_value, src2_value); 1241a1b2185820e6080864d18a35759cc046dc4ee578TDYa 1242a1b2185820e6080864d18a35759cc046dc4ee578TDYa return EmitCompareResultSelection(cmp_eq, cmp_lt); 1243a1b2185820e6080864d18a35759cc046dc4ee578TDYa} 1244a1b2185820e6080864d18a35759cc046dc4ee578TDYa 1245a1b2185820e6080864d18a35759cc046dc4ee578TDYallvm::Value* GBCExpanderPass::EmitCompareResultSelection(llvm::Value* cmp_eq, 1246a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* cmp_lt) { 1247a1b2185820e6080864d18a35759cc046dc4ee578TDYa 1248a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Constant* zero = irb_.getJInt(0); 1249a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Constant* pos1 = irb_.getJInt(1); 1250a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Constant* neg1 = irb_.getJInt(-1); 1251a1b2185820e6080864d18a35759cc046dc4ee578TDYa 1252a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* result_lt = irb_.CreateSelect(cmp_lt, neg1, pos1); 1253a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* result_eq = irb_.CreateSelect(cmp_eq, zero, result_lt); 1254a1b2185820e6080864d18a35759cc046dc4ee578TDYa 1255a1b2185820e6080864d18a35759cc046dc4ee578TDYa return result_eq; 1256a1b2185820e6080864d18a35759cc046dc4ee578TDYa} 1257a1b2185820e6080864d18a35759cc046dc4ee578TDYa 125875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chienllvm::Value* GBCExpanderPass::Expand_IntegerShift(llvm::Value* src1_value, 125975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien llvm::Value* src2_value, 126075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien IntegerShiftKind kind, 126175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien JType op_jty) { 126275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien DCHECK(op_jty == kInt || op_jty == kLong); 126375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 126475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien // Mask and zero-extend RHS properly 126575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien if (op_jty == kInt) { 126675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien src2_value = irb_.CreateAnd(src2_value, 0x1f); 126775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } else { 126875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien llvm::Value* masked_src2_value = irb_.CreateAnd(src2_value, 0x3f); 126975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien src2_value = irb_.CreateZExt(masked_src2_value, irb_.getJLongTy()); 127075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 127175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 127275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien // Create integer shift llvm instruction 127375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien switch (kind) { 127475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case kIntegerSHL: 127575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return irb_.CreateShl(src1_value, src2_value); 127675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 127775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case kIntegerSHR: 127875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return irb_.CreateAShr(src1_value, src2_value); 127975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 128075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case kIntegerUSHR: 128175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return irb_.CreateLShr(src1_value, src2_value); 128275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 128375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien default: 128475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien LOG(FATAL) << "Unknown integer shift kind: " << kind; 128575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 128675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 128775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien} 128875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 12895a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYallvm::Value* GBCExpanderPass::Expand_HLArrayGet(llvm::CallInst& call_inst, 12905a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa JType elem_jty) { 12915a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 12925a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* array_addr = call_inst.getArgOperand(1); 12935a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* index_value = call_inst.getArgOperand(2); 1294920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 12955a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 1296920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa if (!(opt_flags & MIR_IGNORE_NULL_CHECK)) { 1297920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa EmitGuard_NullPointerException(dex_pc, array_addr); 1298920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa } 1299920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa if (!(opt_flags & MIR_IGNORE_RANGE_CHECK)) { 1300920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa EmitGuard_ArrayIndexOutOfBoundsException(dex_pc, array_addr, index_value); 1301920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa } 13025a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13035a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* array_elem_addr = EmitArrayGEP(array_addr, index_value, elem_jty); 13045a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13055a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* array_elem_value = irb_.CreateLoad(array_elem_addr, kTBAAHeapArray, elem_jty); 13065a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13075a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa switch (elem_jty) { 13085a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa case kVoid: 13095a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa break; 13105a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13115a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa case kBoolean: 13125a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa case kChar: 13135a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa array_elem_value = irb_.CreateZExt(array_elem_value, irb_.getJType(elem_jty, kReg)); 13145a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa break; 13155a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13165a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa case kByte: 13175a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa case kShort: 13185a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa array_elem_value = irb_.CreateSExt(array_elem_value, irb_.getJType(elem_jty, kReg)); 13195a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa break; 13205a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13215a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa case kInt: 13225a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa case kLong: 13235a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa case kFloat: 13245a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa case kDouble: 13255a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa case kObject: 13265a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa break; 13275a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13285a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa default: 13295a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa LOG(FATAL) << "Unknown java type: " << elem_jty; 13305a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 13315a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13325a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return array_elem_value; 13335a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa} 13345a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13355a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13365a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYavoid GBCExpanderPass::Expand_HLArrayPut(llvm::CallInst& call_inst, 13375a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa JType elem_jty) { 13385a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 13395a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* new_value = call_inst.getArgOperand(1); 13405a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* array_addr = call_inst.getArgOperand(2); 13415a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* index_value = call_inst.getArgOperand(3); 1342920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 13435a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 1344920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa if (!(opt_flags & MIR_IGNORE_NULL_CHECK)) { 1345920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa EmitGuard_NullPointerException(dex_pc, array_addr); 1346920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa } 1347920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa if (!(opt_flags & MIR_IGNORE_RANGE_CHECK)) { 1348920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa EmitGuard_ArrayIndexOutOfBoundsException(dex_pc, array_addr, index_value); 1349920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa } 13505a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13515a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa switch (elem_jty) { 13525a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa case kVoid: 13535a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa break; 13545a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13555a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa case kBoolean: 13565a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa case kChar: 1357bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao case kByte: 1358bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao case kShort: 13595a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa new_value = irb_.CreateTrunc(new_value, irb_.getJType(elem_jty, kArray)); 13605a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa break; 13615a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13625a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa case kInt: 13635a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa case kLong: 13645a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa case kFloat: 13655a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa case kDouble: 13665a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa case kObject: 13675a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa break; 13685a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13695a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa default: 13705a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa LOG(FATAL) << "Unknown java type: " << elem_jty; 13715a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 13725a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13735a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* array_elem_addr = EmitArrayGEP(array_addr, index_value, elem_jty); 13745a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13755a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa if (elem_jty == kObject) { // If put an object, check the type, and mark GC card table. 13765a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Function* runtime_func = irb_.GetRuntime(runtime_support::CheckPutArrayElement); 13775a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13785a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreateCall2(runtime_func, new_value, array_addr); 13795a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13805a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitGuard_ExceptionLandingPad(dex_pc); 13815a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13825a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitMarkGCCard(new_value, array_addr); 13835a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 13845a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13855a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreateStore(new_value, array_elem_addr, kTBAAHeapArray, elem_jty); 13865a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13875a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return; 13885a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa} 13895a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 13905e869b6560f918837cc6be3a50234deb2be46385TDYallvm::Value* GBCExpanderPass::Expand_HLIGet(llvm::CallInst& call_inst, 13915e869b6560f918837cc6be3a50234deb2be46385TDYa JType field_jty) { 13925e869b6560f918837cc6be3a50234deb2be46385TDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 13935e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* object_addr = call_inst.getArgOperand(1); 13945e869b6560f918837cc6be3a50234deb2be46385TDYa uint32_t field_idx = LV2UInt(call_inst.getArgOperand(2)); 1395920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 13965e869b6560f918837cc6be3a50234deb2be46385TDYa 1397920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa if (!(opt_flags & MIR_IGNORE_NULL_CHECK)) { 1398920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa EmitGuard_NullPointerException(dex_pc, object_addr); 1399920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa } 14005e869b6560f918837cc6be3a50234deb2be46385TDYa 14015e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* field_value; 14025e869b6560f918837cc6be3a50234deb2be46385TDYa 14035e869b6560f918837cc6be3a50234deb2be46385TDYa int field_offset; 14045e869b6560f918837cc6be3a50234deb2be46385TDYa bool is_volatile; 14055e869b6560f918837cc6be3a50234deb2be46385TDYa bool is_fast_path = compiler_->ComputeInstanceFieldInfo( 14065e869b6560f918837cc6be3a50234deb2be46385TDYa field_idx, oat_compilation_unit_, field_offset, is_volatile, false); 14075e869b6560f918837cc6be3a50234deb2be46385TDYa 14085e869b6560f918837cc6be3a50234deb2be46385TDYa if (!is_fast_path) { 14095e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Function* runtime_func; 14105e869b6560f918837cc6be3a50234deb2be46385TDYa 14115e869b6560f918837cc6be3a50234deb2be46385TDYa if (field_jty == kObject) { 14125e869b6560f918837cc6be3a50234deb2be46385TDYa runtime_func = irb_.GetRuntime(runtime_support::GetObjectInstance); 14135e869b6560f918837cc6be3a50234deb2be46385TDYa } else if (field_jty == kLong || field_jty == kDouble) { 14145e869b6560f918837cc6be3a50234deb2be46385TDYa runtime_func = irb_.GetRuntime(runtime_support::Get64Instance); 14155e869b6560f918837cc6be3a50234deb2be46385TDYa } else { 14165e869b6560f918837cc6be3a50234deb2be46385TDYa runtime_func = irb_.GetRuntime(runtime_support::Get32Instance); 14175e869b6560f918837cc6be3a50234deb2be46385TDYa } 14185e869b6560f918837cc6be3a50234deb2be46385TDYa 14195e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::ConstantInt* field_idx_value = irb_.getInt32(field_idx); 14205e869b6560f918837cc6be3a50234deb2be46385TDYa 14215e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 14225e869b6560f918837cc6be3a50234deb2be46385TDYa 14235e869b6560f918837cc6be3a50234deb2be46385TDYa EmitUpdateDexPC(dex_pc); 14245e869b6560f918837cc6be3a50234deb2be46385TDYa 14255e869b6560f918837cc6be3a50234deb2be46385TDYa field_value = irb_.CreateCall3(runtime_func, field_idx_value, 14265e869b6560f918837cc6be3a50234deb2be46385TDYa method_object_addr, object_addr); 14275e869b6560f918837cc6be3a50234deb2be46385TDYa 14285e869b6560f918837cc6be3a50234deb2be46385TDYa EmitGuard_ExceptionLandingPad(dex_pc); 14295e869b6560f918837cc6be3a50234deb2be46385TDYa 14305e869b6560f918837cc6be3a50234deb2be46385TDYa } else { 14315e869b6560f918837cc6be3a50234deb2be46385TDYa DCHECK_GE(field_offset, 0); 14325e869b6560f918837cc6be3a50234deb2be46385TDYa 14335e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::PointerType* field_type = 14345e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.getJType(field_jty, kField)->getPointerTo(); 14355e869b6560f918837cc6be3a50234deb2be46385TDYa 14365e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::ConstantInt* field_offset_value = irb_.getPtrEquivInt(field_offset); 14375e869b6560f918837cc6be3a50234deb2be46385TDYa 14385e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* field_addr = 14395e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreatePtrDisp(object_addr, field_offset_value, field_type); 14405e869b6560f918837cc6be3a50234deb2be46385TDYa 14415e869b6560f918837cc6be3a50234deb2be46385TDYa // TODO: Check is_volatile. We need to generate atomic load instruction 14425e869b6560f918837cc6be3a50234deb2be46385TDYa // when is_volatile is true. 14435e869b6560f918837cc6be3a50234deb2be46385TDYa field_value = irb_.CreateLoad(field_addr, kTBAAHeapInstance, field_jty); 14445e869b6560f918837cc6be3a50234deb2be46385TDYa } 14455e869b6560f918837cc6be3a50234deb2be46385TDYa 14465e869b6560f918837cc6be3a50234deb2be46385TDYa if (field_jty == kFloat || field_jty == kDouble) { 14475a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa field_value = irb_.CreateBitCast(field_value, irb_.getJType(field_jty, kAccurate)); 14485e869b6560f918837cc6be3a50234deb2be46385TDYa } 14495e869b6560f918837cc6be3a50234deb2be46385TDYa 14505e869b6560f918837cc6be3a50234deb2be46385TDYa return field_value; 14515e869b6560f918837cc6be3a50234deb2be46385TDYa} 14525e869b6560f918837cc6be3a50234deb2be46385TDYa 14535e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::Expand_HLIPut(llvm::CallInst& call_inst, 14545e869b6560f918837cc6be3a50234deb2be46385TDYa JType field_jty) { 14555e869b6560f918837cc6be3a50234deb2be46385TDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 1456bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao llvm::Value* new_value = call_inst.getArgOperand(1); 1457bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao llvm::Value* object_addr = call_inst.getArgOperand(2); 14585e869b6560f918837cc6be3a50234deb2be46385TDYa uint32_t field_idx = LV2UInt(call_inst.getArgOperand(3)); 1459920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 14605e869b6560f918837cc6be3a50234deb2be46385TDYa 14615e869b6560f918837cc6be3a50234deb2be46385TDYa if (field_jty == kFloat || field_jty == kDouble) { 14625a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa new_value = irb_.CreateBitCast(new_value, irb_.getJType(field_jty, kField)); 14635e869b6560f918837cc6be3a50234deb2be46385TDYa } 14645e869b6560f918837cc6be3a50234deb2be46385TDYa 1465920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa if (!(opt_flags & MIR_IGNORE_NULL_CHECK)) { 1466920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa EmitGuard_NullPointerException(dex_pc, object_addr); 1467920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa } 14685e869b6560f918837cc6be3a50234deb2be46385TDYa 14695e869b6560f918837cc6be3a50234deb2be46385TDYa int field_offset; 14705e869b6560f918837cc6be3a50234deb2be46385TDYa bool is_volatile; 14715e869b6560f918837cc6be3a50234deb2be46385TDYa bool is_fast_path = compiler_->ComputeInstanceFieldInfo( 14725e869b6560f918837cc6be3a50234deb2be46385TDYa field_idx, oat_compilation_unit_, field_offset, is_volatile, true); 14735e869b6560f918837cc6be3a50234deb2be46385TDYa 14745e869b6560f918837cc6be3a50234deb2be46385TDYa if (!is_fast_path) { 14755e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Function* runtime_func; 14765e869b6560f918837cc6be3a50234deb2be46385TDYa 14775e869b6560f918837cc6be3a50234deb2be46385TDYa if (field_jty == kObject) { 14785e869b6560f918837cc6be3a50234deb2be46385TDYa runtime_func = irb_.GetRuntime(runtime_support::SetObjectInstance); 14795e869b6560f918837cc6be3a50234deb2be46385TDYa } else if (field_jty == kLong || field_jty == kDouble) { 14805e869b6560f918837cc6be3a50234deb2be46385TDYa runtime_func = irb_.GetRuntime(runtime_support::Set64Instance); 14815e869b6560f918837cc6be3a50234deb2be46385TDYa } else { 14825e869b6560f918837cc6be3a50234deb2be46385TDYa runtime_func = irb_.GetRuntime(runtime_support::Set32Instance); 14835e869b6560f918837cc6be3a50234deb2be46385TDYa } 14845e869b6560f918837cc6be3a50234deb2be46385TDYa 14855e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* field_idx_value = irb_.getInt32(field_idx); 14865e869b6560f918837cc6be3a50234deb2be46385TDYa 14875e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 14885e869b6560f918837cc6be3a50234deb2be46385TDYa 14895e869b6560f918837cc6be3a50234deb2be46385TDYa EmitUpdateDexPC(dex_pc); 14905e869b6560f918837cc6be3a50234deb2be46385TDYa 14915e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateCall4(runtime_func, field_idx_value, 14925e869b6560f918837cc6be3a50234deb2be46385TDYa method_object_addr, object_addr, new_value); 14935e869b6560f918837cc6be3a50234deb2be46385TDYa 14945e869b6560f918837cc6be3a50234deb2be46385TDYa EmitGuard_ExceptionLandingPad(dex_pc); 14955e869b6560f918837cc6be3a50234deb2be46385TDYa 14965e869b6560f918837cc6be3a50234deb2be46385TDYa } else { 14975e869b6560f918837cc6be3a50234deb2be46385TDYa DCHECK_GE(field_offset, 0); 14985e869b6560f918837cc6be3a50234deb2be46385TDYa 14995e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::PointerType* field_type = 15005e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.getJType(field_jty, kField)->getPointerTo(); 15015e869b6560f918837cc6be3a50234deb2be46385TDYa 15025e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* field_offset_value = irb_.getPtrEquivInt(field_offset); 15035e869b6560f918837cc6be3a50234deb2be46385TDYa 15045e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* field_addr = 15055e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreatePtrDisp(object_addr, field_offset_value, field_type); 15065e869b6560f918837cc6be3a50234deb2be46385TDYa 15075e869b6560f918837cc6be3a50234deb2be46385TDYa // TODO: Check is_volatile. We need to generate atomic store instruction 15085e869b6560f918837cc6be3a50234deb2be46385TDYa // when is_volatile is true. 15095e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateStore(new_value, field_addr, kTBAAHeapInstance, field_jty); 15105e869b6560f918837cc6be3a50234deb2be46385TDYa 15115e869b6560f918837cc6be3a50234deb2be46385TDYa if (field_jty == kObject) { // If put an object, mark the GC card table. 15125e869b6560f918837cc6be3a50234deb2be46385TDYa EmitMarkGCCard(new_value, object_addr); 15135e869b6560f918837cc6be3a50234deb2be46385TDYa } 15145e869b6560f918837cc6be3a50234deb2be46385TDYa } 15155e869b6560f918837cc6be3a50234deb2be46385TDYa 15165e869b6560f918837cc6be3a50234deb2be46385TDYa return; 15175e869b6560f918837cc6be3a50234deb2be46385TDYa} 15185e869b6560f918837cc6be3a50234deb2be46385TDYa 1519f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::EmitLoadConstantClass(uint32_t dex_pc, 1520f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_idx) { 1521bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao if (!compiler_->CanAccessTypeWithoutChecks(method_idx_, *dex_file_, type_idx)) { 1522f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* type_idx_value = irb_.getInt32(type_idx); 1523f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1524f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 1525f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1526f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread(); 1527f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1528f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Function* runtime_func = 1529f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.GetRuntime(runtime_support::InitializeTypeAndVerifyAccess); 1530f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1531f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 1532f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1533f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* type_object_addr = 1534f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCall3(runtime_func, type_idx_value, method_object_addr, thread_object_addr); 1535f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1536f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 1537f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1538f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return type_object_addr; 1539f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1540f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } else { 1541f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Try to load the class (type) object from the test cache. 1542f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* type_field_addr = 1543f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitLoadDexCacheResolvedTypeFieldAddr(type_idx); 1544f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1545ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa llvm::Value* type_object_addr = irb_.CreateLoad(type_field_addr, kTBAARuntimeInfo); 1546f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1547bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao if (compiler_->CanAssumeTypeIsPresentInDexCache(*dex_file_, type_idx)) { 1548f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return type_object_addr; 1549f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 1550f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1551f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_original = irb_.GetInsertBlock(); 1552f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1553f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Test whether class (type) object is in the dex cache or not 1554f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* equal_null = 1555f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateICmpEQ(type_object_addr, irb_.getJNull()); 1556f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1557f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_cont = 1558f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "cont"); 1559f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1560f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_load_class = 1561f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "load_class"); 1562f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1563f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCondBr(equal_null, block_load_class, block_cont, kUnlikely); 1564f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1565f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Failback routine to load the class object 1566f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_load_class); 1567f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1568f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Function* runtime_func = irb_.GetRuntime(runtime_support::InitializeType); 1569f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1570f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Constant* type_idx_value = irb_.getInt32(type_idx); 1571f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1572f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 1573f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1574f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread(); 1575f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1576f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 1577f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1578f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* loaded_type_object_addr = 1579f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCall3(runtime_func, type_idx_value, method_object_addr, thread_object_addr); 1580f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1581f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 1582f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1583f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_after_load_class = irb_.GetInsertBlock(); 1584f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1585f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateBr(block_cont); 1586f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1587f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Now the class object must be loaded 1588f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_cont); 1589f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1590f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::PHINode* phi = irb_.CreatePHI(irb_.getJObjectTy(), 2); 1591f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1592f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa phi->addIncoming(type_object_addr, block_original); 1593f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa phi->addIncoming(loaded_type_object_addr, block_after_load_class); 1594f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1595f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return phi; 1596f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 1597f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 1598f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 15995a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYallvm::Value* GBCExpanderPass::EmitLoadStaticStorage(uint32_t dex_pc, 16005a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa uint32_t type_idx) { 16015a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::BasicBlock* block_load_static = 16025a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa CreateBasicBlockWithDexPC(dex_pc, "load_static"); 16035a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16045a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::BasicBlock* block_cont = CreateBasicBlockWithDexPC(dex_pc, "cont"); 16055a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16065a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // Load static storage from dex cache 16075a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* storage_field_addr = 16085a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitLoadDexCacheStaticStorageFieldAddr(type_idx); 16095a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 1610ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa llvm::Value* storage_object_addr = irb_.CreateLoad(storage_field_addr, kTBAARuntimeInfo); 16115a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16125a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::BasicBlock* block_original = irb_.GetInsertBlock(); 16135a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16145a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // Test: Is the static storage of this class initialized? 16155a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* equal_null = 16165a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreateICmpEQ(storage_object_addr, irb_.getJNull()); 16175a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16185a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreateCondBr(equal_null, block_load_static, block_cont, kUnlikely); 16195a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16205a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // Failback routine to load the class object 16215a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.SetInsertPoint(block_load_static); 16225a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16235a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Function* runtime_func = irb_.GetRuntime(runtime_support::InitializeStaticStorage); 16245a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16255a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Constant* type_idx_value = irb_.getInt32(type_idx); 16265a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16275a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 16285a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16295a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread(); 16305a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16315a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitUpdateDexPC(dex_pc); 16325a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16335a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* loaded_storage_object_addr = 16345a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreateCall3(runtime_func, type_idx_value, method_object_addr, thread_object_addr); 16355a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16365a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitGuard_ExceptionLandingPad(dex_pc); 16375a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16385a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::BasicBlock* block_after_load_static = irb_.GetInsertBlock(); 16395a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16405a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreateBr(block_cont); 16415a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16425a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // Now the class object must be loaded 16435a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.SetInsertPoint(block_cont); 16445a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16455a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::PHINode* phi = irb_.CreatePHI(irb_.getJObjectTy(), 2); 16465a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16475a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa phi->addIncoming(storage_object_addr, block_original); 16485a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa phi->addIncoming(loaded_storage_object_addr, block_after_load_static); 16495a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16505a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return phi; 16515a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa} 16525a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16535a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYallvm::Value* GBCExpanderPass::Expand_HLSget(llvm::CallInst& call_inst, 16545a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa JType field_jty) { 16555a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 16565a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa uint32_t field_idx = LV2UInt(call_inst.getArgOperand(0)); 16575a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16585a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa int field_offset; 16595a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa int ssb_index; 16605a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa bool is_referrers_class; 16615a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa bool is_volatile; 16625a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16635a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa bool is_fast_path = compiler_->ComputeStaticFieldInfo( 16645a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa field_idx, oat_compilation_unit_, field_offset, ssb_index, 16655a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa is_referrers_class, is_volatile, false); 16665a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16675a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* static_field_value; 16685a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16695a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa if (!is_fast_path) { 16705a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Function* runtime_func; 16715a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16725a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa if (field_jty == kObject) { 16735a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa runtime_func = irb_.GetRuntime(runtime_support::GetObjectStatic); 16745a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } else if (field_jty == kLong || field_jty == kDouble) { 16755a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa runtime_func = irb_.GetRuntime(runtime_support::Get64Static); 16765a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } else { 16775a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa runtime_func = irb_.GetRuntime(runtime_support::Get32Static); 16785a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 16795a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16805a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Constant* field_idx_value = irb_.getInt32(field_idx); 16815a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16825a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 16835a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16845a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitUpdateDexPC(dex_pc); 16855a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16865a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa static_field_value = 16875a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreateCall2(runtime_func, field_idx_value, method_object_addr); 16885a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16895a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitGuard_ExceptionLandingPad(dex_pc); 16905a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16915a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } else { 16925a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa DCHECK_GE(field_offset, 0); 16935a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16945a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* static_storage_addr = NULL; 16955a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16965a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa if (is_referrers_class) { 16975a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // Fast path, static storage base is this method's class 16985a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 16995a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17005a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa static_storage_addr = 17015a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.LoadFromObjectOffset(method_object_addr, 170266f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier art::AbstractMethod::DeclaringClassOffset().Int32Value(), 17035a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.getJObjectTy(), 17045a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa kTBAAConstJObject); 17055a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } else { 17065a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // Medium path, static storage base in a different class which 17075a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // requires checks that the other class is initialized 17085a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa DCHECK_GE(ssb_index, 0); 17095a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa static_storage_addr = EmitLoadStaticStorage(dex_pc, ssb_index); 17105a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 17115a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17125a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset); 17135a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17145a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* static_field_addr = 17155a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value, 17165a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.getJType(field_jty, kField)->getPointerTo()); 17175a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17185a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // TODO: Check is_volatile. We need to generate atomic load instruction 17195a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // when is_volatile is true. 17205a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa static_field_value = irb_.CreateLoad(static_field_addr, kTBAAHeapStatic, field_jty); 17215a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 17225a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17235a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa if (field_jty == kFloat || field_jty == kDouble) { 17245a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa static_field_value = 17255a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreateBitCast(static_field_value, irb_.getJType(field_jty, kAccurate)); 17265a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 17275a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17285a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return static_field_value; 17295a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa} 17305a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17315a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYavoid GBCExpanderPass::Expand_HLSput(llvm::CallInst& call_inst, 17325a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa JType field_jty) { 17335a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 17345a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa uint32_t field_idx = LV2UInt(call_inst.getArgOperand(0)); 17355a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* new_value = call_inst.getArgOperand(1); 17365a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17375a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa if (field_jty == kFloat || field_jty == kDouble) { 17385a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa new_value = irb_.CreateBitCast(new_value, irb_.getJType(field_jty, kField)); 17395a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 17405a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17415a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa int field_offset; 17425a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa int ssb_index; 17435a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa bool is_referrers_class; 17445a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa bool is_volatile; 17455a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17465a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa bool is_fast_path = compiler_->ComputeStaticFieldInfo( 17475a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa field_idx, oat_compilation_unit_, field_offset, ssb_index, 17485a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa is_referrers_class, is_volatile, true); 17495a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17505a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa if (!is_fast_path) { 17515a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Function* runtime_func; 17525a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17535a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa if (field_jty == kObject) { 17545a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa runtime_func = irb_.GetRuntime(runtime_support::SetObjectStatic); 17555a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } else if (field_jty == kLong || field_jty == kDouble) { 17565a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa runtime_func = irb_.GetRuntime(runtime_support::Set64Static); 17575a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } else { 17585a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa runtime_func = irb_.GetRuntime(runtime_support::Set32Static); 17595a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 17605a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17615a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Constant* field_idx_value = irb_.getInt32(field_idx); 17625a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17635a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 17645a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17655a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitUpdateDexPC(dex_pc); 17665a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17675a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreateCall3(runtime_func, field_idx_value, 17685a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa method_object_addr, new_value); 17695a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17705a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitGuard_ExceptionLandingPad(dex_pc); 17715a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17725a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } else { 17735a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa DCHECK_GE(field_offset, 0); 17745a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17755a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* static_storage_addr = NULL; 17765a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17775a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa if (is_referrers_class) { 17785a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // Fast path, static storage base is this method's class 17795a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 17805a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17815a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa static_storage_addr = 17825a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.LoadFromObjectOffset(method_object_addr, 178366f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier art::AbstractMethod::DeclaringClassOffset().Int32Value(), 17845a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.getJObjectTy(), 17855a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa kTBAAConstJObject); 17865a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } else { 17875a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // Medium path, static storage base in a different class which 17885a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // requires checks that the other class is initialized 17895a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa DCHECK_GE(ssb_index, 0); 17905a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa static_storage_addr = EmitLoadStaticStorage(dex_pc, ssb_index); 17915a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 17925a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17935a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset); 17945a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17955a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* static_field_addr = 17965a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value, 17975a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.getJType(field_jty, kField)->getPointerTo()); 17985a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 17995a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // TODO: Check is_volatile. We need to generate atomic store instruction 18005a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // when is_volatile is true. 18015a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreateStore(new_value, static_field_addr, kTBAAHeapStatic, field_jty); 18025a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18035a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa if (field_jty == kObject) { // If put an object, mark the GC card table. 18045a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitMarkGCCard(new_value, static_storage_addr); 18055a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 18065a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 18075a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18085a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return; 18095a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa} 18105a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 1811f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_ConstString(llvm::CallInst& call_inst) { 1812f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 1813f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t string_idx = LV2UInt(call_inst.getArgOperand(0)); 1814f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1815f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* string_field_addr = EmitLoadDexCacheStringFieldAddr(string_idx); 1816f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1817ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa llvm::Value* string_addr = irb_.CreateLoad(string_field_addr, kTBAARuntimeInfo); 1818f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1819bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao if (!compiler_->CanAssumeStringIsPresentInDexCache(*dex_file_, string_idx)) { 1820f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_str_exist = 1821f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "str_exist"); 1822f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1823f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_str_resolve = 1824f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "str_resolve"); 1825f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1826f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_cont = 1827f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "str_cont"); 1828f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1829f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Test: Is the string resolved and in the dex cache? 1830f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* equal_null = irb_.CreateICmpEQ(string_addr, irb_.getJNull()); 1831f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1832f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCondBr(equal_null, block_str_resolve, block_str_exist, kUnlikely); 1833f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1834f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // String is resolved, go to next basic block. 1835f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_str_exist); 1836f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateBr(block_cont); 1837f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1838f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // String is not resolved yet, resolve it now. 1839f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_str_resolve); 1840f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1841f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Function* runtime_func = irb_.GetRuntime(runtime_support::ResolveString); 1842f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1843f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 1844f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1845f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* string_idx_value = irb_.getInt32(string_idx); 1846f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1847f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 1848f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1849f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* result = irb_.CreateCall2(runtime_func, method_object_addr, 1850f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa string_idx_value); 1851f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1852f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 1853f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1854bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao irb_.CreateBr(block_cont); 1855bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao 1856bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao 1857f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_pre_cont = irb_.GetInsertBlock(); 1858f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1859f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_cont); 1860f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1861f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::PHINode* phi = irb_.CreatePHI(irb_.getJObjectTy(), 2); 1862f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1863f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa phi->addIncoming(string_addr, block_str_exist); 1864f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa phi->addIncoming(result, block_pre_cont); 1865f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1866f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa string_addr = phi; 1867f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 1868f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1869f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return string_addr; 1870f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 1871f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1872f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_ConstClass(llvm::CallInst& call_inst) { 1873f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 1874f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0)); 1875f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1876f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, type_idx); 1877f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1878f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return type_object_addr; 1879f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 1880f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1881f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYavoid GBCExpanderPass::Expand_MonitorEnter(llvm::CallInst& call_inst) { 1882f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 1883f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_addr = call_inst.getArgOperand(1); 1884920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 1885f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1886920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa if (!(opt_flags & MIR_IGNORE_NULL_CHECK)) { 1887920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa EmitGuard_NullPointerException(dex_pc, object_addr); 1888920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa } 1889f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1890ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa EmitUpdateDexPC(dex_pc); 1891ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa 1892f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.Runtime().EmitLockObject(object_addr); 1893f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1894f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return; 1895f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 1896f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1897f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYavoid GBCExpanderPass::Expand_MonitorExit(llvm::CallInst& call_inst) { 1898f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 1899f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_addr = call_inst.getArgOperand(1); 1900920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 1901f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1902920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa if (!(opt_flags & MIR_IGNORE_NULL_CHECK)) { 1903920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa EmitGuard_NullPointerException(dex_pc, object_addr); 1904920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa } 1905f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1906f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 1907f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1908f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.Runtime().EmitUnlockObject(object_addr); 1909f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1910f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 1911f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1912f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return; 1913f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 1914f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1915f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYavoid GBCExpanderPass::Expand_HLCheckCast(llvm::CallInst& call_inst) { 1916f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 1917f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0)); 1918f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_addr = call_inst.getArgOperand(1); 1919f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1920f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_test_class = 1921f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "test_class"); 1922f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1923f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_test_sub_class = 1924f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "test_sub_class"); 1925f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1926f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_cont = 1927f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "checkcast_cont"); 1928f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1929f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Test: Is the reference equal to null? Act as no-op when it is null. 1930f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* equal_null = irb_.CreateICmpEQ(object_addr, irb_.getJNull()); 1931f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1932f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCondBr(equal_null, 1933f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa block_cont, 1934f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa block_test_class); 1935f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1936f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Test: Is the object instantiated from the given class? 1937f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_test_class); 1938f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, type_idx); 1939920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa DCHECK_EQ(art::Object::ClassOffset().Int32Value(), 0); 1940f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1941f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::PointerType* jobject_ptr_ty = irb_.getJObjectTy(); 1942f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1943f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_type_field_addr = 1944f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateBitCast(object_addr, jobject_ptr_ty->getPointerTo()); 1945f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1946f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_type_object_addr = 1947f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateLoad(object_type_field_addr, kTBAAConstJObject); 1948f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1949f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* equal_class = 1950f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateICmpEQ(type_object_addr, object_type_object_addr); 1951f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1952f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCondBr(equal_class, 1953f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa block_cont, 1954f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa block_test_sub_class); 1955f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1956f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Test: Is the object instantiated from the subclass of the given class? 1957f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_test_sub_class); 1958f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1959f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 1960f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1961f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCall2(irb_.GetRuntime(runtime_support::CheckCast), 1962f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa type_object_addr, object_type_object_addr); 1963f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1964f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 1965f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1966f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateBr(block_cont); 1967f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1968f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_cont); 1969f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1970f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return; 1971f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 1972f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1973f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_InstanceOf(llvm::CallInst& call_inst) { 1974f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 1975f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0)); 1976f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_addr = call_inst.getArgOperand(1); 1977f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1978f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_nullp = 1979f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "nullp"); 1980f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1981f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_test_class = 1982f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "test_class"); 1983f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1984f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_class_equals = 1985f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "class_eq"); 1986f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1987f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_test_sub_class = 1988f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "test_sub_class"); 1989f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1990f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_cont = 1991f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "instance_of_cont"); 1992f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1993f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Overview of the following code : 1994f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // We check for null, if so, then false, otherwise check for class == . If so 1995f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // then true, otherwise do callout slowpath. 1996f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // 1997f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Test: Is the reference equal to null? Set 0 when it is null. 1998f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* equal_null = irb_.CreateICmpEQ(object_addr, irb_.getJNull()); 1999f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2000f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCondBr(equal_null, block_nullp, block_test_class); 2001f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2002f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_nullp); 2003f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateBr(block_cont); 2004f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2005f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Test: Is the object instantiated from the given class? 2006f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_test_class); 2007f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, type_idx); 2008920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa DCHECK_EQ(art::Object::ClassOffset().Int32Value(), 0); 2009f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2010f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::PointerType* jobject_ptr_ty = irb_.getJObjectTy(); 2011f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2012f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_type_field_addr = 2013f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateBitCast(object_addr, jobject_ptr_ty->getPointerTo()); 2014f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2015f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_type_object_addr = 2016f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateLoad(object_type_field_addr, kTBAAConstJObject); 2017f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2018f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* equal_class = 2019f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateICmpEQ(type_object_addr, object_type_object_addr); 2020f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2021f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCondBr(equal_class, block_class_equals, block_test_sub_class); 2022f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2023f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_class_equals); 2024f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateBr(block_cont); 2025f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2026f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Test: Is the object instantiated from the subclass of the given class? 2027f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_test_sub_class); 2028f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* result = 2029f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCall2(irb_.GetRuntime(runtime_support::IsAssignable), 2030f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa type_object_addr, object_type_object_addr); 2031f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateBr(block_cont); 2032f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2033f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_cont); 2034f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2035f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::PHINode* phi = irb_.CreatePHI(irb_.getJIntTy(), 3); 2036f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2037f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa phi->addIncoming(irb_.getJInt(0), block_nullp); 2038f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa phi->addIncoming(irb_.getJInt(1), block_class_equals); 2039f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa phi->addIncoming(result, block_test_sub_class); 2040f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2041f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return phi; 2042f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2043f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2044f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_NewInstance(llvm::CallInst& call_inst) { 2045f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2046f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0)); 2047f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2048f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Function* runtime_func; 2049bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao if (compiler_->CanAccessInstantiableTypeWithoutChecks(method_idx_, *dex_file_, type_idx)) { 2050f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa runtime_func = irb_.GetRuntime(runtime_support::AllocObject); 2051f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } else { 2052f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa runtime_func = irb_.GetRuntime(runtime_support::AllocObjectWithAccessCheck); 2053f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2054f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2055f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Constant* type_index_value = irb_.getInt32(type_idx); 2056f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2057f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 2058f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2059f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread(); 2060f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2061f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 2062f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2063f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_addr = 2064f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCall3(runtime_func, type_index_value, method_object_addr, thread_object_addr); 2065f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2066f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 2067f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2068f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return object_addr; 2069f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2070f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2071f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_HLInvoke(llvm::CallInst& call_inst) { 2072f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2073920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::InvokeType invoke_type = static_cast<art::InvokeType>(LV2UInt(call_inst.getArgOperand(0))); 2074920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa bool is_static = (invoke_type == art::kStatic); 2075f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t callee_method_idx = LV2UInt(call_inst.getArgOperand(1)); 2076920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa int opt_flags = LV2UInt(call_inst.getArgOperand(2)); 2077f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2078f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Compute invoke related information for compiler decision 2079f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa int vtable_idx = -1; 2080f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uintptr_t direct_code = 0; 2081f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uintptr_t direct_method = 0; 2082f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa bool is_fast_path = compiler_-> 2083f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa ComputeInvokeInfo(callee_method_idx, oat_compilation_unit_, 2084f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa invoke_type, vtable_idx, direct_code, direct_method); 2085f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2086f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Load *this* actual parameter 2087f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* this_addr = NULL; 2088f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2089f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa if (!is_static) { 2090f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Test: Is *this* parameter equal to null? 2091f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa this_addr = call_inst.getArgOperand(3); 2092f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2093f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2094f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Load the method object 2095f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* callee_method_object_addr = NULL; 2096f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2097f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa if (!is_fast_path) { 2098f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa callee_method_object_addr = 2099f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitCallRuntimeForCalleeMethodObjectAddr(callee_method_idx, invoke_type, 2100f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa this_addr, dex_pc, is_fast_path); 2101f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2102920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa if (!is_static && !(opt_flags & MIR_IGNORE_NULL_CHECK)) { 2103f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_NullPointerException(dex_pc, this_addr); 2104f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2105f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } else { 2106920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa if (!is_static && !(opt_flags & MIR_IGNORE_NULL_CHECK)) { 2107f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_NullPointerException(dex_pc, this_addr); 2108f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2109f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2110f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa switch (invoke_type) { 2111920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case art::kStatic: 2112920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case art::kDirect: 2113f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa if (direct_method != 0u && 2114f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa direct_method != static_cast<uintptr_t>(-1)) { 2115f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa callee_method_object_addr = 2116f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateIntToPtr(irb_.getPtrEquivInt(direct_method), 2117f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.getJObjectTy()); 2118f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } else { 2119f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa callee_method_object_addr = 2120f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitLoadSDCalleeMethodObjectAddr(callee_method_idx); 2121f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2122f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa break; 2123f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2124920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case art::kVirtual: 2125f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa DCHECK(vtable_idx != -1); 2126f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa callee_method_object_addr = 2127f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitLoadVirtualCalleeMethodObjectAddr(vtable_idx, this_addr); 2128f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa break; 2129f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2130920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case art::kSuper: 2131f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa LOG(FATAL) << "invoke-super should be promoted to invoke-direct in " 2132f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa "the fast path."; 2133f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa break; 2134f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2135920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case art::kInterface: 2136f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa callee_method_object_addr = 2137f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitCallRuntimeForCalleeMethodObjectAddr(callee_method_idx, 2138f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa invoke_type, this_addr, 2139f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa dex_pc, is_fast_path); 2140f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa break; 2141f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2142f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2143f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2144f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Load the actual parameter 2145f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa std::vector<llvm::Value*> args; 2146f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2147f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa args.push_back(callee_method_object_addr); // method object for callee 2148f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2149f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa for (uint32_t i = 3; i < call_inst.getNumArgOperands(); ++i) { 2150f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa args.push_back(call_inst.getArgOperand(i)); 2151f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2152f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2153f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* code_addr; 2154f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa if (direct_code != 0u && 2155f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa direct_code != static_cast<uintptr_t>(-1)) { 2156f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa code_addr = 2157f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateIntToPtr(irb_.getPtrEquivInt(direct_code), 2158f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa GetFunctionType(callee_method_idx, is_static)->getPointerTo()); 2159f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } else { 2160f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa code_addr = 2161f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.LoadFromObjectOffset(callee_method_object_addr, 216266f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier art::AbstractMethod::GetCodeOffset().Int32Value(), 2163f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa GetFunctionType(callee_method_idx, is_static)->getPointerTo(), 2164ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa kTBAARuntimeInfo); 2165f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2166f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2167f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Invoke callee 2168f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 2169f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* retval = irb_.CreateCall(code_addr, args); 2170f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 2171f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2172f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return retval; 2173f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2174f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2175f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_OptArrayLength(llvm::CallInst& call_inst) { 2176f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2177f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Get the array object address 2178f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* array_addr = call_inst.getArgOperand(1); 2179920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 2180f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2181920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa if (!(opt_flags & MIR_IGNORE_NULL_CHECK)) { 2182920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa EmitGuard_NullPointerException(dex_pc, array_addr); 2183920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa } 2184f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2185f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Get the array length and store it to the register 2186f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return EmitLoadArrayLength(array_addr); 2187f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2188f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2189f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_NewArray(llvm::CallInst& call_inst) { 2190f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2191f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0)); 2192f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* length = call_inst.getArgOperand(1); 2193f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2194f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return EmitAllocNewArray(dex_pc, length, type_idx, false); 2195f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2196f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2197f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_HLFilledNewArray(llvm::CallInst& call_inst) { 2198f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2199f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_idx = LV2UInt(call_inst.getArgOperand(1)); 2200f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t length = call_inst.getNumArgOperands() - 3; 2201f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2202f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_addr = 2203f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitAllocNewArray(dex_pc, irb_.getInt32(length), type_idx, true); 2204f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2205f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa if (length > 0) { 2206f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Check for the element type 2207f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_desc_len = 0; 2208f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa const char* type_desc = 2209f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa dex_file_->StringByTypeIdx(type_idx, &type_desc_len); 2210f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2211f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa DCHECK_GE(type_desc_len, 2u); // should be guaranteed by verifier 2212f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa DCHECK_EQ(type_desc[0], '['); // should be guaranteed by verifier 2213f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa bool is_elem_int_ty = (type_desc[1] == 'I'); 2214f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2215f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t alignment; 2216f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Constant* elem_size; 2217f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::PointerType* field_type; 2218f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2219f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // NOTE: Currently filled-new-array only supports 'L', '[', and 'I' 2220f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // as the element, thus we are only checking 2 cases: primitive int and 2221f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // non-primitive type. 2222f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa if (is_elem_int_ty) { 2223f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa alignment = sizeof(int32_t); 2224f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa elem_size = irb_.getPtrEquivInt(sizeof(int32_t)); 2225f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa field_type = irb_.getJIntTy()->getPointerTo(); 2226f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } else { 2227f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa alignment = irb_.getSizeOfPtrEquivInt(); 2228f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa elem_size = irb_.getSizeOfPtrEquivIntValue(); 2229f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa field_type = irb_.getJObjectTy()->getPointerTo(); 2230f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2231f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2232f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* data_field_offset = 2233920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa irb_.getPtrEquivInt(art::Array::DataOffset(alignment).Int32Value()); 2234f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2235f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* data_field_addr = 2236f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreatePtrDisp(object_addr, data_field_offset, field_type); 2237f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2238f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // TODO: Tune this code. Currently we are generating one instruction for 2239f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // one element which may be very space consuming. Maybe changing to use 2240f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // memcpy may help; however, since we can't guarantee that the alloca of 2241f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // dalvik register are continuous, we can't perform such optimization yet. 2242f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa for (uint32_t i = 0; i < length; ++i) { 2243f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* reg_value = call_inst.getArgOperand(i+3); 2244f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2245f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateStore(reg_value, data_field_addr, kTBAAHeapArray); 2246f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2247f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa data_field_addr = 2248f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreatePtrDisp(data_field_addr, elem_size, field_type); 2249f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2250f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2251f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2252f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return object_addr; 2253f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2254f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2255f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYavoid GBCExpanderPass::Expand_HLFillArrayData(llvm::CallInst& call_inst) { 2256f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2257f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa int32_t payload_offset = static_cast<int32_t>(dex_pc) + 2258f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa LV2SInt(call_inst.getArgOperand(0)); 2259f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* array_addr = call_inst.getArgOperand(1); 2260f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2261920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa const art::Instruction::ArrayDataPayload* payload = 2262920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa reinterpret_cast<const art::Instruction::ArrayDataPayload*>( 2263f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa code_item_->insns_ + payload_offset); 2264f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2265f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa if (payload->element_count == 0) { 2266f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // When the number of the elements in the payload is zero, we don't have 2267f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // to copy any numbers. However, we should check whether the array object 2268f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // address is equal to null or not. 2269f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_NullPointerException(dex_pc, array_addr); 2270f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } else { 2271f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // To save the code size, we are going to call the runtime function to 2272f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // copy the content from DexFile. 2273f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2274f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // NOTE: We will check for the NullPointerException in the runtime. 2275f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2276f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Function* runtime_func = irb_.GetRuntime(runtime_support::FillArrayData); 2277f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2278f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 2279f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2280f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 2281f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2282f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCall4(runtime_func, 2283f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa method_object_addr, irb_.getInt32(dex_pc), 2284f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa array_addr, irb_.getInt32(payload_offset)); 2285f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2286f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 2287f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2288f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2289f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return; 2290f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2291f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2292f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::EmitAllocNewArray(uint32_t dex_pc, 2293f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* array_length_value, 2294f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_idx, 2295f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa bool is_filled_new_array) { 2296f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Function* runtime_func; 2297f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2298f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa bool skip_access_check = 2299bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao compiler_->CanAccessTypeWithoutChecks(method_idx_, *dex_file_, type_idx); 2300f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2301f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2302f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa if (is_filled_new_array) { 2303f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa runtime_func = skip_access_check ? 2304f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.GetRuntime(runtime_support::CheckAndAllocArray) : 2305f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.GetRuntime(runtime_support::CheckAndAllocArrayWithAccessCheck); 2306f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } else { 2307f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa runtime_func = skip_access_check ? 2308f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.GetRuntime(runtime_support::AllocArray) : 2309f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.GetRuntime(runtime_support::AllocArrayWithAccessCheck); 2310f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2311f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2312f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Constant* type_index_value = irb_.getInt32(type_idx); 2313f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2314f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 2315f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2316f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread(); 2317f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2318f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 2319f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2320f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_addr = 2321f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCall4(runtime_func, type_index_value, method_object_addr, 2322f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa array_length_value, thread_object_addr); 2323f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2324f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 2325f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2326f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return object_addr; 2327f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2328f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2329f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass:: 2330f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYaEmitCallRuntimeForCalleeMethodObjectAddr(uint32_t callee_method_idx, 2331920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::InvokeType invoke_type, 2332f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* this_addr, 2333f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc, 2334f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa bool is_fast_path) { 2335f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2336f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Function* runtime_func = NULL; 2337f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2338f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa switch (invoke_type) { 2339920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case art::kStatic: 2340f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa runtime_func = irb_.GetRuntime(runtime_support::FindStaticMethodWithAccessCheck); 2341f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa break; 2342f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2343920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case art::kDirect: 2344f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa runtime_func = irb_.GetRuntime(runtime_support::FindDirectMethodWithAccessCheck); 2345f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa break; 2346f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2347920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case art::kVirtual: 2348f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa runtime_func = irb_.GetRuntime(runtime_support::FindVirtualMethodWithAccessCheck); 2349f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa break; 2350f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2351920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case art::kSuper: 2352f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa runtime_func = irb_.GetRuntime(runtime_support::FindSuperMethodWithAccessCheck); 2353f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa break; 2354f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2355920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case art::kInterface: 2356f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa if (is_fast_path) { 2357f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa runtime_func = irb_.GetRuntime(runtime_support::FindInterfaceMethod); 2358f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } else { 2359f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa runtime_func = irb_.GetRuntime(runtime_support::FindInterfaceMethodWithAccessCheck); 2360f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2361f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa break; 2362f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2363f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2364f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* callee_method_idx_value = irb_.getInt32(callee_method_idx); 2365f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2366f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa if (this_addr == NULL) { 2367920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa DCHECK_EQ(invoke_type, art::kStatic); 2368f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa this_addr = irb_.getJNull(); 2369f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2370f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2371f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* caller_method_object_addr = EmitLoadMethodObjectAddr(); 2372f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2373f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread(); 2374f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2375f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 2376f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2377f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* callee_method_object_addr = 2378f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCall4(runtime_func, 2379f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa callee_method_idx_value, 2380f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa this_addr, 2381f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa caller_method_object_addr, 2382f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa thread_object_addr); 2383f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2384f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 2385f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2386f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return callee_method_object_addr; 2387f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2388f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 23895e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::EmitMarkGCCard(llvm::Value* value, llvm::Value* target_addr) { 23905e869b6560f918837cc6be3a50234deb2be46385TDYa // Using runtime support, let the target can override by InlineAssembly. 23915e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.Runtime().EmitMarkGCCard(value, target_addr); 23925e869b6560f918837cc6be3a50234deb2be46385TDYa} 23935e869b6560f918837cc6be3a50234deb2be46385TDYa 23945e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::EmitUpdateDexPC(uint32_t dex_pc) { 2395c531cefbfb5394413122e9f57d211ba436cff012buzbee#if defined(ART_USE_PORTABLE_COMPILER) 2396bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao if (shadow_frame_ == NULL) { 2397bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao return; 2398bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao } 2399bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao#endif 24005e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.StoreToObjectOffset(shadow_frame_, 2401920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::ShadowFrame::DexPCOffset(), 24025e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.getInt32(dex_pc), 24035e869b6560f918837cc6be3a50234deb2be46385TDYa kTBAAShadowFrame); 24045e869b6560f918837cc6be3a50234deb2be46385TDYa} 24055e869b6560f918837cc6be3a50234deb2be46385TDYa 24065e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::EmitGuard_DivZeroException(uint32_t dex_pc, 24075e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* denominator, 24085e869b6560f918837cc6be3a50234deb2be46385TDYa JType op_jty) { 24095e869b6560f918837cc6be3a50234deb2be46385TDYa DCHECK(op_jty == kInt || op_jty == kLong) << op_jty; 24105e869b6560f918837cc6be3a50234deb2be46385TDYa 24115e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Constant* zero = irb_.getJZero(op_jty); 24125e869b6560f918837cc6be3a50234deb2be46385TDYa 24135e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* equal_zero = irb_.CreateICmpEQ(denominator, zero); 24145e869b6560f918837cc6be3a50234deb2be46385TDYa 24155e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* block_exception = CreateBasicBlockWithDexPC(dex_pc, "div0"); 24165e869b6560f918837cc6be3a50234deb2be46385TDYa 24175e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* block_continue = CreateBasicBlockWithDexPC(dex_pc, "cont"); 24185e869b6560f918837cc6be3a50234deb2be46385TDYa 24195e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateCondBr(equal_zero, block_exception, block_continue, kUnlikely); 24205e869b6560f918837cc6be3a50234deb2be46385TDYa 24215e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.SetInsertPoint(block_exception); 24225e869b6560f918837cc6be3a50234deb2be46385TDYa EmitUpdateDexPC(dex_pc); 24235e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateCall(irb_.GetRuntime(runtime_support::ThrowDivZeroException)); 24245e869b6560f918837cc6be3a50234deb2be46385TDYa EmitBranchExceptionLandingPad(dex_pc); 24255e869b6560f918837cc6be3a50234deb2be46385TDYa 24265e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.SetInsertPoint(block_continue); 24275e869b6560f918837cc6be3a50234deb2be46385TDYa} 24285e869b6560f918837cc6be3a50234deb2be46385TDYa 24295e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::EmitGuard_NullPointerException(uint32_t dex_pc, 24305e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* object) { 24315e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* equal_null = irb_.CreateICmpEQ(object, irb_.getJNull()); 24325e869b6560f918837cc6be3a50234deb2be46385TDYa 24335e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* block_exception = 24345e869b6560f918837cc6be3a50234deb2be46385TDYa CreateBasicBlockWithDexPC(dex_pc, "nullp"); 24355e869b6560f918837cc6be3a50234deb2be46385TDYa 24365e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* block_continue = 24375e869b6560f918837cc6be3a50234deb2be46385TDYa CreateBasicBlockWithDexPC(dex_pc, "cont"); 24385e869b6560f918837cc6be3a50234deb2be46385TDYa 24395e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateCondBr(equal_null, block_exception, block_continue, kUnlikely); 24405e869b6560f918837cc6be3a50234deb2be46385TDYa 24415e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.SetInsertPoint(block_exception); 24425e869b6560f918837cc6be3a50234deb2be46385TDYa EmitUpdateDexPC(dex_pc); 24435e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateCall(irb_.GetRuntime(runtime_support::ThrowNullPointerException), 24445e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.getInt32(dex_pc)); 24455e869b6560f918837cc6be3a50234deb2be46385TDYa EmitBranchExceptionLandingPad(dex_pc); 24465e869b6560f918837cc6be3a50234deb2be46385TDYa 24475e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.SetInsertPoint(block_continue); 24485e869b6560f918837cc6be3a50234deb2be46385TDYa} 24495e869b6560f918837cc6be3a50234deb2be46385TDYa 24505e869b6560f918837cc6be3a50234deb2be46385TDYavoid 24515e869b6560f918837cc6be3a50234deb2be46385TDYaGBCExpanderPass::EmitGuard_ArrayIndexOutOfBoundsException(uint32_t dex_pc, 24525e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* array, 24535e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* index) { 24545e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* array_len = EmitLoadArrayLength(array); 24555e869b6560f918837cc6be3a50234deb2be46385TDYa 24565e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* cmp = irb_.CreateICmpUGE(index, array_len); 24575e869b6560f918837cc6be3a50234deb2be46385TDYa 24585e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* block_exception = 24595e869b6560f918837cc6be3a50234deb2be46385TDYa CreateBasicBlockWithDexPC(dex_pc, "overflow"); 24605e869b6560f918837cc6be3a50234deb2be46385TDYa 24615e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* block_continue = 24625e869b6560f918837cc6be3a50234deb2be46385TDYa CreateBasicBlockWithDexPC(dex_pc, "cont"); 24635e869b6560f918837cc6be3a50234deb2be46385TDYa 24645e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateCondBr(cmp, block_exception, block_continue, kUnlikely); 24655e869b6560f918837cc6be3a50234deb2be46385TDYa 24665e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.SetInsertPoint(block_exception); 24675e869b6560f918837cc6be3a50234deb2be46385TDYa 24685e869b6560f918837cc6be3a50234deb2be46385TDYa EmitUpdateDexPC(dex_pc); 24695e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateCall2(irb_.GetRuntime(runtime_support::ThrowIndexOutOfBounds), index, array_len); 24705e869b6560f918837cc6be3a50234deb2be46385TDYa EmitBranchExceptionLandingPad(dex_pc); 24715e869b6560f918837cc6be3a50234deb2be46385TDYa 24725e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.SetInsertPoint(block_continue); 24735e869b6560f918837cc6be3a50234deb2be46385TDYa} 24745e869b6560f918837cc6be3a50234deb2be46385TDYa 24755e869b6560f918837cc6be3a50234deb2be46385TDYallvm::FunctionType* GBCExpanderPass::GetFunctionType(uint32_t method_idx, 24765e869b6560f918837cc6be3a50234deb2be46385TDYa bool is_static) { 24775e869b6560f918837cc6be3a50234deb2be46385TDYa // Get method signature 2478920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::DexFile::MethodId const& method_id = dex_file_->GetMethodId(method_idx); 24795e869b6560f918837cc6be3a50234deb2be46385TDYa 24805e869b6560f918837cc6be3a50234deb2be46385TDYa uint32_t shorty_size; 24815e869b6560f918837cc6be3a50234deb2be46385TDYa const char* shorty = dex_file_->GetMethodShorty(method_id, &shorty_size); 24825e869b6560f918837cc6be3a50234deb2be46385TDYa CHECK_GE(shorty_size, 1u); 24835e869b6560f918837cc6be3a50234deb2be46385TDYa 24845e869b6560f918837cc6be3a50234deb2be46385TDYa // Get return type 2485bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao 2486bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao char ret_shorty = shorty[0]; 2487c531cefbfb5394413122e9f57d211ba436cff012buzbee#if defined(ART_USE_PORTABLE_COMPILER) 248826f10eed520942d3db754c31941e457048475f61buzbee ret_shorty = art::RemapShorty(ret_shorty); 2489bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao#endif 2490bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao llvm::Type* ret_type = irb_.getJType(ret_shorty, kAccurate); 24915e869b6560f918837cc6be3a50234deb2be46385TDYa 24925e869b6560f918837cc6be3a50234deb2be46385TDYa // Get argument type 24935e869b6560f918837cc6be3a50234deb2be46385TDYa std::vector<llvm::Type*> args_type; 24945e869b6560f918837cc6be3a50234deb2be46385TDYa 24955e869b6560f918837cc6be3a50234deb2be46385TDYa args_type.push_back(irb_.getJObjectTy()); // method object pointer 24965e869b6560f918837cc6be3a50234deb2be46385TDYa 24975e869b6560f918837cc6be3a50234deb2be46385TDYa if (!is_static) { 24985e869b6560f918837cc6be3a50234deb2be46385TDYa args_type.push_back(irb_.getJType('L', kAccurate)); // "this" object pointer 24995e869b6560f918837cc6be3a50234deb2be46385TDYa } 25005e869b6560f918837cc6be3a50234deb2be46385TDYa 25015e869b6560f918837cc6be3a50234deb2be46385TDYa for (uint32_t i = 1; i < shorty_size; ++i) { 2502c531cefbfb5394413122e9f57d211ba436cff012buzbee#if defined(ART_USE_PORTABLE_COMPILER) 250326f10eed520942d3db754c31941e457048475f61buzbee char shorty_type = art::RemapShorty(shorty[i]); 2504f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa args_type.push_back(irb_.getJType(shorty_type, kAccurate)); 2505f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa#else 25065e869b6560f918837cc6be3a50234deb2be46385TDYa args_type.push_back(irb_.getJType(shorty[i], kAccurate)); 2507f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa#endif 25085e869b6560f918837cc6be3a50234deb2be46385TDYa } 25095e869b6560f918837cc6be3a50234deb2be46385TDYa 25105e869b6560f918837cc6be3a50234deb2be46385TDYa return llvm::FunctionType::get(ret_type, args_type, false); 25115e869b6560f918837cc6be3a50234deb2be46385TDYa} 25125e869b6560f918837cc6be3a50234deb2be46385TDYa 25135e869b6560f918837cc6be3a50234deb2be46385TDYa 25145e869b6560f918837cc6be3a50234deb2be46385TDYallvm::BasicBlock* GBCExpanderPass:: 25155e869b6560f918837cc6be3a50234deb2be46385TDYaCreateBasicBlockWithDexPC(uint32_t dex_pc, const char* postfix) { 25165e869b6560f918837cc6be3a50234deb2be46385TDYa std::string name; 25175e869b6560f918837cc6be3a50234deb2be46385TDYa 25185e869b6560f918837cc6be3a50234deb2be46385TDYa#if !defined(NDEBUG) 2519920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::StringAppendF(&name, "B%04x.%s", dex_pc, postfix); 25205e869b6560f918837cc6be3a50234deb2be46385TDYa#endif 25215e869b6560f918837cc6be3a50234deb2be46385TDYa 25225e869b6560f918837cc6be3a50234deb2be46385TDYa return llvm::BasicBlock::Create(context_, name, func_); 25235e869b6560f918837cc6be3a50234deb2be46385TDYa} 25245e869b6560f918837cc6be3a50234deb2be46385TDYa 25255e869b6560f918837cc6be3a50234deb2be46385TDYallvm::BasicBlock* GBCExpanderPass::GetBasicBlock(uint32_t dex_pc) { 25265e869b6560f918837cc6be3a50234deb2be46385TDYa DCHECK(dex_pc < code_item_->insns_size_in_code_units_); 2527bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao CHECK(basic_blocks_[dex_pc] != NULL); 25285e869b6560f918837cc6be3a50234deb2be46385TDYa return basic_blocks_[dex_pc]; 25295e869b6560f918837cc6be3a50234deb2be46385TDYa} 25305e869b6560f918837cc6be3a50234deb2be46385TDYa 25315e869b6560f918837cc6be3a50234deb2be46385TDYaint32_t GBCExpanderPass::GetTryItemOffset(uint32_t dex_pc) { 25325e869b6560f918837cc6be3a50234deb2be46385TDYa int32_t min = 0; 25335e869b6560f918837cc6be3a50234deb2be46385TDYa int32_t max = code_item_->tries_size_ - 1; 25345e869b6560f918837cc6be3a50234deb2be46385TDYa 25355e869b6560f918837cc6be3a50234deb2be46385TDYa while (min <= max) { 25365e869b6560f918837cc6be3a50234deb2be46385TDYa int32_t mid = min + (max - min) / 2; 25375e869b6560f918837cc6be3a50234deb2be46385TDYa 2538920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa const art::DexFile::TryItem* ti = art::DexFile::GetTryItems(*code_item_, mid); 25395e869b6560f918837cc6be3a50234deb2be46385TDYa uint32_t start = ti->start_addr_; 25405e869b6560f918837cc6be3a50234deb2be46385TDYa uint32_t end = start + ti->insn_count_; 25415e869b6560f918837cc6be3a50234deb2be46385TDYa 25425e869b6560f918837cc6be3a50234deb2be46385TDYa if (dex_pc < start) { 25435e869b6560f918837cc6be3a50234deb2be46385TDYa max = mid - 1; 25445e869b6560f918837cc6be3a50234deb2be46385TDYa } else if (dex_pc >= end) { 25455e869b6560f918837cc6be3a50234deb2be46385TDYa min = mid + 1; 25465e869b6560f918837cc6be3a50234deb2be46385TDYa } else { 25475e869b6560f918837cc6be3a50234deb2be46385TDYa return mid; // found 25485e869b6560f918837cc6be3a50234deb2be46385TDYa } 25495e869b6560f918837cc6be3a50234deb2be46385TDYa } 25505e869b6560f918837cc6be3a50234deb2be46385TDYa 25515e869b6560f918837cc6be3a50234deb2be46385TDYa return -1; // not found 25525e869b6560f918837cc6be3a50234deb2be46385TDYa} 25535e869b6560f918837cc6be3a50234deb2be46385TDYa 25545e869b6560f918837cc6be3a50234deb2be46385TDYallvm::BasicBlock* GBCExpanderPass::GetLandingPadBasicBlock(uint32_t dex_pc) { 25555e869b6560f918837cc6be3a50234deb2be46385TDYa // Find the try item for this address in this method 25565e869b6560f918837cc6be3a50234deb2be46385TDYa int32_t ti_offset = GetTryItemOffset(dex_pc); 25575e869b6560f918837cc6be3a50234deb2be46385TDYa 25585e869b6560f918837cc6be3a50234deb2be46385TDYa if (ti_offset == -1) { 25595e869b6560f918837cc6be3a50234deb2be46385TDYa return NULL; // No landing pad is available for this address. 25605e869b6560f918837cc6be3a50234deb2be46385TDYa } 25615e869b6560f918837cc6be3a50234deb2be46385TDYa 25625e869b6560f918837cc6be3a50234deb2be46385TDYa // Check for the existing landing pad basic block 25635e869b6560f918837cc6be3a50234deb2be46385TDYa DCHECK_GT(basic_block_landing_pads_.size(), static_cast<size_t>(ti_offset)); 25645e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* block_lpad = basic_block_landing_pads_[ti_offset]; 25655e869b6560f918837cc6be3a50234deb2be46385TDYa 25665e869b6560f918837cc6be3a50234deb2be46385TDYa if (block_lpad) { 25675e869b6560f918837cc6be3a50234deb2be46385TDYa // We have generated landing pad for this try item already. Return the 25685e869b6560f918837cc6be3a50234deb2be46385TDYa // same basic block. 25695e869b6560f918837cc6be3a50234deb2be46385TDYa return block_lpad; 25705e869b6560f918837cc6be3a50234deb2be46385TDYa } 25715e869b6560f918837cc6be3a50234deb2be46385TDYa 25725e869b6560f918837cc6be3a50234deb2be46385TDYa // Get try item from code item 2573920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa const art::DexFile::TryItem* ti = art::DexFile::GetTryItems(*code_item_, ti_offset); 25745e869b6560f918837cc6be3a50234deb2be46385TDYa 25755e869b6560f918837cc6be3a50234deb2be46385TDYa std::string lpadname; 25765e869b6560f918837cc6be3a50234deb2be46385TDYa 25775e869b6560f918837cc6be3a50234deb2be46385TDYa#if !defined(NDEBUG) 2578920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::StringAppendF(&lpadname, "lpad%d_%04x_to_%04x", ti_offset, ti->start_addr_, ti->handler_off_); 25795e869b6560f918837cc6be3a50234deb2be46385TDYa#endif 25805e869b6560f918837cc6be3a50234deb2be46385TDYa 25815e869b6560f918837cc6be3a50234deb2be46385TDYa // Create landing pad basic block 25825e869b6560f918837cc6be3a50234deb2be46385TDYa block_lpad = llvm::BasicBlock::Create(context_, lpadname, func_); 25835e869b6560f918837cc6be3a50234deb2be46385TDYa 25845e869b6560f918837cc6be3a50234deb2be46385TDYa // Change IRBuilder insert point 25855e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP(); 25865e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.SetInsertPoint(block_lpad); 25875e869b6560f918837cc6be3a50234deb2be46385TDYa 25885e869b6560f918837cc6be3a50234deb2be46385TDYa // Find catch block with matching type 25895e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 25905e869b6560f918837cc6be3a50234deb2be46385TDYa 25915e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* ti_offset_value = irb_.getInt32(ti_offset); 25925e869b6560f918837cc6be3a50234deb2be46385TDYa 25935e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* catch_handler_index_value = 25945e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateCall2(irb_.GetRuntime(runtime_support::FindCatchBlock), 25955e869b6560f918837cc6be3a50234deb2be46385TDYa method_object_addr, ti_offset_value); 25965e869b6560f918837cc6be3a50234deb2be46385TDYa 25975e869b6560f918837cc6be3a50234deb2be46385TDYa // Switch instruction (Go to unwind basic block by default) 25985e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::SwitchInst* sw = 25995e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateSwitch(catch_handler_index_value, GetUnwindBasicBlock()); 26005e869b6560f918837cc6be3a50234deb2be46385TDYa 26015e869b6560f918837cc6be3a50234deb2be46385TDYa // Cases with matched catch block 2602920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::CatchHandlerIterator iter(*code_item_, ti->start_addr_); 26035e869b6560f918837cc6be3a50234deb2be46385TDYa 26045e869b6560f918837cc6be3a50234deb2be46385TDYa for (uint32_t c = 0; iter.HasNext(); iter.Next(), ++c) { 26055e869b6560f918837cc6be3a50234deb2be46385TDYa sw->addCase(irb_.getInt32(c), GetBasicBlock(iter.GetHandlerAddress())); 26065e869b6560f918837cc6be3a50234deb2be46385TDYa } 26075e869b6560f918837cc6be3a50234deb2be46385TDYa 26085e869b6560f918837cc6be3a50234deb2be46385TDYa // Restore the orignal insert point for IRBuilder 26095e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.restoreIP(irb_ip_original); 26105e869b6560f918837cc6be3a50234deb2be46385TDYa 26115e869b6560f918837cc6be3a50234deb2be46385TDYa // Cache this landing pad 26125e869b6560f918837cc6be3a50234deb2be46385TDYa DCHECK_GT(basic_block_landing_pads_.size(), static_cast<size_t>(ti_offset)); 26135e869b6560f918837cc6be3a50234deb2be46385TDYa basic_block_landing_pads_[ti_offset] = block_lpad; 26145e869b6560f918837cc6be3a50234deb2be46385TDYa 26155e869b6560f918837cc6be3a50234deb2be46385TDYa return block_lpad; 26165e869b6560f918837cc6be3a50234deb2be46385TDYa} 26175e869b6560f918837cc6be3a50234deb2be46385TDYa 26185e869b6560f918837cc6be3a50234deb2be46385TDYallvm::BasicBlock* GBCExpanderPass::GetUnwindBasicBlock() { 26195e869b6560f918837cc6be3a50234deb2be46385TDYa // Check the existing unwinding baisc block block 26205e869b6560f918837cc6be3a50234deb2be46385TDYa if (basic_block_unwind_ != NULL) { 26215e869b6560f918837cc6be3a50234deb2be46385TDYa return basic_block_unwind_; 26225e869b6560f918837cc6be3a50234deb2be46385TDYa } 26235e869b6560f918837cc6be3a50234deb2be46385TDYa 26245e869b6560f918837cc6be3a50234deb2be46385TDYa // Create new basic block for unwinding 26255e869b6560f918837cc6be3a50234deb2be46385TDYa basic_block_unwind_ = 26265e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock::Create(context_, "exception_unwind", func_); 26275e869b6560f918837cc6be3a50234deb2be46385TDYa 26285e869b6560f918837cc6be3a50234deb2be46385TDYa // Change IRBuilder insert point 26295e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP(); 26305e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.SetInsertPoint(basic_block_unwind_); 26315e869b6560f918837cc6be3a50234deb2be46385TDYa 26325e869b6560f918837cc6be3a50234deb2be46385TDYa // Pop the shadow frame 26335e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_PopShadowFrame(); 26345e869b6560f918837cc6be3a50234deb2be46385TDYa 26355e869b6560f918837cc6be3a50234deb2be46385TDYa // Emit the code to return default value (zero) for the given return type. 26365e869b6560f918837cc6be3a50234deb2be46385TDYa char ret_shorty = oat_compilation_unit_->GetShorty()[0]; 2637c531cefbfb5394413122e9f57d211ba436cff012buzbee#if defined(ART_USE_PORTABLE_COMPILER) 263826f10eed520942d3db754c31941e457048475f61buzbee ret_shorty = art::RemapShorty(ret_shorty); 2639bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao#endif 26405e869b6560f918837cc6be3a50234deb2be46385TDYa if (ret_shorty == 'V') { 26415e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateRetVoid(); 26425e869b6560f918837cc6be3a50234deb2be46385TDYa } else { 26435e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateRet(irb_.getJZero(ret_shorty)); 26445e869b6560f918837cc6be3a50234deb2be46385TDYa } 26455e869b6560f918837cc6be3a50234deb2be46385TDYa 26465e869b6560f918837cc6be3a50234deb2be46385TDYa // Restore the orignal insert point for IRBuilder 26475e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.restoreIP(irb_ip_original); 26485e869b6560f918837cc6be3a50234deb2be46385TDYa 26495e869b6560f918837cc6be3a50234deb2be46385TDYa return basic_block_unwind_; 26505e869b6560f918837cc6be3a50234deb2be46385TDYa} 26515e869b6560f918837cc6be3a50234deb2be46385TDYa 26525e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::EmitBranchExceptionLandingPad(uint32_t dex_pc) { 26535e869b6560f918837cc6be3a50234deb2be46385TDYa if (llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc)) { 265455e5e6c5702e3f1f68bd83ae741af769740d9a74TDYa landing_pad_phi_mapping_[lpad].push_back(std::make_pair(current_bb_->getUniquePredecessor(), 2655aa55887fd30484a77e7775dfbcddbee883ce6380TDYa irb_.GetInsertBlock())); 26565e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateBr(lpad); 26575e869b6560f918837cc6be3a50234deb2be46385TDYa } else { 26585e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateBr(GetUnwindBasicBlock()); 26595e869b6560f918837cc6be3a50234deb2be46385TDYa } 26605e869b6560f918837cc6be3a50234deb2be46385TDYa} 26615e869b6560f918837cc6be3a50234deb2be46385TDYa 26625e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::EmitGuard_ExceptionLandingPad(uint32_t dex_pc) { 26639a14265c911b2e63bec51a814b8b6fd157745b57Jeff Hao llvm::Value* exception_pending = irb_.Runtime().EmitIsExceptionPending(); 2664a1ae861c673ab5160a2a7afee2ada806cb61966bjeffhao 26659a14265c911b2e63bec51a814b8b6fd157745b57Jeff Hao llvm::BasicBlock* block_cont = CreateBasicBlockWithDexPC(dex_pc, "cont"); 26665e869b6560f918837cc6be3a50234deb2be46385TDYa 26675e869b6560f918837cc6be3a50234deb2be46385TDYa if (llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc)) { 266855e5e6c5702e3f1f68bd83ae741af769740d9a74TDYa landing_pad_phi_mapping_[lpad].push_back(std::make_pair(current_bb_->getUniquePredecessor(), 2669aa55887fd30484a77e7775dfbcddbee883ce6380TDYa irb_.GetInsertBlock())); 26709a14265c911b2e63bec51a814b8b6fd157745b57Jeff Hao irb_.CreateCondBr(exception_pending, lpad, block_cont, kUnlikely); 26715e869b6560f918837cc6be3a50234deb2be46385TDYa } else { 26729a14265c911b2e63bec51a814b8b6fd157745b57Jeff Hao irb_.CreateCondBr(exception_pending, GetUnwindBasicBlock(), block_cont, kUnlikely); 26735e869b6560f918837cc6be3a50234deb2be46385TDYa } 26745e869b6560f918837cc6be3a50234deb2be46385TDYa 26755e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.SetInsertPoint(block_cont); 26765e869b6560f918837cc6be3a50234deb2be46385TDYa} 26775e869b6560f918837cc6be3a50234deb2be46385TDYa 267821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* 267921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::ExpandIntrinsic(IntrinsicHelper::IntrinsicId intr_id, 268021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::CallInst& call_inst) { 268121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao switch (intr_id) { 268221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Thread -----------------------------------------------------------==// 268321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::GetCurrentThread: { 2684b672d1e48b6e02bb69c7cd9bcfa7509c81514c07TDYa return irb_.Runtime().EmitGetCurrentThread(); 268521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 268675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::CheckSuspend: { 2687ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa Expand_TestSuspend(call_inst); 2688890ea89879ba555a08433146058d516575646c59TDYa return NULL; 2689890ea89879ba555a08433146058d516575646c59TDYa } 2690890ea89879ba555a08433146058d516575646c59TDYa case IntrinsicHelper::TestSuspend: { 2691d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien Expand_TestSuspend(call_inst); 269275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 269375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 269421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::MarkGCCard: { 26959a129457c233b653c7a8f65c963509267252b0a7TDYa Expand_MarkGCCard(call_inst); 26969a129457c233b653c7a8f65c963509267252b0a7TDYa return NULL; 269721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 269875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 269921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Exception --------------------------------------------------------==// 270021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ThrowException: { 270121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::ThrowException, call_inst); 270221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 2703f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa case IntrinsicHelper::HLThrowException: { 2704f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2705f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2706f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 2707f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2708f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCall(irb_.GetRuntime(runtime_support::ThrowException), 2709f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa call_inst.getArgOperand(0)); 2710f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2711f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 2712f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return NULL; 2713f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 271421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::GetException: { 2715823433dbf4afec17169d5ca738031af5b374e140TDYa return irb_.Runtime().EmitGetAndClearException(); 271621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 271721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::IsExceptionPending: { 271821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.Runtime().EmitIsExceptionPending(); 271921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 272021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::FindCatchBlock: { 272121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::FindCatchBlock, call_inst); 272221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 272321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ThrowDivZeroException: { 272421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::ThrowDivZeroException, call_inst); 272521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 272621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ThrowNullPointerException: { 272721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::ThrowNullPointerException, call_inst); 272821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 272921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ThrowIndexOutOfBounds: { 273021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::ThrowIndexOutOfBounds, call_inst); 273121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 273275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 273375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Const String -----------------------------------------------------==// 273475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::ConstString: { 2735f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return Expand_ConstString(call_inst); 273675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 273721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::LoadStringFromDexCache: { 273821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_LoadStringFromDexCache(call_inst.getArgOperand(0)); 273921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 274021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ResolveString: { 274121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::ResolveString, call_inst); 274221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 274375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 274475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Const Class ------------------------------------------------------==// 274575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::ConstClass: { 2746f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return Expand_ConstClass(call_inst); 274775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 274821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InitializeTypeAndVerifyAccess: { 274921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::InitializeTypeAndVerifyAccess, call_inst); 275021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 275121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::LoadTypeFromDexCache: { 275221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_LoadTypeFromDexCache(call_inst.getArgOperand(0)); 275321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 275421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InitializeType: { 275521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::InitializeType, call_inst); 275621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 275775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 275821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Lock -------------------------------------------------------------==// 275921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::LockObject: { 276021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_LockObject(call_inst.getArgOperand(0)); 276121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 276221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 276321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::UnlockObject: { 276421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_UnlockObject(call_inst.getArgOperand(0)); 276521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 276621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 276775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 276821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Cast -------------------------------------------------------------==// 276921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::CheckCast: { 277021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::CheckCast, call_inst); 277121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 277275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLCheckCast: { 2773f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa Expand_HLCheckCast(call_inst); 277475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 277575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 277621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::IsAssignable: { 277721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::IsAssignable, call_inst); 277821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 277975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 278021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Alloc ------------------------------------------------------------==// 278121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::AllocObject: { 278221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::AllocObject, call_inst); 278321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 278421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::AllocObjectWithAccessCheck: { 278521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::AllocObjectWithAccessCheck, call_inst); 278621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 278775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 278875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Instance ---------------------------------------------------------==// 278975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::NewInstance: { 2790f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return Expand_NewInstance(call_inst); 279175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 279275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::InstanceOf: { 2793f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return Expand_InstanceOf(call_inst); 279475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 279575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 279621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Array ------------------------------------------------------------==// 279775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::NewArray: { 2798f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return Expand_NewArray(call_inst); 279975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 280075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::OptArrayLength: { 2801f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return Expand_OptArrayLength(call_inst); 280275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 280321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayLength: { 280421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return EmitLoadArrayLength(call_inst.getArgOperand(0)); 280521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 280621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::AllocArray: { 280721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::AllocArray, call_inst); 280821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 280921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::AllocArrayWithAccessCheck: { 281021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::AllocArrayWithAccessCheck, 281121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst); 281221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 281321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::CheckAndAllocArray: { 281421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::CheckAndAllocArray, call_inst); 281521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 281621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::CheckAndAllocArrayWithAccessCheck: { 281721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::CheckAndAllocArrayWithAccessCheck, 281821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst); 281921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 282021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayGet: { 282121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_ArrayGet(call_inst.getArgOperand(0), 282221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 282321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kInt); 282421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 282521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayGetWide: { 282621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_ArrayGet(call_inst.getArgOperand(0), 282721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 282821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kLong); 282921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 283021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayGetObject: { 283121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_ArrayGet(call_inst.getArgOperand(0), 283221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 283321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kObject); 283421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 283521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayGetBoolean: { 283621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_ArrayGet(call_inst.getArgOperand(0), 283721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 283821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kBoolean); 283921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 284021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayGetByte: { 284121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_ArrayGet(call_inst.getArgOperand(0), 284221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 284321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kByte); 284421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 284521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayGetChar: { 284621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_ArrayGet(call_inst.getArgOperand(0), 284721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 284821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kChar); 284921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 285021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayGetShort: { 285121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_ArrayGet(call_inst.getArgOperand(0), 285221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 285321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kShort); 285421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 285521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayPut: { 285621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_ArrayPut(call_inst.getArgOperand(0), 285721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 285821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 285921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kInt); 286021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 286121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 286221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayPutWide: { 286321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_ArrayPut(call_inst.getArgOperand(0), 286421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 286521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 286621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kLong); 286721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 286821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 286921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayPutObject: { 287021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_ArrayPut(call_inst.getArgOperand(0), 287121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 287221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 287321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kObject); 287421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 287521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 287621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayPutBoolean: { 287721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_ArrayPut(call_inst.getArgOperand(0), 287821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 287921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 288021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kBoolean); 288121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 288221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 288321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayPutByte: { 288421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_ArrayPut(call_inst.getArgOperand(0), 288521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 288621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 288721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kByte); 288821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 288921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 289021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayPutChar: { 289121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_ArrayPut(call_inst.getArgOperand(0), 289221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 289321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 289421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kChar); 289521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 289621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 289721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayPutShort: { 289821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_ArrayPut(call_inst.getArgOperand(0), 289921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 290021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 290121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kShort); 290221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 290321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 290421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::CheckPutArrayElement: { 290521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::CheckPutArrayElement, call_inst); 290621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 290721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::FilledNewArray: { 290821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_FilledNewArray(call_inst); 290921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 291021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 291121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::FillArrayData: { 291221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::FillArrayData, call_inst); 291321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 291475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLFillArrayData: { 2915f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa Expand_HLFillArrayData(call_inst); 291675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 291775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 291875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLFilledNewArray: { 2919f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return Expand_HLFilledNewArray(call_inst); 292075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 292175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 292221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Instance Field ---------------------------------------------------==// 292321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGet: 292421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetBoolean: 292521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetByte: 292621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetChar: 292721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetShort: { 292821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::Get32Instance, call_inst); 292921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 293021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetWide: { 293121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::Get64Instance, call_inst); 293221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 293321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetObject: { 293421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::GetObjectInstance, call_inst); 293521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 293621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetFast: { 293721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_IGetFast(call_inst.getArgOperand(0), 293821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 293921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 294021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kInt); 294121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 294221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetWideFast: { 294321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_IGetFast(call_inst.getArgOperand(0), 294421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 294521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 294621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kLong); 294721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 294821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetObjectFast: { 294921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_IGetFast(call_inst.getArgOperand(0), 295021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 295121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 295221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kObject); 295321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 295421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetBooleanFast: { 295521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_IGetFast(call_inst.getArgOperand(0), 295621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 295721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 295821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kBoolean); 295921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 296021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetByteFast: { 296121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_IGetFast(call_inst.getArgOperand(0), 296221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 296321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 296421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kByte); 296521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 296621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetCharFast: { 296721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_IGetFast(call_inst.getArgOperand(0), 296821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 296921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 297021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kChar); 297121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 297221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetShortFast: { 297321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_IGetFast(call_inst.getArgOperand(0), 297421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 297521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 297621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kShort); 297721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 297821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPut: 297921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutBoolean: 298021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutByte: 298121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutChar: 298221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutShort: { 298321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::Set32Instance, call_inst); 298421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 298521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutWide: { 298621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::Set64Instance, call_inst); 298721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 298821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutObject: { 298921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::SetObjectInstance, call_inst); 299021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 299121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutFast: { 299221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_IPutFast(call_inst.getArgOperand(0), 299321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 299421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 299521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 299621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kInt); 299721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 299821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 299921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutWideFast: { 300021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_IPutFast(call_inst.getArgOperand(0), 300121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 300221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 300321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 300421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kLong); 300521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 300621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 300721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutObjectFast: { 300821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_IPutFast(call_inst.getArgOperand(0), 300921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 301021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 301121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 301221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kObject); 301321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 301421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 301521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutBooleanFast: { 301621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_IPutFast(call_inst.getArgOperand(0), 301721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 301821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 301921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 302021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kBoolean); 302121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 302221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 302321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutByteFast: { 302421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_IPutFast(call_inst.getArgOperand(0), 302521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 302621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 302721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 302821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kByte); 302921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 303021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 303121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutCharFast: { 303221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_IPutFast(call_inst.getArgOperand(0), 303321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 303421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 303521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 303621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kChar); 303721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 303821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 303921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutShortFast: { 304021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_IPutFast(call_inst.getArgOperand(0), 304121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 304221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 304321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 304421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kShort); 304521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 304621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 304775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 304821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Static Field -----------------------------------------------------==// 304921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGet: 305021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetBoolean: 305121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetByte: 305221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetChar: 305321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetShort: { 305421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::Get32Static, call_inst); 305521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 305621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetWide: { 305721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::Get64Static, call_inst); 305821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 305921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetObject: { 306021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::GetObjectStatic, call_inst); 306121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 306221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetFast: { 306321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_SGetFast(call_inst.getArgOperand(0), 306421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 306521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 306621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kInt); 306721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 306821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetWideFast: { 306921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_SGetFast(call_inst.getArgOperand(0), 307021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 307121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 307221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kLong); 307321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 307421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetObjectFast: { 307521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_SGetFast(call_inst.getArgOperand(0), 307621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 307721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 307821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kObject); 307921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 308021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetBooleanFast: { 308121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_SGetFast(call_inst.getArgOperand(0), 308221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 308321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 308421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kBoolean); 308521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 308621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetByteFast: { 308721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_SGetFast(call_inst.getArgOperand(0), 308821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 308921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 309021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kByte); 309121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 309221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetCharFast: { 309321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_SGetFast(call_inst.getArgOperand(0), 309421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 309521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 309621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kChar); 309721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 309821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetShortFast: { 309921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_SGetFast(call_inst.getArgOperand(0), 310021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 310121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 310221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kShort); 310321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 310421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPut: 310521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutBoolean: 310621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutByte: 310721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutChar: 310821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutShort: { 310921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::Set32Static, call_inst); 311021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 311121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutWide: { 311221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::Set64Static, call_inst); 311321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 311421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutObject: { 311521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::SetObjectStatic, call_inst); 311621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 311721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutFast: { 311821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_SPutFast(call_inst.getArgOperand(0), 311921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 312021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 312121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 312221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kInt); 312321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 312421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 312521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutWideFast: { 312621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_SPutFast(call_inst.getArgOperand(0), 312721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 312821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 312921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 313021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kLong); 313121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 313221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 313321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutObjectFast: { 313421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_SPutFast(call_inst.getArgOperand(0), 313521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 313621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 313721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 313821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kObject); 313921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 314021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 314121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutBooleanFast: { 314221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_SPutFast(call_inst.getArgOperand(0), 314321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 314421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 314521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 314621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kBoolean); 314721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 314821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 314921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutByteFast: { 315021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_SPutFast(call_inst.getArgOperand(0), 315121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 315221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 315321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 315421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kByte); 315521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 315621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 315721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutCharFast: { 315821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_SPutFast(call_inst.getArgOperand(0), 315921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 316021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 316121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 316221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kChar); 316321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 316421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 316521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutShortFast: { 316621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_SPutFast(call_inst.getArgOperand(0), 316721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 316821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 316921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 317021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kShort); 317121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 317221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 317321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::LoadDeclaringClassSSB: { 317421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_LoadDeclaringClassSSB(call_inst.getArgOperand(0)); 317521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 317621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::LoadClassSSBFromDexCache: { 317721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_LoadClassSSBFromDexCache(call_inst.getArgOperand(0)); 317821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 317921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InitializeAndLoadClassSSB: { 318021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::InitializeStaticStorage, call_inst); 318121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 318275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 318375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- High-level Array -------------------------------------------------==// 318475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayGet: { 31855a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLArrayGet(call_inst, kInt); 318675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 318775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayGetBoolean: { 31885a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLArrayGet(call_inst, kBoolean); 318975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 319075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayGetByte: { 31915a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLArrayGet(call_inst, kByte); 319275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 319375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayGetChar: { 31945a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLArrayGet(call_inst, kChar); 319575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 319675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayGetShort: { 31975a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLArrayGet(call_inst, kShort); 319875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 319975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayGetFloat: { 32005a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLArrayGet(call_inst, kFloat); 320175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 320275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayGetWide: { 32035a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLArrayGet(call_inst, kLong); 320475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 320575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayGetDouble: { 32065a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLArrayGet(call_inst, kDouble); 320775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 320875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayGetObject: { 32095a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLArrayGet(call_inst, kObject); 321075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 321175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayPut: { 32125a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLArrayPut(call_inst, kInt); 321375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 321475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 321575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayPutBoolean: { 32165a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLArrayPut(call_inst, kBoolean); 321775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 321875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 321975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayPutByte: { 32205a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLArrayPut(call_inst, kByte); 322175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 322275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 322375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayPutChar: { 32245a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLArrayPut(call_inst, kChar); 322575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 322675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 322775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayPutShort: { 32285a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLArrayPut(call_inst, kShort); 322975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 323075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 323175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayPutFloat: { 32325a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLArrayPut(call_inst, kFloat); 323375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 323475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 323575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayPutWide: { 32365a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLArrayPut(call_inst, kLong); 323775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 323875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 323975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayPutDouble: { 32405a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLArrayPut(call_inst, kDouble); 324175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 324275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 324375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayPutObject: { 32445a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLArrayPut(call_inst, kObject); 324575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 324675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 324775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 324875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- High-level Instance ----------------------------------------------==// 324975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIGet: { 32505e869b6560f918837cc6be3a50234deb2be46385TDYa return Expand_HLIGet(call_inst, kInt); 325175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 325275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIGetBoolean: { 32535e869b6560f918837cc6be3a50234deb2be46385TDYa return Expand_HLIGet(call_inst, kBoolean); 325475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 325575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIGetByte: { 32565e869b6560f918837cc6be3a50234deb2be46385TDYa return Expand_HLIGet(call_inst, kByte); 325775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 325875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIGetChar: { 32595e869b6560f918837cc6be3a50234deb2be46385TDYa return Expand_HLIGet(call_inst, kChar); 326075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 326175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIGetShort: { 32625e869b6560f918837cc6be3a50234deb2be46385TDYa return Expand_HLIGet(call_inst, kShort); 326375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 326475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIGetFloat: { 32655e869b6560f918837cc6be3a50234deb2be46385TDYa return Expand_HLIGet(call_inst, kFloat); 326675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 326775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIGetWide: { 32685e869b6560f918837cc6be3a50234deb2be46385TDYa return Expand_HLIGet(call_inst, kLong); 326975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 327075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIGetDouble: { 32715e869b6560f918837cc6be3a50234deb2be46385TDYa return Expand_HLIGet(call_inst, kDouble); 327275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 327375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIGetObject: { 32745e869b6560f918837cc6be3a50234deb2be46385TDYa return Expand_HLIGet(call_inst, kObject); 327575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 327675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIPut: { 32775e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_HLIPut(call_inst, kInt); 327875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 327975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 328075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIPutBoolean: { 32815e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_HLIPut(call_inst, kBoolean); 328275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 328375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 328475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIPutByte: { 32855e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_HLIPut(call_inst, kByte); 328675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 328775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 328875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIPutChar: { 32895e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_HLIPut(call_inst, kChar); 329075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 329175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 329275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIPutShort: { 32935e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_HLIPut(call_inst, kShort); 329475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 329575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 329675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIPutFloat: { 32975e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_HLIPut(call_inst, kFloat); 329875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 329975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 330075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIPutWide: { 33015e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_HLIPut(call_inst, kLong); 330275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 330375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 330475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIPutDouble: { 33055e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_HLIPut(call_inst, kDouble); 330675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 330775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 330875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIPutObject: { 33095e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_HLIPut(call_inst, kObject); 331075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 331175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 331275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 331375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- High-level Invoke ------------------------------------------------==// 3314f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa case IntrinsicHelper::HLInvokeVoid: 3315f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa case IntrinsicHelper::HLInvokeObj: 3316f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa case IntrinsicHelper::HLInvokeInt: 3317f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa case IntrinsicHelper::HLInvokeFloat: 3318f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa case IntrinsicHelper::HLInvokeLong: 331975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLInvokeDouble: { 3320f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return Expand_HLInvoke(call_inst); 332175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 332275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 332321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Invoke -----------------------------------------------------------==// 332421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::FindStaticMethodWithAccessCheck: { 332521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::FindStaticMethodWithAccessCheck, call_inst); 332621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 332721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::FindDirectMethodWithAccessCheck: { 332821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::FindDirectMethodWithAccessCheck, call_inst); 332921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 333021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::FindVirtualMethodWithAccessCheck: { 333121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::FindVirtualMethodWithAccessCheck, call_inst); 333221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 333321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::FindSuperMethodWithAccessCheck: { 333421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::FindSuperMethodWithAccessCheck, call_inst); 333521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 333621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::FindInterfaceMethodWithAccessCheck: { 333721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::FindInterfaceMethodWithAccessCheck, call_inst); 333821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 333921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::GetSDCalleeMethodObjAddrFast: { 334021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_GetSDCalleeMethodObjAddrFast(call_inst.getArgOperand(0)); 334121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 334221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::GetVirtualCalleeMethodObjAddrFast: { 334321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_GetVirtualCalleeMethodObjAddrFast( 334421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(0), call_inst.getArgOperand(1)); 334521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 334621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::GetInterfaceCalleeMethodObjAddrFast: { 334721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::FindInterfaceMethod, call_inst); 334821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 334921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetVoid: 335021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetBoolean: 335121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetByte: 335221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetChar: 335321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetShort: 335421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetInt: 335521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetLong: 335621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetFloat: 335721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetDouble: 335821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetObject: { 335921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_Invoke(call_inst); 336021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 336175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 336221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Math -------------------------------------------------------------==// 336321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::DivInt: { 33644ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa return Expand_DivRem(call_inst, /* is_div */true, kInt); 336521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 336621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::RemInt: { 33674ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa return Expand_DivRem(call_inst, /* is_div */false, kInt); 336821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 336921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::DivLong: { 33704ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa return Expand_DivRem(call_inst, /* is_div */true, kLong); 337121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 337221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::RemLong: { 33734ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa return Expand_DivRem(call_inst, /* is_div */false, kLong); 337421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 337521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::D2L: { 337621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::art_d2l, call_inst); 337721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 337821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::D2I: { 337921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::art_d2i, call_inst); 338021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 338121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::F2L: { 338221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::art_f2l, call_inst); 338321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 338421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::F2I: { 338521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return ExpandToRuntime(runtime_support::art_f2i, call_inst); 338621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 338775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 338875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- High-level Static ------------------------------------------------==// 338975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSget: { 33905a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLSget(call_inst, kInt); 339175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 339275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSgetBoolean: { 33935a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLSget(call_inst, kBoolean); 339475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 339575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSgetByte: { 33965a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLSget(call_inst, kByte); 339775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 339875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSgetChar: { 33995a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLSget(call_inst, kChar); 340075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 340175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSgetShort: { 34025a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLSget(call_inst, kShort); 340375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 340475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSgetFloat: { 34055a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLSget(call_inst, kFloat); 340675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 340775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSgetWide: { 34085a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLSget(call_inst, kLong); 340975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 341075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSgetDouble: { 34115a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLSget(call_inst, kDouble); 341275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 341375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSgetObject: { 34145a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLSget(call_inst, kObject); 341575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 341675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSput: { 34175a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLSput(call_inst, kInt); 341875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 341975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 342075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSputBoolean: { 34215a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLSput(call_inst, kBoolean); 342275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 342375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 342475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSputByte: { 34255a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLSput(call_inst, kByte); 342675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 342775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 342875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSputChar: { 34295a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLSput(call_inst, kChar); 343075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 343175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 343275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSputShort: { 34335a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLSput(call_inst, kShort); 343475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 343575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 343675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSputFloat: { 34375a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLSput(call_inst, kFloat); 343875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 343975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 344075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSputWide: { 34415a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLSput(call_inst, kLong); 344275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 344375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 344475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSputDouble: { 34455a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLSput(call_inst, kDouble); 344675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 344775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 344875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSputObject: { 34495a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLSput(call_inst, kObject); 345075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 345175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 345275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 345375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- High-level Monitor -----------------------------------------------==// 345475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::MonitorEnter: { 3455f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa Expand_MonitorEnter(call_inst); 345675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 345775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 345875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::MonitorExit: { 3459f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa Expand_MonitorExit(call_inst); 346075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 346175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 346275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 346321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Shadow Frame -----------------------------------------------------==// 346421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::AllocaShadowFrame: { 3465ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa Expand_AllocaShadowFrame(call_inst.getArgOperand(0)); 346621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 346721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 34688e950c117975d23f50ed7e32ca5db01a813c25d0TDYa case IntrinsicHelper::SetVReg: { 34698e950c117975d23f50ed7e32ca5db01a813c25d0TDYa Expand_SetVReg(call_inst.getArgOperand(0), 34708e950c117975d23f50ed7e32ca5db01a813c25d0TDYa call_inst.getArgOperand(1)); 34718e950c117975d23f50ed7e32ca5db01a813c25d0TDYa return NULL; 34728e950c117975d23f50ed7e32ca5db01a813c25d0TDYa } 347321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::PopShadowFrame: { 347421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_PopShadowFrame(); 347521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 347621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 347721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::UpdateDexPC: { 347821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_UpdateDexPC(call_inst.getArgOperand(0)); 347921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 348021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 3481a1b2185820e6080864d18a35759cc046dc4ee578TDYa 348275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Comparison -------------------------------------------------------==// 3483a1b2185820e6080864d18a35759cc046dc4ee578TDYa case IntrinsicHelper::CmplFloat: 3484a1b2185820e6080864d18a35759cc046dc4ee578TDYa case IntrinsicHelper::CmplDouble: { 348575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return Expand_FPCompare(call_inst.getArgOperand(0), 348675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien call_inst.getArgOperand(1), 348775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien false); 3488a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 3489a1b2185820e6080864d18a35759cc046dc4ee578TDYa case IntrinsicHelper::CmpgFloat: 3490a1b2185820e6080864d18a35759cc046dc4ee578TDYa case IntrinsicHelper::CmpgDouble: { 349175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return Expand_FPCompare(call_inst.getArgOperand(0), 349275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien call_inst.getArgOperand(1), 349375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien true); 3494a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 3495a1b2185820e6080864d18a35759cc046dc4ee578TDYa case IntrinsicHelper::CmpLong: { 349675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return Expand_LongCompare(call_inst.getArgOperand(0), 349775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien call_inst.getArgOperand(1)); 349875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 349975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 350075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Const ------------------------------------------------------------==// 3501920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::ConstInt: 3502920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::ConstLong: { 3503d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien return call_inst.getArgOperand(0); 350475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 3505920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::ConstFloat: { 3506d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien return irb_.CreateBitCast(call_inst.getArgOperand(0), 3507d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien irb_.getJFloatTy()); 350875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 3509920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::ConstDouble: { 3510d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien return irb_.CreateBitCast(call_inst.getArgOperand(0), 3511d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien irb_.getJDoubleTy()); 3512d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien } 3513920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::ConstObj: { 3514bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao CHECK(LV2UInt(call_inst.getArgOperand(0)) == 0); 3515bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao return irb_.getJNull(); 3516a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 351775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 351875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Method Info ------------------------------------------------------==// 3519920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::MethodInfo: { 3520b259652a72293b4bd3c346bb0e40fb8a7f878fa2Shih-wei Liao // Nothing to be done, because MethodInfo carries optional hints that are 3521b259652a72293b4bd3c346bb0e40fb8a7f878fa2Shih-wei Liao // not needed by the portable path. 352275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 352375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 352475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 352575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Copy -------------------------------------------------------------==// 3526920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::CopyInt: 3527920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::CopyFloat: 3528920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::CopyLong: 3529920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::CopyDouble: 3530920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::CopyObj: { 3531d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien return call_inst.getArgOperand(0); 353275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 353375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 353475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Shift ------------------------------------------------------------==// 3535920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::SHLLong: { 353675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return Expand_IntegerShift(call_inst.getArgOperand(0), 353775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien call_inst.getArgOperand(1), 353875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien kIntegerSHL, kLong); 3539a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 3540920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::SHRLong: { 354175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return Expand_IntegerShift(call_inst.getArgOperand(0), 354275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien call_inst.getArgOperand(1), 354375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien kIntegerSHR, kLong); 3544a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 3545920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::USHRLong: { 354675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return Expand_IntegerShift(call_inst.getArgOperand(0), 354775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien call_inst.getArgOperand(1), 354875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien kIntegerUSHR, kLong); 3549a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 3550920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::SHLInt: { 355175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return Expand_IntegerShift(call_inst.getArgOperand(0), 355275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien call_inst.getArgOperand(1), 355375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien kIntegerSHL, kInt); 3554a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 3555920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::SHRInt: { 355675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return Expand_IntegerShift(call_inst.getArgOperand(0), 355775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien call_inst.getArgOperand(1), 355875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien kIntegerSHR, kInt); 3559a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 3560920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::USHRInt: { 356175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return Expand_IntegerShift(call_inst.getArgOperand(0), 356275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien call_inst.getArgOperand(1), 356375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien kIntegerUSHR, kInt); 3564a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 356521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 356675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Conversion -------------------------------------------------------==// 356775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::IntToChar: { 356875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return irb_.CreateZExt(irb_.CreateTrunc(call_inst.getArgOperand(0), irb_.getJCharTy()), 356975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien irb_.getJIntTy()); 357075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 357175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::IntToShort: { 357275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return irb_.CreateSExt(irb_.CreateTrunc(call_inst.getArgOperand(0), irb_.getJShortTy()), 357375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien irb_.getJIntTy()); 357421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 357575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::IntToByte: { 357675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return irb_.CreateSExt(irb_.CreateTrunc(call_inst.getArgOperand(0), irb_.getJByteTy()), 357775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien irb_.getJIntTy()); 357875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 357975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 358087caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa //==- Exception --------------------------------------------------------==// 358187caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa case IntrinsicHelper::CatchTargets: { 358255e5e6c5702e3f1f68bd83ae741af769740d9a74TDYa UpdatePhiInstruction(current_bb_, irb_.GetInsertBlock()); 358387caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa llvm::SwitchInst* si = llvm::dyn_cast<llvm::SwitchInst>(call_inst.getNextNode()); 358487caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa CHECK(si != NULL); 358587caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa irb_.CreateBr(si->getDefaultDest()); 358687caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa si->eraseFromParent(); 358787caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa return call_inst.getArgOperand(0); 358887caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa } 358987caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa 359075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Unknown Cases ----------------------------------------------------==// 359175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::MaxIntrinsicId: 359275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::UnknownId: 359375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //default: 359475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien // NOTE: "default" is intentionally commented so that C/C++ compiler will 359575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien // give some warning on unmatched cases. 359675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien // NOTE: We should not implement these cases. 359775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien break; 359821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 359975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien UNIMPLEMENTED(FATAL) << "Unexpected GBC intrinsic: " << static_cast<int>(intr_id); 360021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 360121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 360221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 360321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} // anonymous namespace 360421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 360521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaonamespace art { 3606b259652a72293b4bd3c346bb0e40fb8a7f878fa2Shih-wei Liao 360721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaonamespace compiler_llvm { 360821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 360921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::FunctionPass* 361021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoCreateGBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb) { 361121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return new GBCExpanderPass(intrinsic_helper, irb); 361221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 361321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 3614bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liaollvm::FunctionPass* 3615bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei LiaoCreateGBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb, 3616bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao Compiler* compiler, OatCompilationUnit* oat_compilation_unit) { 3617bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao if (compiler != NULL) { 3618bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao return new GBCExpanderPass(intrinsic_helper, irb, 3619bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao compiler, oat_compilation_unit); 3620bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao } else { 3621bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao return new GBCExpanderPass(intrinsic_helper, irb); 3622bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao } 3623bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao} 3624bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao 362521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} // namespace compiler_llvm 362621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} // namespace art 3627