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 174f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h" 187940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "driver/compiler_driver.h" 197940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "driver/dex_compilation_unit.h" 2076ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers#include "intrinsic_helper.h" 218e6960569e9de6350d7da89aa02efe0e4b924d6fIan Rogers#include "ir_builder.h" 2251c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom#include "method_reference.h" 23ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "mirror/art_method.h" 2498573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers#include "mirror/array.h" 25901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz#include "mirror/string.h" 2621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include "thread.h" 278e6960569e9de6350d7da89aa02efe0e4b924d6fIan Rogers#include "utils_llvm.h" 285e869b6560f918837cc6be3a50234deb2be46385TDYa#include "verifier/method_verifier.h" 2921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 307940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/compiler_ir.h" 317940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/mir_graph.h" 327940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/quick/mir_to_lir.h" 33920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa 3421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include <llvm/ADT/STLExtras.h> 3537d4879df243f7a2161b5416fad299ad1d495131Brian Carlstrom#include <llvm/IR/Intrinsics.h> 3637d4879df243f7a2161b5416fad299ad1d495131Brian Carlstrom#include <llvm/IR/Metadata.h> 3721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include <llvm/Pass.h> 3821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include <llvm/Support/CFG.h> 3921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include <llvm/Support/InstIterator.h> 4021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 4121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao#include <vector> 42aa55887fd30484a77e7775dfbcddbee883ce6380TDYa#include <map> 43aa55887fd30484a77e7775dfbcddbee883ce6380TDYa#include <utility> 4421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 453e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::kMIRIgnoreNullCheck; 463e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::kMIRIgnoreRangeCheck; 473e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::IRBuilder; 483e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::IntrinsicHelper; 493e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::JType; 503e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::RuntimeSupportBuilder; 513e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::kBoolean; 523e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::kByte; 533e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::kChar; 543e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::kDouble; 553e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::kFloat; 563e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::kInt; 573e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::kLikely; 583e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::kLong; 593e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::kObject; 603e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::kShort; 613e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::kTBAAConstJObject; 623e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::kTBAAHeapArray; 633e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::kTBAAHeapInstance; 643e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::kTBAAHeapStatic; 653e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::kTBAARegister; 663e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::kTBAARuntimeInfo; 673e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::kTBAAShadowFrame; 683e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::kUnlikely; 693e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::kVoid; 703e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::AllocArray; 713e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::AllocArrayWithAccessCheck; 723e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::AllocObject; 733e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::AllocObjectWithAccessCheck; 743e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::CheckAndAllocArray; 753e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::CheckAndAllocArrayWithAccessCheck; 763e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::CheckCast; 773e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::CheckPutArrayElement; 783e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::FillArrayData; 793e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::FindCatchBlock; 803e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::FindDirectMethodWithAccessCheck; 813e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::FindInterfaceMethod; 823e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::FindInterfaceMethodWithAccessCheck; 833e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::FindStaticMethodWithAccessCheck; 843e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::FindSuperMethodWithAccessCheck; 853e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::FindVirtualMethodWithAccessCheck; 863e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::Get32Instance; 873e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::Get32Static; 883e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::Get64Instance; 893e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::Get64Static; 903e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::GetObjectInstance; 913e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::GetObjectStatic; 923e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::InitializeStaticStorage; 933e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::InitializeType; 943e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::InitializeTypeAndVerifyAccess; 953e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::IsAssignable; 963e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::ResolveString; 973e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::RuntimeId; 983e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::Set32Instance; 993e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::Set32Static; 1003e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::Set64Instance; 1013e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::Set64Static; 1023e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::SetObjectInstance; 1033e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::SetObjectStatic; 1043e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::ThrowDivZeroException; 1053e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::ThrowException; 1063e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::ThrowIndexOutOfBounds; 1073e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::ThrowNullPointerException; 1083e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::ThrowStackOverflowException; 1093e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::art_d2i; 1103e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::art_d2l; 1113e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::art_f2i; 1123e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::llvm::runtime_support::art_f2l; 11321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 114b259652a72293b4bd3c346bb0e40fb8a7f878fa2Shih-wei Liaonamespace art { 11526f10eed520942d3db754c31941e457048475f61buzbeeextern char RemapShorty(char shortyType); 1163e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom} // namespace art 117b259652a72293b4bd3c346bb0e40fb8a7f878fa2Shih-wei Liao 11821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaonamespace { 11921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 12021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaoclass GBCExpanderPass : public llvm::FunctionPass { 12121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao private: 12221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao const IntrinsicHelper& intrinsic_helper_; 12321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao IRBuilder& irb_; 12421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 12521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::LLVMContext& context_; 12621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao RuntimeSupportBuilder& rtb_; 12721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 12821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao private: 12921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::AllocaInst* shadow_frame_; 13021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* old_shadow_frame_; 13121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 13221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao private: 1331212a022fa5f8ef9585d765b1809521812af882cIan Rogers art::CompilerDriver* const driver_; 1345e869b6560f918837cc6be3a50234deb2be46385TDYa 13589756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers const art::DexCompilationUnit* const dex_compilation_unit_; 1365e869b6560f918837cc6be3a50234deb2be46385TDYa 1375e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Function* func_; 1385e869b6560f918837cc6be3a50234deb2be46385TDYa 1395e869b6560f918837cc6be3a50234deb2be46385TDYa std::vector<llvm::BasicBlock*> basic_blocks_; 1405e869b6560f918837cc6be3a50234deb2be46385TDYa 1415e869b6560f918837cc6be3a50234deb2be46385TDYa std::vector<llvm::BasicBlock*> basic_block_landing_pads_; 14255e5e6c5702e3f1f68bd83ae741af769740d9a74TDYa llvm::BasicBlock* current_bb_; 143aa55887fd30484a77e7775dfbcddbee883ce6380TDYa std::map<llvm::BasicBlock*, std::vector<std::pair<llvm::BasicBlock*, llvm::BasicBlock*> > > 144aa55887fd30484a77e7775dfbcddbee883ce6380TDYa landing_pad_phi_mapping_; 1455e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* basic_block_unwind_; 1465e869b6560f918837cc6be3a50234deb2be46385TDYa 147f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz // Maps each vreg to its shadow frame address. 148f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz std::vector<llvm::Value*> shadow_frame_vreg_addresses_; 149f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz 15067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien bool changed_; 15167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 1525e869b6560f918837cc6be3a50234deb2be46385TDYa private: 15321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //---------------------------------------------------------------------------- 15475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien // Constant for GBC expansion 15575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //---------------------------------------------------------------------------- 15675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien enum IntegerShiftKind { 15775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien kIntegerSHL, 15875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien kIntegerSHR, 15975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien kIntegerUSHR, 16075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien }; 16175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 16275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien private: 16375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //---------------------------------------------------------------------------- 16421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Helper function for GBC expansion 16521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //---------------------------------------------------------------------------- 16621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 1673e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom llvm::Value* ExpandToRuntime(RuntimeId rt, llvm::CallInst& inst); 16821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 1695e869b6560f918837cc6be3a50234deb2be46385TDYa uint64_t LV2UInt(llvm::Value* lv) { 1705e869b6560f918837cc6be3a50234deb2be46385TDYa return llvm::cast<llvm::ConstantInt>(lv)->getZExtValue(); 1715e869b6560f918837cc6be3a50234deb2be46385TDYa } 1725e869b6560f918837cc6be3a50234deb2be46385TDYa 1735e869b6560f918837cc6be3a50234deb2be46385TDYa int64_t LV2SInt(llvm::Value* lv) { 1745e869b6560f918837cc6be3a50234deb2be46385TDYa return llvm::cast<llvm::ConstantInt>(lv)->getSExtValue(); 1755e869b6560f918837cc6be3a50234deb2be46385TDYa } 1765e869b6560f918837cc6be3a50234deb2be46385TDYa 17721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao private: 17821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // TODO: Almost all Emit* are directly copy-n-paste from MethodCompiler. 17921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Refactor these utility functions from MethodCompiler to avoid forking. 18021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 18167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien void EmitStackOverflowCheck(llvm::Instruction* first_non_alloca); 18267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 18367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien void RewriteFunction(); 18467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 18567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien void RewriteBasicBlock(llvm::BasicBlock* original_block); 18667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 18767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien void UpdatePhiInstruction(llvm::BasicBlock* old_basic_block, 18867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock* new_basic_block); 18967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 19021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 19176ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers // Sign or zero extend category 1 types < 32bits in size to 32bits. 19276ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers llvm::Value* SignOrZeroExtendCat1Types(llvm::Value* value, JType jty); 19376ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers 19476ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers // Truncate category 1 types from 32bits to the given JType size. 19576ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers llvm::Value* TruncateCat1Types(llvm::Value* value, JType jty); 19676ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers 19721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //---------------------------------------------------------------------------- 19821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Dex cache code generation helper function 19921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //---------------------------------------------------------------------------- 200920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa llvm::Value* EmitLoadDexCacheAddr(art::MemberOffset dex_cache_offset); 20121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 20221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* EmitLoadDexCacheStaticStorageFieldAddr(uint32_t type_idx); 20321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 20421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* EmitLoadDexCacheResolvedTypeFieldAddr(uint32_t type_idx); 20521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 20621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* EmitLoadDexCacheResolvedMethodFieldAddr(uint32_t method_idx); 20721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 20821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* EmitLoadDexCacheStringFieldAddr(uint32_t string_idx); 20921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 21021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //---------------------------------------------------------------------------- 21121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Code generation helper function 21221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //---------------------------------------------------------------------------- 21321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* EmitLoadMethodObjectAddr(); 21421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 21521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* EmitLoadArrayLength(llvm::Value* array); 21621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 21721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* EmitLoadSDCalleeMethodObjectAddr(uint32_t callee_method_idx); 21821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 21921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* EmitLoadVirtualCalleeMethodObjectAddr(int vtable_idx, 22021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* this_addr); 22121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 22221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* EmitArrayGEP(llvm::Value* array_addr, 22321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* index_value, 22421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType elem_jty); 22521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 226901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz //---------------------------------------------------------------------------- 227901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz // Invoke helper function 228901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz //---------------------------------------------------------------------------- 229901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz llvm::Value* EmitInvoke(llvm::CallInst& call_inst); 230901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 231901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz //---------------------------------------------------------------------------- 232901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz // Inlining helper functions 233901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz //---------------------------------------------------------------------------- 234901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz bool EmitIntrinsic(llvm::CallInst& call_inst, llvm::Value** result); 235901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 236901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz bool EmitIntrinsicStringLengthOrIsEmpty(llvm::CallInst& call_inst, 237901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz llvm::Value** result, bool is_empty); 238901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 23921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao private: 24021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //---------------------------------------------------------------------------- 24121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Expand Greenland intrinsics 24221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //---------------------------------------------------------------------------- 24321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao void Expand_TestSuspend(llvm::CallInst& call_inst); 24421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 2459a129457c233b653c7a8f65c963509267252b0a7TDYa void Expand_MarkGCCard(llvm::CallInst& call_inst); 2469a129457c233b653c7a8f65c963509267252b0a7TDYa 24721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* Expand_LoadStringFromDexCache(llvm::Value* string_idx_value); 24821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 24921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* Expand_LoadTypeFromDexCache(llvm::Value* type_idx_value); 25021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 25121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao void Expand_LockObject(llvm::Value* obj); 25221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 25321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao void Expand_UnlockObject(llvm::Value* obj); 25421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 25521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* Expand_ArrayGet(llvm::Value* array_addr, 25621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* index_value, 25721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType elem_jty); 25821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 25921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao void Expand_ArrayPut(llvm::Value* new_value, 26021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* array_addr, 26121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* index_value, 26221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType elem_jty); 26321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 26421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao void Expand_FilledNewArray(llvm::CallInst& call_inst); 26521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 26621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* Expand_IGetFast(llvm::Value* field_offset_value, 26721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* is_volatile_value, 26821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* object_addr, 26921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType field_jty); 27021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 27121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao void Expand_IPutFast(llvm::Value* field_offset_value, 27221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* is_volatile_value, 27321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* object_addr, 27421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* new_value, 27521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType field_jty); 27621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 27721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* Expand_SGetFast(llvm::Value* static_storage_addr, 27821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* field_offset_value, 27921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* is_volatile_value, 28021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType field_jty); 28121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 28221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao void Expand_SPutFast(llvm::Value* static_storage_addr, 28321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* field_offset_value, 28421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* is_volatile_value, 28521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* new_value, 28621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType field_jty); 28721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 28821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* Expand_LoadDeclaringClassSSB(llvm::Value* method_object_addr); 28921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 29021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* Expand_LoadClassSSBFromDexCache(llvm::Value* type_idx_value); 29121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 29221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* 29321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_GetSDCalleeMethodObjAddrFast(llvm::Value* callee_method_idx_value); 29421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 29521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* 29621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_GetVirtualCalleeMethodObjAddrFast(llvm::Value* vtable_idx_value, 29721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* this_addr); 29821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 29921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* Expand_Invoke(llvm::CallInst& call_inst); 30021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 3014ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa llvm::Value* Expand_DivRem(llvm::CallInst& call_inst, bool is_div, JType op_jty); 30221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 303ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa void Expand_AllocaShadowFrame(llvm::Value* num_vregs_value); 30421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 3058e950c117975d23f50ed7e32ca5db01a813c25d0TDYa void Expand_SetVReg(llvm::Value* entry_idx, llvm::Value* obj); 3068e950c117975d23f50ed7e32ca5db01a813c25d0TDYa 30721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao void Expand_PopShadowFrame(); 30821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 30921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao void Expand_UpdateDexPC(llvm::Value* dex_pc_value); 31021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 311a1b2185820e6080864d18a35759cc046dc4ee578TDYa //---------------------------------------------------------------------------- 312a1b2185820e6080864d18a35759cc046dc4ee578TDYa // Quick 313a1b2185820e6080864d18a35759cc046dc4ee578TDYa //---------------------------------------------------------------------------- 314a1b2185820e6080864d18a35759cc046dc4ee578TDYa 315a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* Expand_FPCompare(llvm::Value* src1_value, 316a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* src2_value, 317a1b2185820e6080864d18a35759cc046dc4ee578TDYa bool gt_bias); 318a1b2185820e6080864d18a35759cc046dc4ee578TDYa 319a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* Expand_LongCompare(llvm::Value* src1_value, llvm::Value* src2_value); 320a1b2185820e6080864d18a35759cc046dc4ee578TDYa 321a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* EmitCompareResultSelection(llvm::Value* cmp_eq, 322a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* cmp_lt); 323a1b2185820e6080864d18a35759cc046dc4ee578TDYa 324f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* EmitLoadConstantClass(uint32_t dex_pc, uint32_t type_idx); 3255a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* EmitLoadStaticStorage(uint32_t dex_pc, uint32_t type_idx); 3265a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 3275e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* Expand_HLIGet(llvm::CallInst& call_inst, JType field_jty); 3285e869b6560f918837cc6be3a50234deb2be46385TDYa void Expand_HLIPut(llvm::CallInst& call_inst, JType field_jty); 3295e869b6560f918837cc6be3a50234deb2be46385TDYa 3305a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* Expand_HLSget(llvm::CallInst& call_inst, JType field_jty); 3315a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa void Expand_HLSput(llvm::CallInst& call_inst, JType field_jty); 3325a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 3335a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* Expand_HLArrayGet(llvm::CallInst& call_inst, JType field_jty); 3345a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa void Expand_HLArrayPut(llvm::CallInst& call_inst, JType field_jty); 3355a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 336f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* Expand_ConstString(llvm::CallInst& call_inst); 337f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* Expand_ConstClass(llvm::CallInst& call_inst); 338f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 339f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa void Expand_MonitorEnter(llvm::CallInst& call_inst); 340f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa void Expand_MonitorExit(llvm::CallInst& call_inst); 341f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 342f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa void Expand_HLCheckCast(llvm::CallInst& call_inst); 343f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* Expand_InstanceOf(llvm::CallInst& call_inst); 344f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 345f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* Expand_NewInstance(llvm::CallInst& call_inst); 346f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 347f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* Expand_HLInvoke(llvm::CallInst& call_inst); 348f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 349f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* Expand_OptArrayLength(llvm::CallInst& call_inst); 350f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* Expand_NewArray(llvm::CallInst& call_inst); 351f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* Expand_HLFilledNewArray(llvm::CallInst& call_inst); 352f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa void Expand_HLFillArrayData(llvm::CallInst& call_inst); 353f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 354f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* EmitAllocNewArray(uint32_t dex_pc, 355f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* array_length_value, 356f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_idx, 357f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa bool is_filled_new_array); 358f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 359f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* EmitCallRuntimeForCalleeMethodObjectAddr(uint32_t callee_method_idx, 360920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::InvokeType invoke_type, 361f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* this_addr, 362f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc, 363f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa bool is_fast_path); 364f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 3655e869b6560f918837cc6be3a50234deb2be46385TDYa void EmitMarkGCCard(llvm::Value* value, llvm::Value* target_addr); 3665e869b6560f918837cc6be3a50234deb2be46385TDYa 3675e869b6560f918837cc6be3a50234deb2be46385TDYa void EmitUpdateDexPC(uint32_t dex_pc); 3685e869b6560f918837cc6be3a50234deb2be46385TDYa 3695e869b6560f918837cc6be3a50234deb2be46385TDYa void EmitGuard_DivZeroException(uint32_t dex_pc, 3705e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* denominator, 3715e869b6560f918837cc6be3a50234deb2be46385TDYa JType op_jty); 3725e869b6560f918837cc6be3a50234deb2be46385TDYa 3732ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz void EmitGuard_NullPointerException(uint32_t dex_pc, llvm::Value* object, 3742ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz int opt_flags); 3755e869b6560f918837cc6be3a50234deb2be46385TDYa 3765e869b6560f918837cc6be3a50234deb2be46385TDYa void EmitGuard_ArrayIndexOutOfBoundsException(uint32_t dex_pc, 3775e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* array, 3782ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz llvm::Value* index, 3792ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz int opt_flags); 3805e869b6560f918837cc6be3a50234deb2be46385TDYa 3818e6960569e9de6350d7da89aa02efe0e4b924d6fIan Rogers llvm::FunctionType* GetFunctionType(llvm::Type* ret_type, uint32_t method_idx, bool is_static); 3825e869b6560f918837cc6be3a50234deb2be46385TDYa 3835e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* GetBasicBlock(uint32_t dex_pc); 3845e869b6560f918837cc6be3a50234deb2be46385TDYa 3855e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* CreateBasicBlockWithDexPC(uint32_t dex_pc, 3865e869b6560f918837cc6be3a50234deb2be46385TDYa const char* postfix); 3875e869b6560f918837cc6be3a50234deb2be46385TDYa 3885e869b6560f918837cc6be3a50234deb2be46385TDYa int32_t GetTryItemOffset(uint32_t dex_pc); 3895e869b6560f918837cc6be3a50234deb2be46385TDYa 3905e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* GetLandingPadBasicBlock(uint32_t dex_pc); 3915e869b6560f918837cc6be3a50234deb2be46385TDYa 3925e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* GetUnwindBasicBlock(); 3935e869b6560f918837cc6be3a50234deb2be46385TDYa 3945e869b6560f918837cc6be3a50234deb2be46385TDYa void EmitGuard_ExceptionLandingPad(uint32_t dex_pc); 3955e869b6560f918837cc6be3a50234deb2be46385TDYa 3965e869b6560f918837cc6be3a50234deb2be46385TDYa void EmitBranchExceptionLandingPad(uint32_t dex_pc); 3975e869b6560f918837cc6be3a50234deb2be46385TDYa 39875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //---------------------------------------------------------------------------- 39975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien // Expand Arithmetic Helper Intrinsics 40075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //---------------------------------------------------------------------------- 40175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 40275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien llvm::Value* Expand_IntegerShift(llvm::Value* src1_value, 40375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien llvm::Value* src2_value, 40475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien IntegerShiftKind kind, 40575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien JType op_jty); 40675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 40721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao public: 40821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao static char ID; 40921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 410bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao GBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb, 4110d94eb659387bb797498918ac7e1a41f14b4a11bIan Rogers art::CompilerDriver* driver, const art::DexCompilationUnit* dex_compilation_unit) 412bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao : llvm::FunctionPass(ID), intrinsic_helper_(intrinsic_helper), irb_(irb), 413bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao context_(irb.getContext()), rtb_(irb.Runtime()), 4148e950c117975d23f50ed7e32ca5db01a813c25d0TDYa shadow_frame_(NULL), old_shadow_frame_(NULL), 4150d94eb659387bb797498918ac7e1a41f14b4a11bIan Rogers driver_(driver), 41689756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers dex_compilation_unit_(dex_compilation_unit), 4178e6960569e9de6350d7da89aa02efe0e4b924d6fIan Rogers func_(NULL), current_bb_(NULL), basic_block_unwind_(NULL), changed_(false) {} 418bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao 41921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao bool runOnFunction(llvm::Function& func); 42021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 42121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao private: 42267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien void InsertStackOverflowCheck(llvm::Function& func); 42321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 42421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* ExpandIntrinsic(IntrinsicHelper::IntrinsicId intr_id, 42521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::CallInst& call_inst); 42621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao}; 42721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 42821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaochar GBCExpanderPass::ID = 0; 42921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 43021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaobool GBCExpanderPass::runOnFunction(llvm::Function& func) { 4318e6960569e9de6350d7da89aa02efe0e4b924d6fIan Rogers VLOG(compiler) << "GBC expansion on " << func.getName().str(); 4328e6960569e9de6350d7da89aa02efe0e4b924d6fIan Rogers 433b672d1e48b6e02bb69c7cd9bcfa7509c81514c07TDYa // Runtime support or stub 434265091e581c9f643b37e7966890911f09e223269Brian Carlstrom if (dex_compilation_unit_ == NULL) { 435b672d1e48b6e02bb69c7cd9bcfa7509c81514c07TDYa return false; 436b672d1e48b6e02bb69c7cd9bcfa7509c81514c07TDYa } 43721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 43867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Setup rewrite context 43967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien shadow_frame_ = NULL; 44067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien old_shadow_frame_ = NULL; 44167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien func_ = &func; 4427934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom changed_ = false; // Assume unchanged 44321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 444f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz shadow_frame_vreg_addresses_.resize(dex_compilation_unit_->GetCodeItem()->registers_size_, NULL); 44589756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers basic_blocks_.resize(dex_compilation_unit_->GetCodeItem()->insns_size_in_code_units_); 44689756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers basic_block_landing_pads_.resize(dex_compilation_unit_->GetCodeItem()->tries_size_, NULL); 447bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao basic_block_unwind_ = NULL; 448bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao for (llvm::Function::iterator bb_iter = func_->begin(), bb_end = func_->end(); 449bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao bb_iter != bb_end; 450bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao ++bb_iter) { 451bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao if (bb_iter->begin()->getMetadata("DexOff") == NULL) { 452bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao continue; 453bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao } 454bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao uint32_t dex_pc = LV2UInt(bb_iter->begin()->getMetadata("DexOff")->getOperand(0)); 455bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao basic_blocks_[dex_pc] = bb_iter; 456bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao } 457bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao 45867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Insert stack overflow check 4597934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom InsertStackOverflowCheck(func); // TODO: Use intrinsic. 46021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 46167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Rewrite the intrinsics 46267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien RewriteFunction(); 46321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 46467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien VERIFY_LLVM_FUNCTION(func); 46521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 46667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien return changed_; 46767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien} 46867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 46967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chienvoid GBCExpanderPass::RewriteBasicBlock(llvm::BasicBlock* original_block) { 47067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock* curr_basic_block = original_block; 47167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 47267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock::iterator inst_iter = original_block->begin(); 47367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock::iterator inst_end = original_block->end(); 47467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 47567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien while (inst_iter != inst_end) { 47667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::CallInst* call_inst = llvm::dyn_cast<llvm::CallInst>(inst_iter); 47767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien IntrinsicHelper::IntrinsicId intr_id = IntrinsicHelper::UnknownId; 47867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 47967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien if (call_inst) { 48067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::Function* callee_func = call_inst->getCalledFunction(); 48167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien intr_id = intrinsic_helper_.GetIntrinsicId(callee_func); 48221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 48321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 48467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien if (intr_id == IntrinsicHelper::UnknownId) { 48567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // This is not intrinsic call. Skip this instruction. 48667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien ++inst_iter; 48767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien continue; 48867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien } 48921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 49067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Rewrite the intrinsic and change the function 49167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien changed_ = true; 49267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien irb_.SetInsertPoint(inst_iter); 49321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 49467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Expand the intrinsic 49567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien if (llvm::Value* new_value = ExpandIntrinsic(intr_id, *call_inst)) { 49667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien inst_iter->replaceAllUsesWith(new_value); 49767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien } 49821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 49967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Remove the old intrinsic call instruction 50067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock::iterator old_inst = inst_iter++; 50167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien old_inst->eraseFromParent(); 50267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 50367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Splice the instruction to the new basic block 50467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock* next_basic_block = irb_.GetInsertBlock(); 50567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien if (next_basic_block != curr_basic_block) { 50667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien next_basic_block->getInstList().splice( 50767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien irb_.GetInsertPoint(), curr_basic_block->getInstList(), 50867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien inst_iter, inst_end); 50967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien curr_basic_block = next_basic_block; 51067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien inst_end = curr_basic_block->end(); 51167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien } 51267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien } 51367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien} 51421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 51521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 51667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chienvoid GBCExpanderPass::RewriteFunction() { 51767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien size_t num_basic_blocks = func_->getBasicBlockList().size(); 51867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // NOTE: We are not using (bb_iter != bb_end) as the for-loop condition, 51967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // because we will create new basic block while expanding the intrinsics. 52067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // We only want to iterate through the input basic blocks. 52121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 522aa55887fd30484a77e7775dfbcddbee883ce6380TDYa landing_pad_phi_mapping_.clear(); 523aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 52467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien for (llvm::Function::iterator bb_iter = func_->begin(); 52567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien num_basic_blocks > 0; ++bb_iter, --num_basic_blocks) { 526627d8c4ae50f22f628fe6a768f2924ee7e0029deShih-wei Liao // Set insert point to current basic block. 527627d8c4ae50f22f628fe6a768f2924ee7e0029deShih-wei Liao irb_.SetInsertPoint(bb_iter); 52867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 52955e5e6c5702e3f1f68bd83ae741af769740d9a74TDYa current_bb_ = bb_iter; 530aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 53167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Rewrite the basic block 53267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien RewriteBasicBlock(bb_iter); 53367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 53467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Update the phi-instructions in the successor basic block 53567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock* last_block = irb_.GetInsertBlock(); 53667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien if (last_block != bb_iter) { 53767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien UpdatePhiInstruction(bb_iter, last_block); 53821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 53967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien } 540aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 541aa55887fd30484a77e7775dfbcddbee883ce6380TDYa typedef std::map<llvm::PHINode*, llvm::PHINode*> HandlerPHIMap; 542aa55887fd30484a77e7775dfbcddbee883ce6380TDYa HandlerPHIMap handler_phi; 543aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // Iterate every used landing pad basic block 544aa55887fd30484a77e7775dfbcddbee883ce6380TDYa for (size_t i = 0, ei = basic_block_landing_pads_.size(); i != ei; ++i) { 545aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::BasicBlock* lbb = basic_block_landing_pads_[i]; 546aa55887fd30484a77e7775dfbcddbee883ce6380TDYa if (lbb == NULL) { 547aa55887fd30484a77e7775dfbcddbee883ce6380TDYa continue; 548aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 549aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 550aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::TerminatorInst* term_inst = lbb->getTerminator(); 551aa55887fd30484a77e7775dfbcddbee883ce6380TDYa std::vector<std::pair<llvm::BasicBlock*, llvm::BasicBlock*> >& rewrite_pair 552aa55887fd30484a77e7775dfbcddbee883ce6380TDYa = landing_pad_phi_mapping_[lbb]; 553aa55887fd30484a77e7775dfbcddbee883ce6380TDYa irb_.SetInsertPoint(lbb->begin()); 554aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 555aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // Iterate every succeeding basic block (catch block) 556aa55887fd30484a77e7775dfbcddbee883ce6380TDYa for (unsigned succ_iter = 0, succ_end = term_inst->getNumSuccessors(); 557aa55887fd30484a77e7775dfbcddbee883ce6380TDYa succ_iter != succ_end; ++succ_iter) { 558aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::BasicBlock* succ_basic_block = term_inst->getSuccessor(succ_iter); 559aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 560aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // Iterate every phi instructions in the succeeding basic block 561aa55887fd30484a77e7775dfbcddbee883ce6380TDYa for (llvm::BasicBlock::iterator 562aa55887fd30484a77e7775dfbcddbee883ce6380TDYa inst_iter = succ_basic_block->begin(), 563aa55887fd30484a77e7775dfbcddbee883ce6380TDYa inst_end = succ_basic_block->end(); 564aa55887fd30484a77e7775dfbcddbee883ce6380TDYa inst_iter != inst_end; ++inst_iter) { 565aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::PHINode *phi = llvm::dyn_cast<llvm::PHINode>(inst_iter); 566aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 567aa55887fd30484a77e7775dfbcddbee883ce6380TDYa if (!phi) { 5687934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom break; // Meet non-phi instruction. Done. 569aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 570aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 571aa55887fd30484a77e7775dfbcddbee883ce6380TDYa if (handler_phi[phi] == NULL) { 572aa55887fd30484a77e7775dfbcddbee883ce6380TDYa handler_phi[phi] = llvm::PHINode::Create(phi->getType(), 1); 573aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 574aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 575aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // Create new_phi in landing pad 576aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::PHINode* new_phi = irb_.CreatePHI(phi->getType(), rewrite_pair.size()); 577aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // Insert all incoming value into new_phi by rewrite_pair 578aa55887fd30484a77e7775dfbcddbee883ce6380TDYa for (size_t j = 0, ej = rewrite_pair.size(); j != ej; ++j) { 579aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::BasicBlock* old_bb = rewrite_pair[j].first; 580aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::BasicBlock* new_bb = rewrite_pair[j].second; 581aa55887fd30484a77e7775dfbcddbee883ce6380TDYa new_phi->addIncoming(phi->getIncomingValueForBlock(old_bb), new_bb); 582aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 583aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // Delete all incoming value from phi by rewrite_pair 584aa55887fd30484a77e7775dfbcddbee883ce6380TDYa for (size_t j = 0, ej = rewrite_pair.size(); j != ej; ++j) { 585aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::BasicBlock* old_bb = rewrite_pair[j].first; 586aa55887fd30484a77e7775dfbcddbee883ce6380TDYa int old_bb_idx = phi->getBasicBlockIndex(old_bb); 587aa55887fd30484a77e7775dfbcddbee883ce6380TDYa if (old_bb_idx >= 0) { 588aa55887fd30484a77e7775dfbcddbee883ce6380TDYa phi->removeIncomingValue(old_bb_idx, false); 589aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 590aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 591aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // Insert new_phi into new handler phi 592aa55887fd30484a77e7775dfbcddbee883ce6380TDYa handler_phi[phi]->addIncoming(new_phi, lbb); 593aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 594aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 595aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 596aa55887fd30484a77e7775dfbcddbee883ce6380TDYa 597aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // Replace all handler phi 598aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // We can't just use the old handler phi, because some exception edges will disappear after we 599aa55887fd30484a77e7775dfbcddbee883ce6380TDYa // compute fast-path. 600aa55887fd30484a77e7775dfbcddbee883ce6380TDYa for (HandlerPHIMap::iterator it = handler_phi.begin(); it != handler_phi.end(); ++it) { 601aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::PHINode* old_phi = it->first; 602aa55887fd30484a77e7775dfbcddbee883ce6380TDYa llvm::PHINode* new_phi = it->second; 603aa55887fd30484a77e7775dfbcddbee883ce6380TDYa new_phi->insertBefore(old_phi); 604aa55887fd30484a77e7775dfbcddbee883ce6380TDYa old_phi->replaceAllUsesWith(new_phi); 605aa55887fd30484a77e7775dfbcddbee883ce6380TDYa old_phi->eraseFromParent(); 606aa55887fd30484a77e7775dfbcddbee883ce6380TDYa } 60767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien} 60821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 60967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chienvoid GBCExpanderPass::UpdatePhiInstruction(llvm::BasicBlock* old_basic_block, 61067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock* new_basic_block) { 61167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::TerminatorInst* term_inst = new_basic_block->getTerminator(); 61267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 61367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien if (!term_inst) { 6147934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom return; // No terminating instruction in new_basic_block. Nothing to do. 61521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 61621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 61767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Iterate every succeeding basic block 61867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien for (unsigned succ_iter = 0, succ_end = term_inst->getNumSuccessors(); 61967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien succ_iter != succ_end; ++succ_iter) { 62067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock* succ_basic_block = term_inst->getSuccessor(succ_iter); 62167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 62267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Iterate every phi instructions in the succeeding basic block 62367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien for (llvm::BasicBlock::iterator 62467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien inst_iter = succ_basic_block->begin(), 62567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien inst_end = succ_basic_block->end(); 62667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien inst_iter != inst_end; ++inst_iter) { 62767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::PHINode *phi = llvm::dyn_cast<llvm::PHINode>(inst_iter); 62821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 62967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien if (!phi) { 6307934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom break; // Meet non-phi instruction. Done. 63167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien } 63267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 63367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Update the incoming block of this phi instruction 63467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien for (llvm::PHINode::block_iterator 63567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien ibb_iter = phi->block_begin(), ibb_end = phi->block_end(); 63667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien ibb_iter != ibb_end; ++ibb_iter) { 63767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien if (*ibb_iter == old_basic_block) { 63867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien *ibb_iter = new_basic_block; 63967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien } 64021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 64121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 64221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 64321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 64421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 6453e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromllvm::Value* GBCExpanderPass::ExpandToRuntime(RuntimeId rt, llvm::CallInst& inst) { 64621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Some GBC intrinsic can directly replace with IBC runtime. "Directly" means 64721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // the arguments passed to the GBC intrinsic are as the same as IBC runtime 64821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // function, therefore only called function is needed to change. 64921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao unsigned num_args = inst.getNumArgOperands(); 65021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 65121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao if (num_args <= 0) { 65221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.CreateCall(irb_.GetRuntime(rt)); 65321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } else { 65421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao std::vector<llvm::Value*> args; 65521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao for (unsigned i = 0; i < num_args; i++) { 65621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao args.push_back(inst.getArgOperand(i)); 65721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 65821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 65921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.CreateCall(irb_.GetRuntime(rt), args); 66021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 66121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 66221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 66367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chienvoid 66421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::EmitStackOverflowCheck(llvm::Instruction* first_non_alloca) { 66521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Function* func = first_non_alloca->getParent()->getParent(); 66621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Module* module = func->getParent(); 66721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 66821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Call llvm intrinsic function to get frame address. 66921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Function* frameaddress = 67021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Intrinsic::getDeclaration(module, llvm::Intrinsic::frameaddress); 67121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 67221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // The type of llvm::frameaddress is: i8* @llvm.frameaddress(i32) 67321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* frame_address = irb_.CreateCall(frameaddress, irb_.getInt32(0)); 67421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 67521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Cast i8* to int 67621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao frame_address = irb_.CreatePtrToInt(frame_address, irb_.getPtrEquivIntTy()); 67721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 67821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Get thread.stack_end_ 67921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* stack_end = 680920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa irb_.Runtime().EmitLoadFromThreadOffset(art::Thread::StackEndOffset().Int32Value(), 68121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getPtrEquivIntTy(), 68221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kTBAARuntimeInfo); 68321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 68421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Check the frame address < thread.stack_end_ ? 68521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* is_stack_overflow = irb_.CreateICmpULT(frame_address, stack_end); 68621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 68721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::BasicBlock* block_exception = 68821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::BasicBlock::Create(context_, "stack_overflow", func); 68921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 69021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::BasicBlock* block_continue = 69121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::BasicBlock::Create(context_, "stack_overflow_cont", func); 69221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 69321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateCondBr(is_stack_overflow, block_exception, block_continue, kUnlikely); 69421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 69521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // If stack overflow, throw exception. 69621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.SetInsertPoint(block_exception); 6973e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom irb_.CreateCall(irb_.GetRuntime(ThrowStackOverflowException)); 69821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 69921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Unwind. 70021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Type* ret_type = func->getReturnType(); 70121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao if (ret_type->isVoidTy()) { 70221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateRetVoid(); 70321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } else { 70421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // The return value is ignored when there's an exception. MethodCompiler 70521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // returns zero value under the the corresponding return type in this case. 70621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // GBCExpander returns LLVM undef value here for brevity 70721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateRet(llvm::UndefValue::get(ret_type)); 70821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 70921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 71021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.SetInsertPoint(block_continue); 71121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 71221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 713920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYallvm::Value* GBCExpanderPass::EmitLoadDexCacheAddr(art::MemberOffset offset) { 71421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 71521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 71621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.LoadFromObjectOffset(method_object_addr, 71721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao offset.Int32Value(), 71821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getJObjectTy(), 71921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kTBAAConstJObject); 72021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 72121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 72221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* 72321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::EmitLoadDexCacheStaticStorageFieldAddr(uint32_t type_idx) { 72421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* static_storage_dex_cache_addr = 725ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom EmitLoadDexCacheAddr(art::mirror::ArtMethod::DexCacheInitializedStaticStorageOffset()); 72621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 72721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* type_idx_value = irb_.getPtrEquivInt(type_idx); 72821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 72921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return EmitArrayGEP(static_storage_dex_cache_addr, type_idx_value, kObject); 73021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 73121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 73221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* 73321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::EmitLoadDexCacheResolvedTypeFieldAddr(uint32_t type_idx) { 73421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* resolved_type_dex_cache_addr = 735ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom EmitLoadDexCacheAddr(art::mirror::ArtMethod::DexCacheResolvedTypesOffset()); 73621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 73721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* type_idx_value = irb_.getPtrEquivInt(type_idx); 73821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 73921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return EmitArrayGEP(resolved_type_dex_cache_addr, type_idx_value, kObject); 74021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 74121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 74221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass:: 74321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoEmitLoadDexCacheResolvedMethodFieldAddr(uint32_t method_idx) { 74421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* resolved_method_dex_cache_addr = 745ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom EmitLoadDexCacheAddr(art::mirror::ArtMethod::DexCacheResolvedMethodsOffset()); 74621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 74721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* method_idx_value = irb_.getPtrEquivInt(method_idx); 74821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 74921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return EmitArrayGEP(resolved_method_dex_cache_addr, method_idx_value, kObject); 75021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 75121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 75221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass:: 75321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoEmitLoadDexCacheStringFieldAddr(uint32_t string_idx) { 75421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* string_dex_cache_addr = 755ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom EmitLoadDexCacheAddr(art::mirror::ArtMethod::DexCacheStringsOffset()); 75621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 75721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* string_idx_value = irb_.getPtrEquivInt(string_idx); 75821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 75921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return EmitArrayGEP(string_dex_cache_addr, string_idx_value, kObject); 76021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 76121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 76221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::EmitLoadMethodObjectAddr() { 76321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Function* parent_func = irb_.GetInsertBlock()->getParent(); 76421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return parent_func->arg_begin(); 76521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 76621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 76721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::EmitLoadArrayLength(llvm::Value* array) { 76821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Load array length 76921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.LoadFromObjectOffset(array, 77098573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers art::mirror::Array::LengthOffset().Int32Value(), 77121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getJIntTy(), 77221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kTBAAConstJObject); 77321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 77421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 77521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* 77621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::EmitLoadSDCalleeMethodObjectAddr(uint32_t callee_method_idx) { 77721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* callee_method_object_field_addr = 77821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao EmitLoadDexCacheResolvedMethodFieldAddr(callee_method_idx); 77921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 780ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa return irb_.CreateLoad(callee_method_object_field_addr, kTBAARuntimeInfo); 78121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 78221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 78321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass:: 78421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoEmitLoadVirtualCalleeMethodObjectAddr(int vtable_idx, llvm::Value* this_addr) { 78521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Load class object of *this* pointer 78621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* class_object_addr = 78721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.LoadFromObjectOffset(this_addr, 78898573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers art::mirror::Object::ClassOffset().Int32Value(), 78921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getJObjectTy(), 79021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kTBAAConstJObject); 79121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 79221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Load vtable address 79321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* vtable_addr = 79421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.LoadFromObjectOffset(class_object_addr, 79598573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers art::mirror::Class::VTableOffset().Int32Value(), 79621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getJObjectTy(), 79721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kTBAAConstJObject); 79821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 79921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Load callee method object 80021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* vtable_idx_value = 80121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getPtrEquivInt(static_cast<uint64_t>(vtable_idx)); 80221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 80321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* method_field_addr = 80421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao EmitArrayGEP(vtable_addr, vtable_idx_value, kObject); 80521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 80621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.CreateLoad(method_field_addr, kTBAAConstJObject); 80721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 80821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 80921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao// Emit Array GetElementPtr 81021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::EmitArrayGEP(llvm::Value* array_addr, 81121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* index_value, 81221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType elem_jty) { 81321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao int data_offset; 81421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao if (elem_jty == kLong || elem_jty == kDouble || 81598573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers (elem_jty == kObject && sizeof(uint64_t) == sizeof(art::mirror::Object*))) { 81698573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers data_offset = art::mirror::Array::DataOffset(sizeof(int64_t)).Int32Value(); 81721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } else { 81898573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers data_offset = art::mirror::Array::DataOffset(sizeof(int32_t)).Int32Value(); 81921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 82021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 82121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Constant* data_offset_value = 82221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getPtrEquivInt(data_offset); 82321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 82476ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers llvm::Type* elem_type = irb_.getJType(elem_jty); 82521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 82621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* array_data_addr = 82721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreatePtrDisp(array_addr, data_offset_value, 82821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao elem_type->getPointerTo()); 82921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 83021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.CreateGEP(array_data_addr, index_value); 83121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 83221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 833901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertzllvm::Value* GBCExpanderPass::EmitInvoke(llvm::CallInst& call_inst) { 834901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 835901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz art::InvokeType invoke_type = 836901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz static_cast<art::InvokeType>(LV2UInt(call_inst.getArgOperand(0))); 837901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz bool is_static = (invoke_type == art::kStatic); 83851c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom art::MethodReference target_method(dex_compilation_unit_->GetDexFile(), 83951c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom LV2UInt(call_inst.getArgOperand(1))); 840901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 841901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz // Load *this* actual parameter 842901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz llvm::Value* this_addr = (!is_static) ? call_inst.getArgOperand(3) : NULL; 843901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 844901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz // Compute invoke related information for compiler decision 845901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz int vtable_idx = -1; 846901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz uintptr_t direct_code = 0; 847901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz uintptr_t direct_method = 0; 848e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers bool is_fast_path = driver_->ComputeInvokeInfo(dex_compilation_unit_, dex_pc, 849e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers invoke_type, target_method, 850e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers vtable_idx, 851e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers direct_code, direct_method, 852e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers true); 853901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz // Load the method object 854901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz llvm::Value* callee_method_object_addr = NULL; 855901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 856901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz if (!is_fast_path) { 857901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz callee_method_object_addr = 858e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers EmitCallRuntimeForCalleeMethodObjectAddr(target_method.dex_method_index, invoke_type, 859901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz this_addr, dex_pc, is_fast_path); 860901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz } else { 861901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz switch (invoke_type) { 862901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz case art::kStatic: 863901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz case art::kDirect: 864901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz if (direct_method != 0u && 865901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz direct_method != static_cast<uintptr_t>(-1)) { 866901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz callee_method_object_addr = 867901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz irb_.CreateIntToPtr(irb_.getPtrEquivInt(direct_method), 868901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz irb_.getJObjectTy()); 869901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz } else { 870901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz callee_method_object_addr = 871e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers EmitLoadSDCalleeMethodObjectAddr(target_method.dex_method_index); 872901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz } 873901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz break; 874901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 875901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz case art::kVirtual: 8764274889d48ef82369bf2c1ca70d84689b4f9e93aBrian Carlstrom DCHECK_NE(vtable_idx, -1); 877901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz callee_method_object_addr = 878901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz EmitLoadVirtualCalleeMethodObjectAddr(vtable_idx, this_addr); 879901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz break; 880901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 881901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz case art::kSuper: 882901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz LOG(FATAL) << "invoke-super should be promoted to invoke-direct in " 883901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz "the fast path."; 884901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz break; 885901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 886901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz case art::kInterface: 887901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz callee_method_object_addr = 888e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers EmitCallRuntimeForCalleeMethodObjectAddr(target_method.dex_method_index, 889901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz invoke_type, this_addr, 890901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz dex_pc, is_fast_path); 891901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz break; 892901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz } 893901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz } 894901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 895901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz // Load the actual parameter 896901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz std::vector<llvm::Value*> args; 897901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 8987934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom args.push_back(callee_method_object_addr); // method object for callee 899901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 900901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz for (uint32_t i = 3; i < call_inst.getNumArgOperands(); ++i) { 901901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz args.push_back(call_inst.getArgOperand(i)); 902901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz } 903901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 904901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz llvm::Value* code_addr; 905901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz llvm::Type* func_type = GetFunctionType(call_inst.getType(), 906e3cd2f0e3c3d976ae9c65c8a731003a5aaf71986Ian Rogers target_method.dex_method_index, is_static); 907901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz if (direct_code != 0u && direct_code != static_cast<uintptr_t>(-1)) { 908901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz code_addr = 909901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz irb_.CreateIntToPtr(irb_.getPtrEquivInt(direct_code), 910901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz func_type->getPointerTo()); 911901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz } else { 912901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz code_addr = 913901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz irb_.LoadFromObjectOffset(callee_method_object_addr, 914ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom art::mirror::ArtMethod::GetEntryPointFromCompiledCodeOffset().Int32Value(), 915901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz func_type->getPointerTo(), kTBAARuntimeInfo); 916901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz } 917901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 918901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz // Invoke callee 919901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz EmitUpdateDexPC(dex_pc); 920901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz llvm::Value* retval = irb_.CreateCall(code_addr, args); 921901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz EmitGuard_ExceptionLandingPad(dex_pc); 922901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 923901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz return retval; 924901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz} 925901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 926901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertzbool GBCExpanderPass::EmitIntrinsic(llvm::CallInst& call_inst, 927901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz llvm::Value** result) { 928901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz DCHECK(result != NULL); 929901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 930901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz uint32_t callee_method_idx = LV2UInt(call_inst.getArgOperand(1)); 931901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz std::string callee_method_name( 932901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz PrettyMethod(callee_method_idx, *dex_compilation_unit_->GetDexFile())); 933901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 934901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz if (callee_method_name == "int java.lang.String.length()") { 935901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz return EmitIntrinsicStringLengthOrIsEmpty(call_inst, result, 936901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz false /* is_empty */); 937901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz } 938901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz if (callee_method_name == "boolean java.lang.String.isEmpty()") { 939901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz return EmitIntrinsicStringLengthOrIsEmpty(call_inst, result, 940901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz true /* is_empty */); 941901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz } 942901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 943901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz *result = NULL; 944901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz return false; 945901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz} 946901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 947901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertzbool GBCExpanderPass::EmitIntrinsicStringLengthOrIsEmpty(llvm::CallInst& call_inst, 948901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz llvm::Value** result, 949901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz bool is_empty) { 950901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz art::InvokeType invoke_type = 951901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz static_cast<art::InvokeType>(LV2UInt(call_inst.getArgOperand(0))); 952901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz DCHECK_NE(invoke_type, art::kStatic); 953901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz DCHECK_EQ(call_inst.getNumArgOperands(), 4U); 954901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 955901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz llvm::Value* this_object = call_inst.getArgOperand(3); 956901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz llvm::Value* string_count = 957901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz irb_.LoadFromObjectOffset(this_object, 958901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz art::mirror::String::CountOffset().Int32Value(), 959901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz irb_.getJIntTy(), 960901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz kTBAAConstJObject); 961901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz if (is_empty) { 962901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz llvm::Value* count_equals_zero = irb_.CreateICmpEQ(string_count, 963901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz irb_.getJInt(0)); 964901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz llvm::Value* is_empty = irb_.CreateSelect(count_equals_zero, 965901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz irb_.getJBoolean(true), 966901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz irb_.getJBoolean(false)); 967901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz is_empty = SignOrZeroExtendCat1Types(is_empty, kBoolean); 968901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz *result = is_empty; 969901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz } else { 970901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz *result = string_count; 971901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz } 972901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz return true; 973901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz} 974901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz 97521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_TestSuspend(llvm::CallInst& call_inst) { 976ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 977ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa 978ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa llvm::Value* suspend_count = 979ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa irb_.Runtime().EmitLoadFromThreadOffset(art::Thread::ThreadFlagsOffset().Int32Value(), 980ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa irb_.getInt16Ty(), 981ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa kTBAARuntimeInfo); 982ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa llvm::Value* is_suspend = irb_.CreateICmpNE(suspend_count, irb_.getInt16(0)); 983ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa 984ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa llvm::BasicBlock* basic_block_suspend = CreateBasicBlockWithDexPC(dex_pc, "suspend"); 985ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa llvm::BasicBlock* basic_block_cont = CreateBasicBlockWithDexPC(dex_pc, "suspend_cont"); 986ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa 987ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa irb_.CreateCondBr(is_suspend, basic_block_suspend, basic_block_cont, kUnlikely); 988ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa 989ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa irb_.SetInsertPoint(basic_block_suspend); 990ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa if (dex_pc != art::DexFile::kDexNoIndex) { 991ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa EmitUpdateDexPC(dex_pc); 992ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa } 99321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.Runtime().EmitTestSuspend(); 99411ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao 99511ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao llvm::BasicBlock* basic_block_exception = CreateBasicBlockWithDexPC(dex_pc, "exception"); 99611ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao llvm::Value* exception_pending = irb_.Runtime().EmitIsExceptionPending(); 99711ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao irb_.CreateCondBr(exception_pending, basic_block_exception, basic_block_cont, kUnlikely); 99811ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao 99911ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao irb_.SetInsertPoint(basic_block_exception); 100011ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao llvm::Type* ret_type = call_inst.getParent()->getParent()->getReturnType(); 100111ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao if (ret_type->isVoidTy()) { 100211ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao irb_.CreateRetVoid(); 100311ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao } else { 100411ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao // The return value is ignored when there's an exception. 100511ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao irb_.CreateRet(llvm::UndefValue::get(ret_type)); 100611ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao } 1007ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa 1008ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa irb_.SetInsertPoint(basic_block_cont); 100921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 101021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 101121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 10129a129457c233b653c7a8f65c963509267252b0a7TDYavoid GBCExpanderPass::Expand_MarkGCCard(llvm::CallInst& call_inst) { 10139a129457c233b653c7a8f65c963509267252b0a7TDYa irb_.Runtime().EmitMarkGCCard(call_inst.getArgOperand(0), call_inst.getArgOperand(1)); 10149a129457c233b653c7a8f65c963509267252b0a7TDYa return; 10159a129457c233b653c7a8f65c963509267252b0a7TDYa} 10169a129457c233b653c7a8f65c963509267252b0a7TDYa 101721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* 101821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::Expand_LoadStringFromDexCache(llvm::Value* string_idx_value) { 101921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao uint32_t string_idx = 102021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(string_idx_value)->getZExtValue(); 102121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 102221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* string_field_addr = EmitLoadDexCacheStringFieldAddr(string_idx); 102321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 1024ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa return irb_.CreateLoad(string_field_addr, kTBAARuntimeInfo); 102521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 102621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 102721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* 102821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::Expand_LoadTypeFromDexCache(llvm::Value* type_idx_value) { 102921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao uint32_t type_idx = 103021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(type_idx_value)->getZExtValue(); 103121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 103221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* type_field_addr = 103321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao EmitLoadDexCacheResolvedTypeFieldAddr(type_idx); 103421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 1035ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa return irb_.CreateLoad(type_field_addr, kTBAARuntimeInfo); 103621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 103721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 103821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_LockObject(llvm::Value* obj) { 103921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao rtb_.EmitLockObject(obj); 104021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 104121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 104221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 104321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_UnlockObject(llvm::Value* obj) { 104421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao rtb_.EmitUnlockObject(obj); 104521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 104621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 104721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 104821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::Expand_ArrayGet(llvm::Value* array_addr, 104921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* index_value, 105021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType elem_jty) { 105121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* array_elem_addr = 105221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao EmitArrayGEP(array_addr, index_value, elem_jty); 105321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 105421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.CreateLoad(array_elem_addr, kTBAAHeapArray, elem_jty); 105521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 105621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 105721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_ArrayPut(llvm::Value* new_value, 105821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* array_addr, 105921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* index_value, 106021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType elem_jty) { 106121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* array_elem_addr = 106221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao EmitArrayGEP(array_addr, index_value, elem_jty); 106321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 106421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateStore(new_value, array_elem_addr, kTBAAHeapArray, elem_jty); 106521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 106621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 106721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 106821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 106921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_FilledNewArray(llvm::CallInst& call_inst) { 107021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Most of the codes refer to MethodCompiler::EmitInsn_FilledNewArray 107121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* array = call_inst.getArgOperand(0); 107221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 107321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao uint32_t element_jty = 107421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(call_inst.getArgOperand(1))->getZExtValue(); 107521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 10764274889d48ef82369bf2c1ca70d84689b4f9e93aBrian Carlstrom DCHECK_GT(call_inst.getNumArgOperands(), 2U); 107721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao unsigned num_elements = (call_inst.getNumArgOperands() - 2); 107821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 107921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao bool is_elem_int_ty = (static_cast<JType>(element_jty) == kInt); 108021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 108121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao uint32_t alignment; 108221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Constant* elem_size; 108321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::PointerType* field_type; 108421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 108521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // NOTE: Currently filled-new-array only supports 'L', '[', and 'I' 108621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // as the element, thus we are only checking 2 cases: primitive int and 108721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // non-primitive type. 108821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao if (is_elem_int_ty) { 108921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao alignment = sizeof(int32_t); 109021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao elem_size = irb_.getPtrEquivInt(sizeof(int32_t)); 109121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao field_type = irb_.getJIntTy()->getPointerTo(); 109221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } else { 109321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao alignment = irb_.getSizeOfPtrEquivInt(); 109421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao elem_size = irb_.getSizeOfPtrEquivIntValue(); 109521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao field_type = irb_.getJObjectTy()->getPointerTo(); 109621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 109721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 109821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* data_field_offset = 109998573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers irb_.getPtrEquivInt(art::mirror::Array::DataOffset(alignment).Int32Value()); 110021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 110121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* data_field_addr = 110221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreatePtrDisp(array, data_field_offset, field_type); 110321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 110421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao for (unsigned i = 0; i < num_elements; ++i) { 110521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Values to fill the array begin at the 3rd argument 110621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* reg_value = call_inst.getArgOperand(2 + i); 110721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 110821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateStore(reg_value, data_field_addr, kTBAAHeapArray); 110921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 111021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao data_field_addr = 111121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreatePtrDisp(data_field_addr, elem_size, field_type); 111221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 111321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 111421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 111521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 111621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 111721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::Expand_IGetFast(llvm::Value* field_offset_value, 111821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* /*is_volatile_value*/, 111921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* object_addr, 112021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType field_jty) { 112121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao int field_offset = 112221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue(); 112321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 112421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao DCHECK_GE(field_offset, 0); 112521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 112621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::PointerType* field_type = 112776ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers irb_.getJType(field_jty)->getPointerTo(); 112821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 112921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao field_offset_value = irb_.getPtrEquivInt(field_offset); 113021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 113121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* field_addr = 113221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreatePtrDisp(object_addr, field_offset_value, field_type); 113321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 113421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // TODO: Check is_volatile. We need to generate atomic load instruction 113521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // when is_volatile is true. 113621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.CreateLoad(field_addr, kTBAAHeapInstance, field_jty); 113721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 113821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 113921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_IPutFast(llvm::Value* field_offset_value, 114021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* /* is_volatile_value */, 114121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* object_addr, 114221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* new_value, 114321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType field_jty) { 114421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao int field_offset = 114521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue(); 114621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 114721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao DCHECK_GE(field_offset, 0); 114821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 114921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::PointerType* field_type = 115076ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers irb_.getJType(field_jty)->getPointerTo(); 115121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 115221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao field_offset_value = irb_.getPtrEquivInt(field_offset); 115321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 115421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* field_addr = 115521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreatePtrDisp(object_addr, field_offset_value, field_type); 115621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 115721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // TODO: Check is_volatile. We need to generate atomic store instruction 115821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // when is_volatile is true. 115921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateStore(new_value, field_addr, kTBAAHeapInstance, field_jty); 116021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 116121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 116221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 116321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 116421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::Expand_SGetFast(llvm::Value* static_storage_addr, 116521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* field_offset_value, 116621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* /*is_volatile_value*/, 116721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType field_jty) { 116821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao int field_offset = 116921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue(); 117021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 117121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao DCHECK_GE(field_offset, 0); 117221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 117321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset); 117421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 117521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* static_field_addr = 117621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value, 117776ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers irb_.getJType(field_jty)->getPointerTo()); 117821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 117921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // TODO: Check is_volatile. We need to generate atomic store instruction 118021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // when is_volatile is true. 118121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.CreateLoad(static_field_addr, kTBAAHeapStatic, field_jty); 118221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 118321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 118421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_SPutFast(llvm::Value* static_storage_addr, 118521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* field_offset_value, 118621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* /* is_volatile_value */, 118721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* new_value, 118821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao JType field_jty) { 118921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao int field_offset = 119021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue(); 119121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 119221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao DCHECK_GE(field_offset, 0); 119321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 119421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset); 119521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 119621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* static_field_addr = 119721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value, 119876ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers irb_.getJType(field_jty)->getPointerTo()); 119921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 120021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // TODO: Check is_volatile. We need to generate atomic store instruction 120121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // when is_volatile is true. 120221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateStore(new_value, static_field_addr, kTBAAHeapStatic, field_jty); 120321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 120421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 120521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 120621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 120721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* 120821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::Expand_LoadDeclaringClassSSB(llvm::Value* method_object_addr) { 120921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.LoadFromObjectOffset(method_object_addr, 1210ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom art::mirror::ArtMethod::DeclaringClassOffset().Int32Value(), 121121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.getJObjectTy(), 121221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kTBAAConstJObject); 121321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 121421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 121521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* 121621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::Expand_LoadClassSSBFromDexCache(llvm::Value* type_idx_value) { 121721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao uint32_t type_idx = 121821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(type_idx_value)->getZExtValue(); 121921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 122021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* storage_field_addr = 122121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao EmitLoadDexCacheStaticStorageFieldAddr(type_idx); 122221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 1223ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa return irb_.CreateLoad(storage_field_addr, kTBAARuntimeInfo); 122421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 122521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 122621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* 122721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::Expand_GetSDCalleeMethodObjAddrFast(llvm::Value* callee_method_idx_value) { 122821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao uint32_t callee_method_idx = 122921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(callee_method_idx_value)->getZExtValue(); 123021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 123121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return EmitLoadSDCalleeMethodObjectAddr(callee_method_idx); 123221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 123321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 123421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::Expand_GetVirtualCalleeMethodObjAddrFast( 123521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* vtable_idx_value, 123621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* this_addr) { 123721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao int vtable_idx = 123821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::cast<llvm::ConstantInt>(vtable_idx_value)->getSExtValue(); 123921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 124021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return EmitLoadVirtualCalleeMethodObjectAddr(vtable_idx, this_addr); 124121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 124221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 124321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* GBCExpanderPass::Expand_Invoke(llvm::CallInst& call_inst) { 124421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Most of the codes refer to MethodCompiler::EmitInsn_Invoke 124521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* callee_method_object_addr = call_inst.getArgOperand(0); 124621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao unsigned num_args = call_inst.getNumArgOperands(); 124721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Type* ret_type = call_inst.getType(); 124821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 124921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Determine the function type of the callee method 125021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao std::vector<llvm::Type*> args_type; 125121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao std::vector<llvm::Value*> args; 125221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao for (unsigned i = 0; i < num_args; i++) { 125321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao args.push_back(call_inst.getArgOperand(i)); 125421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao args_type.push_back(args[i]->getType()); 125521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 125621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 125721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::FunctionType* callee_method_type = 125821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::FunctionType::get(ret_type, args_type, false); 125921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 126021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* code_addr = 126121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.LoadFromObjectOffset(callee_method_object_addr, 1262ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom art::mirror::ArtMethod::GetEntryPointFromCompiledCodeOffset().Int32Value(), 126321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao callee_method_type->getPointerTo(), 1264ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa kTBAARuntimeInfo); 126521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 126621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Invoke callee 126721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* retval = irb_.CreateCall(code_addr, args); 126821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 126921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return retval; 127021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 127121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 12724ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYallvm::Value* GBCExpanderPass::Expand_DivRem(llvm::CallInst& call_inst, 127321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao bool is_div, JType op_jty) { 12744ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa llvm::Value* dividend = call_inst.getArgOperand(0); 12754ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa llvm::Value* divisor = call_inst.getArgOperand(1); 12764ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 12774ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa EmitGuard_DivZeroException(dex_pc, divisor, op_jty); 127821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Most of the codes refer to MethodCompiler::EmitIntDivRemResultComputation 127921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 128021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Check the special case: MININT / -1 = MININT 128121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // That case will cause overflow, which is undefined behavior in llvm. 128221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // So we check the divisor is -1 or not, if the divisor is -1, we do 128321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // the special path to avoid undefined behavior. 128476ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers llvm::Type* op_type = irb_.getJType(op_jty); 128521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* zero = irb_.getJZero(op_jty); 128621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* neg_one = llvm::ConstantInt::getSigned(op_type, -1); 128721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 12885e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Function* parent = irb_.GetInsertBlock()->getParent(); 128921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::BasicBlock* eq_neg_one = llvm::BasicBlock::Create(context_, "", parent); 129021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::BasicBlock* ne_neg_one = llvm::BasicBlock::Create(context_, "", parent); 129121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::BasicBlock* neg_one_cont = 129221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::BasicBlock::Create(context_, "", parent); 129321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 129421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* is_equal_neg_one = irb_.CreateICmpEQ(divisor, neg_one); 129521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateCondBr(is_equal_neg_one, eq_neg_one, ne_neg_one, kUnlikely); 129621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 129721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // If divisor == -1 129821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.SetInsertPoint(eq_neg_one); 129921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* eq_result; 130021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao if (is_div) { 130121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // We can just change from "dividend div -1" to "neg dividend". The sub 130221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // don't care the sign/unsigned because of two's complement representation. 130321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // And the behavior is what we want: 130421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // -(2^n) (2^n)-1 130521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // MININT < k <= MAXINT -> mul k -1 = -k 130621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // MININT == k -> mul k -1 = k 130721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // 130821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // LLVM use sub to represent 'neg' 130921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao eq_result = irb_.CreateSub(zero, dividend); 131021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } else { 131121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Everything modulo -1 will be 0. 131221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao eq_result = zero; 131321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 131421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateBr(neg_one_cont); 131521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 131621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // If divisor != -1, just do the division. 131721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.SetInsertPoint(ne_neg_one); 131821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* ne_result; 131921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao if (is_div) { 132021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao ne_result = irb_.CreateSDiv(dividend, divisor); 132121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } else { 132221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao ne_result = irb_.CreateSRem(dividend, divisor); 132321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 132421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateBr(neg_one_cont); 132521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 132621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.SetInsertPoint(neg_one_cont); 132721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::PHINode* result = irb_.CreatePHI(op_type, 2); 132821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao result->addIncoming(eq_result, eq_neg_one); 132921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao result->addIncoming(ne_result, ne_neg_one); 133021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 133121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return result; 133221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 133321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 1334ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYavoid GBCExpanderPass::Expand_AllocaShadowFrame(llvm::Value* num_vregs_value) { 133521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Most of the codes refer to MethodCompiler::EmitPrologueAllocShadowFrame and 133621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // MethodCompiler::EmitPushShadowFrame 13378e950c117975d23f50ed7e32ca5db01a813c25d0TDYa uint16_t num_vregs = 13388e950c117975d23f50ed7e32ca5db01a813c25d0TDYa llvm::cast<llvm::ConstantInt>(num_vregs_value)->getZExtValue(); 133921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 134021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::StructType* shadow_frame_type = 1341ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa irb_.getShadowFrameTy(num_vregs); 134221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 1343772097020befc5b45d81d1604c897d60e7de56feSebastien Hertz // Create allocas at the start of entry block. 1344772097020befc5b45d81d1604c897d60e7de56feSebastien Hertz llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP(); 1345772097020befc5b45d81d1604c897d60e7de56feSebastien Hertz llvm::BasicBlock* entry_block = &func_->front(); 1346772097020befc5b45d81d1604c897d60e7de56feSebastien Hertz irb_.SetInsertPoint(&entry_block->front()); 1347772097020befc5b45d81d1604c897d60e7de56feSebastien Hertz 134821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao shadow_frame_ = irb_.CreateAlloca(shadow_frame_type); 134921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 135021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Alloca a pointer to old shadow frame 135121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao old_shadow_frame_ = 135221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateAlloca(shadow_frame_type->getElementType(0)->getPointerTo()); 135321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 1354772097020befc5b45d81d1604c897d60e7de56feSebastien Hertz irb_.restoreIP(irb_ip_original); 1355772097020befc5b45d81d1604c897d60e7de56feSebastien Hertz 135621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Push the shadow frame 135721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 135821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 135921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* shadow_frame_upcast = 136021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateConstGEP2_32(shadow_frame_, 0, 0); 136121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 136221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::Value* result = rtb_.EmitPushShadowFrame(shadow_frame_upcast, 136321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao method_object_addr, 13648e950c117975d23f50ed7e32ca5db01a813c25d0TDYa num_vregs); 136521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 136621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.CreateStore(result, old_shadow_frame_, kTBAARegister); 136721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 136821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 136921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 137021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 13718e950c117975d23f50ed7e32ca5db01a813c25d0TDYavoid GBCExpanderPass::Expand_SetVReg(llvm::Value* entry_idx, 13728e950c117975d23f50ed7e32ca5db01a813c25d0TDYa llvm::Value* value) { 1373f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz unsigned vreg_idx = LV2UInt(entry_idx); 1374f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz DCHECK_LT(vreg_idx, dex_compilation_unit_->GetCodeItem()->registers_size_); 1375f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz 1376f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz llvm::Value* vreg_addr = shadow_frame_vreg_addresses_[vreg_idx]; 1377f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz if (UNLIKELY(vreg_addr == NULL)) { 1378f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz DCHECK(shadow_frame_ != NULL); 1379f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz 1380f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz llvm::Value* gep_index[] = { 13817934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom irb_.getInt32(0), // No pointer displacement 13827934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom irb_.getInt32(1), // VRegs 13837934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom entry_idx // Pointer field 1384f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz }; 1385f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz 1386f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz // A shadow frame address must dominate every use in the function so we 1387f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz // place it in the entry block right after the allocas. 1388f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz llvm::BasicBlock::iterator first_non_alloca = func_->getEntryBlock().begin(); 1389f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz while (llvm::isa<llvm::AllocaInst>(first_non_alloca)) { 1390f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz ++first_non_alloca; 1391f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz } 13928e950c117975d23f50ed7e32ca5db01a813c25d0TDYa 1393f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz llvm::IRBuilderBase::InsertPoint ip = irb_.saveIP(); 1394f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz irb_.SetInsertPoint(static_cast<llvm::Instruction*>(first_non_alloca)); 1395f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz vreg_addr = irb_.CreateGEP(shadow_frame_, gep_index); 1396f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz shadow_frame_vreg_addresses_[vreg_idx] = vreg_addr; 1397f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz irb_.restoreIP(ip); 1398f11afa079d5899b9ff74d2cad507cfa8c7324690Sebastien Hertz } 13998e950c117975d23f50ed7e32ca5db01a813c25d0TDYa 14008e950c117975d23f50ed7e32ca5db01a813c25d0TDYa irb_.CreateStore(value, 14018e950c117975d23f50ed7e32ca5db01a813c25d0TDYa irb_.CreateBitCast(vreg_addr, value->getType()->getPointerTo()), 14028e950c117975d23f50ed7e32ca5db01a813c25d0TDYa kTBAAShadowFrame); 14038e950c117975d23f50ed7e32ca5db01a813c25d0TDYa return; 14048e950c117975d23f50ed7e32ca5db01a813c25d0TDYa} 14058e950c117975d23f50ed7e32ca5db01a813c25d0TDYa 140621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_PopShadowFrame() { 1407bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao if (old_shadow_frame_ == NULL) { 1408bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao return; 1409bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao } 141021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao rtb_.EmitPopShadowFrame(irb_.CreateLoad(old_shadow_frame_, kTBAARegister)); 141121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 141221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 141321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 141421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaovoid GBCExpanderPass::Expand_UpdateDexPC(llvm::Value* dex_pc_value) { 141521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao irb_.StoreToObjectOffset(shadow_frame_, 1416920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::ShadowFrame::DexPCOffset(), 141721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao dex_pc_value, 141821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kTBAAShadowFrame); 141921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return; 142021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 142121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 142267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chienvoid GBCExpanderPass::InsertStackOverflowCheck(llvm::Function& func) { 14234028312f6f4b49fd69992daf28cd37dd32e79a47jeffhao // All alloca instructions are generated in the first basic block of the 14244028312f6f4b49fd69992daf28cd37dd32e79a47jeffhao // function, and there are no alloca instructions after the first non-alloca 14254028312f6f4b49fd69992daf28cd37dd32e79a47jeffhao // instruction. 142621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 142767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock* first_basic_block = &func.front(); 142867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 142967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Look for first non-alloca instruction 143067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock::iterator first_non_alloca = first_basic_block->begin(); 143121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao while (llvm::isa<llvm::AllocaInst>(first_non_alloca)) { 143221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao ++first_non_alloca; 143321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 143421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 143567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien irb_.SetInsertPoint(first_non_alloca); 143667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 143721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // Insert stack overflow check codes before first_non_alloca (i.e., after all 143821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao // alloca instructions) 143967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien EmitStackOverflowCheck(&*first_non_alloca); 144067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 1441890ea89879ba555a08433146058d516575646c59TDYa irb_.Runtime().EmitTestSuspend(); 1442890ea89879ba555a08433146058d516575646c59TDYa 144367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien llvm::BasicBlock* next_basic_block = irb_.GetInsertBlock(); 144467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien if (next_basic_block != first_basic_block) { 144567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Splice the rest of the instruction to the continuing basic block 144667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien next_basic_block->getInstList().splice( 144767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien irb_.GetInsertPoint(), first_basic_block->getInstList(), 144867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien first_non_alloca, first_basic_block->end()); 144967645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 145067645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Rewrite the basic block 145167645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien RewriteBasicBlock(next_basic_block); 145267645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 145367645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // Update the phi-instructions in the successor basic block 145467645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien UpdatePhiInstruction(first_basic_block, irb_.GetInsertBlock()); 145567645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien } 145667645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien 145767645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien // We have changed the basic block 145867645d87ea0367b9601e7967fa8809e4be9bde7cLogan Chien changed_ = true; 145921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao} 146021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 14615e869b6560f918837cc6be3a50234deb2be46385TDYa// ==== High-level intrinsic expander ========================================== 14625e869b6560f918837cc6be3a50234deb2be46385TDYa 1463a1b2185820e6080864d18a35759cc046dc4ee578TDYallvm::Value* GBCExpanderPass::Expand_FPCompare(llvm::Value* src1_value, 1464a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* src2_value, 1465a1b2185820e6080864d18a35759cc046dc4ee578TDYa bool gt_bias) { 1466a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* cmp_eq = irb_.CreateFCmpOEQ(src1_value, src2_value); 1467a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* cmp_lt; 1468a1b2185820e6080864d18a35759cc046dc4ee578TDYa 1469a1b2185820e6080864d18a35759cc046dc4ee578TDYa if (gt_bias) { 1470a1b2185820e6080864d18a35759cc046dc4ee578TDYa cmp_lt = irb_.CreateFCmpOLT(src1_value, src2_value); 1471a1b2185820e6080864d18a35759cc046dc4ee578TDYa } else { 1472a1b2185820e6080864d18a35759cc046dc4ee578TDYa cmp_lt = irb_.CreateFCmpULT(src1_value, src2_value); 1473a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 1474a1b2185820e6080864d18a35759cc046dc4ee578TDYa 1475a1b2185820e6080864d18a35759cc046dc4ee578TDYa return EmitCompareResultSelection(cmp_eq, cmp_lt); 1476a1b2185820e6080864d18a35759cc046dc4ee578TDYa} 1477a1b2185820e6080864d18a35759cc046dc4ee578TDYa 1478a1b2185820e6080864d18a35759cc046dc4ee578TDYallvm::Value* GBCExpanderPass::Expand_LongCompare(llvm::Value* src1_value, llvm::Value* src2_value) { 1479a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* cmp_eq = irb_.CreateICmpEQ(src1_value, src2_value); 1480a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* cmp_lt = irb_.CreateICmpSLT(src1_value, src2_value); 1481a1b2185820e6080864d18a35759cc046dc4ee578TDYa 1482a1b2185820e6080864d18a35759cc046dc4ee578TDYa return EmitCompareResultSelection(cmp_eq, cmp_lt); 1483a1b2185820e6080864d18a35759cc046dc4ee578TDYa} 1484a1b2185820e6080864d18a35759cc046dc4ee578TDYa 1485a1b2185820e6080864d18a35759cc046dc4ee578TDYallvm::Value* GBCExpanderPass::EmitCompareResultSelection(llvm::Value* cmp_eq, 1486a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* cmp_lt) { 1487a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Constant* zero = irb_.getJInt(0); 1488a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Constant* pos1 = irb_.getJInt(1); 1489a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Constant* neg1 = irb_.getJInt(-1); 1490a1b2185820e6080864d18a35759cc046dc4ee578TDYa 1491a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* result_lt = irb_.CreateSelect(cmp_lt, neg1, pos1); 1492a1b2185820e6080864d18a35759cc046dc4ee578TDYa llvm::Value* result_eq = irb_.CreateSelect(cmp_eq, zero, result_lt); 1493a1b2185820e6080864d18a35759cc046dc4ee578TDYa 1494a1b2185820e6080864d18a35759cc046dc4ee578TDYa return result_eq; 1495a1b2185820e6080864d18a35759cc046dc4ee578TDYa} 1496a1b2185820e6080864d18a35759cc046dc4ee578TDYa 149775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chienllvm::Value* GBCExpanderPass::Expand_IntegerShift(llvm::Value* src1_value, 149875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien llvm::Value* src2_value, 149975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien IntegerShiftKind kind, 150075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien JType op_jty) { 150175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien DCHECK(op_jty == kInt || op_jty == kLong); 150275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 150375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien // Mask and zero-extend RHS properly 150475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien if (op_jty == kInt) { 150575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien src2_value = irb_.CreateAnd(src2_value, 0x1f); 150675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } else { 150775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien llvm::Value* masked_src2_value = irb_.CreateAnd(src2_value, 0x3f); 150875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien src2_value = irb_.CreateZExt(masked_src2_value, irb_.getJLongTy()); 150975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 151075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 151175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien // Create integer shift llvm instruction 151275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien switch (kind) { 151375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case kIntegerSHL: 151475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return irb_.CreateShl(src1_value, src2_value); 151575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 151675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case kIntegerSHR: 151775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return irb_.CreateAShr(src1_value, src2_value); 151875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 151975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case kIntegerUSHR: 152075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return irb_.CreateLShr(src1_value, src2_value); 152175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 152275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien default: 152375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien LOG(FATAL) << "Unknown integer shift kind: " << kind; 152475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 152575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 152675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien} 152775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 152876ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogersllvm::Value* GBCExpanderPass::SignOrZeroExtendCat1Types(llvm::Value* value, JType jty) { 152976ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers switch (jty) { 153076ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kBoolean: 153176ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kChar: 153276ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers return irb_.CreateZExt(value, irb_.getJType(kInt)); 153376ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kByte: 153476ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kShort: 153576ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers return irb_.CreateSExt(value, irb_.getJType(kInt)); 153676ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kVoid: 153776ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kInt: 153876ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kLong: 153976ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kFloat: 154076ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kDouble: 154176ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kObject: 154276ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers return value; // Nothing to do. 154376ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers default: 154476ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers LOG(FATAL) << "Unknown java type: " << jty; 154576ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers return NULL; 154676ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers } 154776ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers} 154876ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers 154976ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogersllvm::Value* GBCExpanderPass::TruncateCat1Types(llvm::Value* value, JType jty) { 155076ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers switch (jty) { 155176ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kBoolean: 155276ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kChar: 155376ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kByte: 155476ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kShort: 155576ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers return irb_.CreateTrunc(value, irb_.getJType(jty)); 155676ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kVoid: 155776ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kInt: 155876ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kLong: 155976ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kFloat: 156076ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kDouble: 156176ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers case kObject: 156276ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers return value; // Nothing to do. 156376ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers default: 156476ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers LOG(FATAL) << "Unknown java type: " << jty; 156576ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers return NULL; 156676ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers } 156776ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers} 156876ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers 15695a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYallvm::Value* GBCExpanderPass::Expand_HLArrayGet(llvm::CallInst& call_inst, 15705a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa JType elem_jty) { 15715a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 15725a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* array_addr = call_inst.getArgOperand(1); 15735a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* index_value = call_inst.getArgOperand(2); 1574920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 15755a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 15762ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz EmitGuard_NullPointerException(dex_pc, array_addr, opt_flags); 15772ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz EmitGuard_ArrayIndexOutOfBoundsException(dex_pc, array_addr, index_value, 15782ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz opt_flags); 15795a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 15805a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* array_elem_addr = EmitArrayGEP(array_addr, index_value, elem_jty); 15815a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 15825a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* array_elem_value = irb_.CreateLoad(array_elem_addr, kTBAAHeapArray, elem_jty); 15835a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 158476ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers return SignOrZeroExtendCat1Types(array_elem_value, elem_jty); 15855a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa} 15865a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 15875a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 15885a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYavoid GBCExpanderPass::Expand_HLArrayPut(llvm::CallInst& call_inst, 15895a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa JType elem_jty) { 15905a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 15915a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* new_value = call_inst.getArgOperand(1); 15925a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* array_addr = call_inst.getArgOperand(2); 15935a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* index_value = call_inst.getArgOperand(3); 1594920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 15955a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 15962ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz EmitGuard_NullPointerException(dex_pc, array_addr, opt_flags); 15972ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz EmitGuard_ArrayIndexOutOfBoundsException(dex_pc, array_addr, index_value, 15982ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz opt_flags); 15995a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 160076ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers new_value = TruncateCat1Types(new_value, elem_jty); 16015a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16025a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* array_elem_addr = EmitArrayGEP(array_addr, index_value, elem_jty); 16035a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16047934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom if (elem_jty == kObject) { // If put an object, check the type, and mark GC card table. 16053e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom llvm::Function* runtime_func = irb_.GetRuntime(CheckPutArrayElement); 16065a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16075a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreateCall2(runtime_func, new_value, array_addr); 16085a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16095a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitGuard_ExceptionLandingPad(dex_pc); 16105a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16115a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitMarkGCCard(new_value, array_addr); 16125a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 16135a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16145a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreateStore(new_value, array_elem_addr, kTBAAHeapArray, elem_jty); 16155a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16165a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return; 16175a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa} 16185a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 16195e869b6560f918837cc6be3a50234deb2be46385TDYallvm::Value* GBCExpanderPass::Expand_HLIGet(llvm::CallInst& call_inst, 16205e869b6560f918837cc6be3a50234deb2be46385TDYa JType field_jty) { 16215e869b6560f918837cc6be3a50234deb2be46385TDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 16225e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* object_addr = call_inst.getArgOperand(1); 16235e869b6560f918837cc6be3a50234deb2be46385TDYa uint32_t field_idx = LV2UInt(call_inst.getArgOperand(2)); 1624920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 16255e869b6560f918837cc6be3a50234deb2be46385TDYa 16262ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz EmitGuard_NullPointerException(dex_pc, object_addr, opt_flags); 16275e869b6560f918837cc6be3a50234deb2be46385TDYa 16285e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* field_value; 16295e869b6560f918837cc6be3a50234deb2be46385TDYa 16305e869b6560f918837cc6be3a50234deb2be46385TDYa int field_offset; 16315e869b6560f918837cc6be3a50234deb2be46385TDYa bool is_volatile; 16321212a022fa5f8ef9585d765b1809521812af882cIan Rogers bool is_fast_path = driver_->ComputeInstanceFieldInfo( 163389756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers field_idx, dex_compilation_unit_, field_offset, is_volatile, false); 16345e869b6560f918837cc6be3a50234deb2be46385TDYa 16355e869b6560f918837cc6be3a50234deb2be46385TDYa if (!is_fast_path) { 16365e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Function* runtime_func; 16375e869b6560f918837cc6be3a50234deb2be46385TDYa 16385e869b6560f918837cc6be3a50234deb2be46385TDYa if (field_jty == kObject) { 16393e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(GetObjectInstance); 16405e869b6560f918837cc6be3a50234deb2be46385TDYa } else if (field_jty == kLong || field_jty == kDouble) { 16413e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(Get64Instance); 16425e869b6560f918837cc6be3a50234deb2be46385TDYa } else { 16433e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(Get32Instance); 16445e869b6560f918837cc6be3a50234deb2be46385TDYa } 16455e869b6560f918837cc6be3a50234deb2be46385TDYa 16465e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::ConstantInt* field_idx_value = irb_.getInt32(field_idx); 16475e869b6560f918837cc6be3a50234deb2be46385TDYa 16485e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 16495e869b6560f918837cc6be3a50234deb2be46385TDYa 16505e869b6560f918837cc6be3a50234deb2be46385TDYa EmitUpdateDexPC(dex_pc); 16515e869b6560f918837cc6be3a50234deb2be46385TDYa 16525e869b6560f918837cc6be3a50234deb2be46385TDYa field_value = irb_.CreateCall3(runtime_func, field_idx_value, 16535e869b6560f918837cc6be3a50234deb2be46385TDYa method_object_addr, object_addr); 16545e869b6560f918837cc6be3a50234deb2be46385TDYa 16555e869b6560f918837cc6be3a50234deb2be46385TDYa EmitGuard_ExceptionLandingPad(dex_pc); 16565e869b6560f918837cc6be3a50234deb2be46385TDYa 16571b2b71f2079bacc26f48b8ce0ebd142b13e63b99Ian Rogers if (field_jty == kFloat || field_jty == kDouble) { 16581b2b71f2079bacc26f48b8ce0ebd142b13e63b99Ian Rogers field_value = irb_.CreateBitCast(field_value, irb_.getJType(field_jty)); 16591b2b71f2079bacc26f48b8ce0ebd142b13e63b99Ian Rogers } 16605e869b6560f918837cc6be3a50234deb2be46385TDYa } else { 16615e869b6560f918837cc6be3a50234deb2be46385TDYa DCHECK_GE(field_offset, 0); 16625e869b6560f918837cc6be3a50234deb2be46385TDYa 16635e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::PointerType* field_type = 166476ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers irb_.getJType(field_jty)->getPointerTo(); 16655e869b6560f918837cc6be3a50234deb2be46385TDYa 16665e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::ConstantInt* field_offset_value = irb_.getPtrEquivInt(field_offset); 16675e869b6560f918837cc6be3a50234deb2be46385TDYa 16685e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* field_addr = 16695e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreatePtrDisp(object_addr, field_offset_value, field_type); 16705e869b6560f918837cc6be3a50234deb2be46385TDYa 16715e869b6560f918837cc6be3a50234deb2be46385TDYa field_value = irb_.CreateLoad(field_addr, kTBAAHeapInstance, field_jty); 167276ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers field_value = SignOrZeroExtendCat1Types(field_value, field_jty); 16734b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz 16744b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz if (is_volatile) { 16754b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz irb_.CreateMemoryBarrier(art::kLoadLoad); 16764b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz } 16775e869b6560f918837cc6be3a50234deb2be46385TDYa } 16785e869b6560f918837cc6be3a50234deb2be46385TDYa 16795e869b6560f918837cc6be3a50234deb2be46385TDYa return field_value; 16805e869b6560f918837cc6be3a50234deb2be46385TDYa} 16815e869b6560f918837cc6be3a50234deb2be46385TDYa 16825e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::Expand_HLIPut(llvm::CallInst& call_inst, 16835e869b6560f918837cc6be3a50234deb2be46385TDYa JType field_jty) { 16845e869b6560f918837cc6be3a50234deb2be46385TDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 1685bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao llvm::Value* new_value = call_inst.getArgOperand(1); 1686bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao llvm::Value* object_addr = call_inst.getArgOperand(2); 16875e869b6560f918837cc6be3a50234deb2be46385TDYa uint32_t field_idx = LV2UInt(call_inst.getArgOperand(3)); 1688920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 16895e869b6560f918837cc6be3a50234deb2be46385TDYa 16902ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz EmitGuard_NullPointerException(dex_pc, object_addr, opt_flags); 16915e869b6560f918837cc6be3a50234deb2be46385TDYa 16925e869b6560f918837cc6be3a50234deb2be46385TDYa int field_offset; 16935e869b6560f918837cc6be3a50234deb2be46385TDYa bool is_volatile; 16941212a022fa5f8ef9585d765b1809521812af882cIan Rogers bool is_fast_path = driver_->ComputeInstanceFieldInfo( 169589756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers field_idx, dex_compilation_unit_, field_offset, is_volatile, true); 16965e869b6560f918837cc6be3a50234deb2be46385TDYa 16975e869b6560f918837cc6be3a50234deb2be46385TDYa if (!is_fast_path) { 16985e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Function* runtime_func; 16995e869b6560f918837cc6be3a50234deb2be46385TDYa 17001b2b71f2079bacc26f48b8ce0ebd142b13e63b99Ian Rogers if (field_jty == kFloat) { 17011b2b71f2079bacc26f48b8ce0ebd142b13e63b99Ian Rogers new_value = irb_.CreateBitCast(new_value, irb_.getJType(kInt)); 17021b2b71f2079bacc26f48b8ce0ebd142b13e63b99Ian Rogers } else if (field_jty == kDouble) { 17031b2b71f2079bacc26f48b8ce0ebd142b13e63b99Ian Rogers new_value = irb_.CreateBitCast(new_value, irb_.getJType(kLong)); 17041b2b71f2079bacc26f48b8ce0ebd142b13e63b99Ian Rogers } 17051b2b71f2079bacc26f48b8ce0ebd142b13e63b99Ian Rogers 17065e869b6560f918837cc6be3a50234deb2be46385TDYa if (field_jty == kObject) { 17073e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(SetObjectInstance); 17085e869b6560f918837cc6be3a50234deb2be46385TDYa } else if (field_jty == kLong || field_jty == kDouble) { 17093e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(Set64Instance); 17105e869b6560f918837cc6be3a50234deb2be46385TDYa } else { 17113e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(Set32Instance); 17125e869b6560f918837cc6be3a50234deb2be46385TDYa } 17135e869b6560f918837cc6be3a50234deb2be46385TDYa 17145e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* field_idx_value = irb_.getInt32(field_idx); 17155e869b6560f918837cc6be3a50234deb2be46385TDYa 17165e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 17175e869b6560f918837cc6be3a50234deb2be46385TDYa 17185e869b6560f918837cc6be3a50234deb2be46385TDYa EmitUpdateDexPC(dex_pc); 17195e869b6560f918837cc6be3a50234deb2be46385TDYa 17205e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateCall4(runtime_func, field_idx_value, 17215e869b6560f918837cc6be3a50234deb2be46385TDYa method_object_addr, object_addr, new_value); 17225e869b6560f918837cc6be3a50234deb2be46385TDYa 17235e869b6560f918837cc6be3a50234deb2be46385TDYa EmitGuard_ExceptionLandingPad(dex_pc); 17245e869b6560f918837cc6be3a50234deb2be46385TDYa 17255e869b6560f918837cc6be3a50234deb2be46385TDYa } else { 17265e869b6560f918837cc6be3a50234deb2be46385TDYa DCHECK_GE(field_offset, 0); 17275e869b6560f918837cc6be3a50234deb2be46385TDYa 17284b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz if (is_volatile) { 17294b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz irb_.CreateMemoryBarrier(art::kStoreStore); 17304b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz } 17314b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz 17325e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::PointerType* field_type = 173376ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers irb_.getJType(field_jty)->getPointerTo(); 17345e869b6560f918837cc6be3a50234deb2be46385TDYa 17355e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* field_offset_value = irb_.getPtrEquivInt(field_offset); 17365e869b6560f918837cc6be3a50234deb2be46385TDYa 17375e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* field_addr = 17385e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreatePtrDisp(object_addr, field_offset_value, field_type); 17395e869b6560f918837cc6be3a50234deb2be46385TDYa 174076ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers new_value = TruncateCat1Types(new_value, field_jty); 17415e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateStore(new_value, field_addr, kTBAAHeapInstance, field_jty); 17425e869b6560f918837cc6be3a50234deb2be46385TDYa 17434b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz if (is_volatile) { 17444b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz irb_.CreateMemoryBarrier(art::kLoadLoad); 17454b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz } 17464b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz 17477934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom if (field_jty == kObject) { // If put an object, mark the GC card table. 17485e869b6560f918837cc6be3a50234deb2be46385TDYa EmitMarkGCCard(new_value, object_addr); 17495e869b6560f918837cc6be3a50234deb2be46385TDYa } 17505e869b6560f918837cc6be3a50234deb2be46385TDYa } 17515e869b6560f918837cc6be3a50234deb2be46385TDYa 17525e869b6560f918837cc6be3a50234deb2be46385TDYa return; 17535e869b6560f918837cc6be3a50234deb2be46385TDYa} 17545e869b6560f918837cc6be3a50234deb2be46385TDYa 1755f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::EmitLoadConstantClass(uint32_t dex_pc, 1756f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_idx) { 175789756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers if (!driver_->CanAccessTypeWithoutChecks(dex_compilation_unit_->GetDexMethodIndex(), 175889756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers *dex_compilation_unit_->GetDexFile(), type_idx)) { 1759f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* type_idx_value = irb_.getInt32(type_idx); 1760f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1761f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 1762f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1763f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread(); 1764f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 17653e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom llvm::Function* runtime_func = irb_.GetRuntime(InitializeTypeAndVerifyAccess); 1766f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1767f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 1768f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1769f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* type_object_addr = 1770f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCall3(runtime_func, type_idx_value, method_object_addr, thread_object_addr); 1771f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1772f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 1773f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1774f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return type_object_addr; 1775f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1776f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } else { 1777f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Try to load the class (type) object from the test cache. 1778f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* type_field_addr = 1779f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitLoadDexCacheResolvedTypeFieldAddr(type_idx); 1780f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1781ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa llvm::Value* type_object_addr = irb_.CreateLoad(type_field_addr, kTBAARuntimeInfo); 1782f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 178389756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers if (driver_->CanAssumeTypeIsPresentInDexCache(*dex_compilation_unit_->GetDexFile(), type_idx)) { 1784f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return type_object_addr; 1785f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 1786f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1787f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_original = irb_.GetInsertBlock(); 1788f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1789f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Test whether class (type) object is in the dex cache or not 1790f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* equal_null = 1791f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateICmpEQ(type_object_addr, irb_.getJNull()); 1792f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1793f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_cont = 1794f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "cont"); 1795f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1796f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_load_class = 1797f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "load_class"); 1798f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1799f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCondBr(equal_null, block_load_class, block_cont, kUnlikely); 1800f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1801f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Failback routine to load the class object 1802f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_load_class); 1803f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 18043e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom llvm::Function* runtime_func = irb_.GetRuntime(InitializeType); 1805f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1806f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Constant* type_idx_value = irb_.getInt32(type_idx); 1807f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1808f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 1809f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1810f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread(); 1811f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1812f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 1813f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1814f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* loaded_type_object_addr = 1815f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCall3(runtime_func, type_idx_value, method_object_addr, thread_object_addr); 1816f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1817f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 1818f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1819f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_after_load_class = irb_.GetInsertBlock(); 1820f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1821f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateBr(block_cont); 1822f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1823f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Now the class object must be loaded 1824f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_cont); 1825f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1826f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::PHINode* phi = irb_.CreatePHI(irb_.getJObjectTy(), 2); 1827f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1828f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa phi->addIncoming(type_object_addr, block_original); 1829f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa phi->addIncoming(loaded_type_object_addr, block_after_load_class); 1830f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 1831f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return phi; 1832f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 1833f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 1834f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 18355a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYallvm::Value* GBCExpanderPass::EmitLoadStaticStorage(uint32_t dex_pc, 18365a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa uint32_t type_idx) { 18375a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::BasicBlock* block_load_static = 18385a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa CreateBasicBlockWithDexPC(dex_pc, "load_static"); 18395a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18405a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::BasicBlock* block_cont = CreateBasicBlockWithDexPC(dex_pc, "cont"); 18415a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18425a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // Load static storage from dex cache 18435a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* storage_field_addr = 18445a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitLoadDexCacheStaticStorageFieldAddr(type_idx); 18455a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 1846ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa llvm::Value* storage_object_addr = irb_.CreateLoad(storage_field_addr, kTBAARuntimeInfo); 18475a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18485a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::BasicBlock* block_original = irb_.GetInsertBlock(); 18495a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18505a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // Test: Is the static storage of this class initialized? 18515a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* equal_null = 18525a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreateICmpEQ(storage_object_addr, irb_.getJNull()); 18535a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18545a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreateCondBr(equal_null, block_load_static, block_cont, kUnlikely); 18555a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18565a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // Failback routine to load the class object 18575a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.SetInsertPoint(block_load_static); 18585a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18593e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom llvm::Function* runtime_func = irb_.GetRuntime(InitializeStaticStorage); 18605a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18615a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Constant* type_idx_value = irb_.getInt32(type_idx); 18625a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18635a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 18645a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18655a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread(); 18665a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18675a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitUpdateDexPC(dex_pc); 18685a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18695a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* loaded_storage_object_addr = 18705a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreateCall3(runtime_func, type_idx_value, method_object_addr, thread_object_addr); 18715a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18725a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitGuard_ExceptionLandingPad(dex_pc); 18735a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18745a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::BasicBlock* block_after_load_static = irb_.GetInsertBlock(); 18755a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18765a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreateBr(block_cont); 18775a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18785a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // Now the class object must be loaded 18795a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.SetInsertPoint(block_cont); 18805a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18815a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::PHINode* phi = irb_.CreatePHI(irb_.getJObjectTy(), 2); 18825a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18835a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa phi->addIncoming(storage_object_addr, block_original); 18845a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa phi->addIncoming(loaded_storage_object_addr, block_after_load_static); 18855a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18865a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return phi; 18875a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa} 18885a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18895a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYallvm::Value* GBCExpanderPass::Expand_HLSget(llvm::CallInst& call_inst, 18905a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa JType field_jty) { 18915a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 18925a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa uint32_t field_idx = LV2UInt(call_inst.getArgOperand(0)); 18935a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18945a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa int field_offset; 18955a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa int ssb_index; 18965a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa bool is_referrers_class; 18975a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa bool is_volatile; 18985a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 18991212a022fa5f8ef9585d765b1809521812af882cIan Rogers bool is_fast_path = driver_->ComputeStaticFieldInfo( 190089756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers field_idx, dex_compilation_unit_, field_offset, ssb_index, 19015a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa is_referrers_class, is_volatile, false); 19025a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19035a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* static_field_value; 19045a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19055a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa if (!is_fast_path) { 19065a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Function* runtime_func; 19075a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19085a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa if (field_jty == kObject) { 19093e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(GetObjectStatic); 19105a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } else if (field_jty == kLong || field_jty == kDouble) { 19113e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(Get64Static); 19125a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } else { 19133e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(Get32Static); 19145a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 19155a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19165a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Constant* field_idx_value = irb_.getInt32(field_idx); 19175a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19185a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 19195a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19205a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitUpdateDexPC(dex_pc); 19215a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19225a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa static_field_value = 19235a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreateCall2(runtime_func, field_idx_value, method_object_addr); 19245a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19255a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitGuard_ExceptionLandingPad(dex_pc); 19265a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19271b2b71f2079bacc26f48b8ce0ebd142b13e63b99Ian Rogers if (field_jty == kFloat || field_jty == kDouble) { 19281b2b71f2079bacc26f48b8ce0ebd142b13e63b99Ian Rogers static_field_value = irb_.CreateBitCast(static_field_value, irb_.getJType(field_jty)); 19291b2b71f2079bacc26f48b8ce0ebd142b13e63b99Ian Rogers } 19305a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } else { 19315a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa DCHECK_GE(field_offset, 0); 19325a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19335a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* static_storage_addr = NULL; 19345a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19355a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa if (is_referrers_class) { 19365a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // Fast path, static storage base is this method's class 19375a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 19385a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19395a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa static_storage_addr = 19405a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.LoadFromObjectOffset(method_object_addr, 1941ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom art::mirror::ArtMethod::DeclaringClassOffset().Int32Value(), 19425a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.getJObjectTy(), 19435a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa kTBAAConstJObject); 19445a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } else { 19455a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // Medium path, static storage base in a different class which 19465a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // requires checks that the other class is initialized 19475a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa DCHECK_GE(ssb_index, 0); 19485a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa static_storage_addr = EmitLoadStaticStorage(dex_pc, ssb_index); 19495a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 19505a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19515a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset); 19525a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19535a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* static_field_addr = 19545a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value, 195576ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers irb_.getJType(field_jty)->getPointerTo()); 19565a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19575a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa static_field_value = irb_.CreateLoad(static_field_addr, kTBAAHeapStatic, field_jty); 195876ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers static_field_value = SignOrZeroExtendCat1Types(static_field_value, field_jty); 19594b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz 19604b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz if (is_volatile) { 19614b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz irb_.CreateMemoryBarrier(art::kLoadLoad); 19624b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz } 19635a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 19645a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19655a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return static_field_value; 19665a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa} 19675a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19685a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYavoid GBCExpanderPass::Expand_HLSput(llvm::CallInst& call_inst, 19695a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa JType field_jty) { 19705a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 19715a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa uint32_t field_idx = LV2UInt(call_inst.getArgOperand(0)); 19725a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* new_value = call_inst.getArgOperand(1); 19735a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19745a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa if (field_jty == kFloat || field_jty == kDouble) { 197576ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers new_value = irb_.CreateBitCast(new_value, irb_.getJType(field_jty)); 19765a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 19775a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19785a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa int field_offset; 19795a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa int ssb_index; 19805a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa bool is_referrers_class; 19815a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa bool is_volatile; 19825a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19831212a022fa5f8ef9585d765b1809521812af882cIan Rogers bool is_fast_path = driver_->ComputeStaticFieldInfo( 198489756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers field_idx, dex_compilation_unit_, field_offset, ssb_index, 19855a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa is_referrers_class, is_volatile, true); 19865a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19875a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa if (!is_fast_path) { 19885a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Function* runtime_func; 19895a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19905a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa if (field_jty == kObject) { 19913e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(SetObjectStatic); 19925a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } else if (field_jty == kLong || field_jty == kDouble) { 19933e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(Set64Static); 19945a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } else { 19953e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(Set32Static); 19965a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 19975a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 19981b2b71f2079bacc26f48b8ce0ebd142b13e63b99Ian Rogers if (field_jty == kFloat) { 19991b2b71f2079bacc26f48b8ce0ebd142b13e63b99Ian Rogers new_value = irb_.CreateBitCast(new_value, irb_.getJType(kInt)); 20001b2b71f2079bacc26f48b8ce0ebd142b13e63b99Ian Rogers } else if (field_jty == kDouble) { 20011b2b71f2079bacc26f48b8ce0ebd142b13e63b99Ian Rogers new_value = irb_.CreateBitCast(new_value, irb_.getJType(kLong)); 20021b2b71f2079bacc26f48b8ce0ebd142b13e63b99Ian Rogers } 20031b2b71f2079bacc26f48b8ce0ebd142b13e63b99Ian Rogers 20045a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Constant* field_idx_value = irb_.getInt32(field_idx); 20055a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 20065a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 20075a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 20085a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitUpdateDexPC(dex_pc); 20095a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 20105a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreateCall3(runtime_func, field_idx_value, 20115a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa method_object_addr, new_value); 20125a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 20135a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitGuard_ExceptionLandingPad(dex_pc); 20145a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 20155a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } else { 20165a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa DCHECK_GE(field_offset, 0); 20175a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 20185a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* static_storage_addr = NULL; 20195a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 20205a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa if (is_referrers_class) { 20215a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // Fast path, static storage base is this method's class 20225a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 20235a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 20245a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa static_storage_addr = 20255a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.LoadFromObjectOffset(method_object_addr, 2026ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom art::mirror::ArtMethod::DeclaringClassOffset().Int32Value(), 20275a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.getJObjectTy(), 20285a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa kTBAAConstJObject); 20295a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } else { 20305a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // Medium path, static storage base in a different class which 20315a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa // requires checks that the other class is initialized 20325a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa DCHECK_GE(ssb_index, 0); 20335a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa static_storage_addr = EmitLoadStaticStorage(dex_pc, ssb_index); 20345a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 20355a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 20364b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz if (is_volatile) { 20374b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz irb_.CreateMemoryBarrier(art::kStoreStore); 20384b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz } 20394b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz 20405a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset); 20415a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 20425a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa llvm::Value* static_field_addr = 20435a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value, 204476ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers irb_.getJType(field_jty)->getPointerTo()); 20455a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 204676ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers new_value = TruncateCat1Types(new_value, field_jty); 20475a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa irb_.CreateStore(new_value, static_field_addr, kTBAAHeapStatic, field_jty); 20485a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 20494b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz if (is_volatile) { 20504b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz irb_.CreateMemoryBarrier(art::kStoreLoad); 20514b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz } 20524b2e0b05686857c9a8b34c5b2325634cca2fdeeeSebastien Hertz 20537934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom if (field_jty == kObject) { // If put an object, mark the GC card table. 20545a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa EmitMarkGCCard(new_value, static_storage_addr); 20555a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 20565a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa } 20575a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 20585a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return; 20595a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa} 20605a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa 2061f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_ConstString(llvm::CallInst& call_inst) { 2062f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2063f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t string_idx = LV2UInt(call_inst.getArgOperand(0)); 2064f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2065f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* string_field_addr = EmitLoadDexCacheStringFieldAddr(string_idx); 2066f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2067ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa llvm::Value* string_addr = irb_.CreateLoad(string_field_addr, kTBAARuntimeInfo); 2068f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 206989756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers if (!driver_->CanAssumeStringIsPresentInDexCache(*dex_compilation_unit_->GetDexFile(), 207089756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers string_idx)) { 2071f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_str_exist = 2072f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "str_exist"); 2073f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2074f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_str_resolve = 2075f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "str_resolve"); 2076f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2077f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_cont = 2078f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "str_cont"); 2079f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2080f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Test: Is the string resolved and in the dex cache? 2081f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* equal_null = irb_.CreateICmpEQ(string_addr, irb_.getJNull()); 2082f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2083f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCondBr(equal_null, block_str_resolve, block_str_exist, kUnlikely); 2084f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2085f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // String is resolved, go to next basic block. 2086f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_str_exist); 2087f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateBr(block_cont); 2088f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2089f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // String is not resolved yet, resolve it now. 2090f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_str_resolve); 2091f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 20923e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom llvm::Function* runtime_func = irb_.GetRuntime(ResolveString); 2093f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2094f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 2095f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2096f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* string_idx_value = irb_.getInt32(string_idx); 2097f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2098f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 2099f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2100f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* result = irb_.CreateCall2(runtime_func, method_object_addr, 2101f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa string_idx_value); 2102f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2103f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 2104f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2105bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao irb_.CreateBr(block_cont); 2106bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao 2107bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao 2108f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_pre_cont = irb_.GetInsertBlock(); 2109f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2110f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_cont); 2111f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2112f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::PHINode* phi = irb_.CreatePHI(irb_.getJObjectTy(), 2); 2113f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2114f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa phi->addIncoming(string_addr, block_str_exist); 2115f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa phi->addIncoming(result, block_pre_cont); 2116f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2117f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa string_addr = phi; 2118f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2119f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2120f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return string_addr; 2121f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2122f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2123f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_ConstClass(llvm::CallInst& call_inst) { 2124f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2125f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0)); 2126f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2127f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, type_idx); 2128f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2129f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return type_object_addr; 2130f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2131f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2132f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYavoid GBCExpanderPass::Expand_MonitorEnter(llvm::CallInst& call_inst) { 2133f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2134f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_addr = call_inst.getArgOperand(1); 2135920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 2136f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 21372ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz EmitGuard_NullPointerException(dex_pc, object_addr, opt_flags); 2138f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2139ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa EmitUpdateDexPC(dex_pc); 2140ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa 2141f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.Runtime().EmitLockObject(object_addr); 2142f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2143f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return; 2144f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2145f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2146f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYavoid GBCExpanderPass::Expand_MonitorExit(llvm::CallInst& call_inst) { 2147f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2148f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_addr = call_inst.getArgOperand(1); 2149920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 2150f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 21512ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz EmitGuard_NullPointerException(dex_pc, object_addr, opt_flags); 2152f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2153f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 2154f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2155f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.Runtime().EmitUnlockObject(object_addr); 2156f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2157f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 2158f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2159f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return; 2160f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2161f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2162f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYavoid GBCExpanderPass::Expand_HLCheckCast(llvm::CallInst& call_inst) { 2163f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2164f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0)); 2165f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_addr = call_inst.getArgOperand(1); 2166f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2167f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_test_class = 2168f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "test_class"); 2169f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2170f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_test_sub_class = 2171f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "test_sub_class"); 2172f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2173f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_cont = 2174f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "checkcast_cont"); 2175f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2176f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Test: Is the reference equal to null? Act as no-op when it is null. 2177f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* equal_null = irb_.CreateICmpEQ(object_addr, irb_.getJNull()); 2178f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 21798e6960569e9de6350d7da89aa02efe0e4b924d6fIan Rogers irb_.CreateCondBr(equal_null, block_cont, block_test_class, kUnlikely); 2180f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2181f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Test: Is the object instantiated from the given class? 2182f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_test_class); 2183f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, type_idx); 218498573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers DCHECK_EQ(art::mirror::Object::ClassOffset().Int32Value(), 0); 2185f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2186f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::PointerType* jobject_ptr_ty = irb_.getJObjectTy(); 2187f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2188f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_type_field_addr = 2189f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateBitCast(object_addr, jobject_ptr_ty->getPointerTo()); 2190f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2191f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_type_object_addr = 2192f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateLoad(object_type_field_addr, kTBAAConstJObject); 2193f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2194f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* equal_class = 2195f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateICmpEQ(type_object_addr, object_type_object_addr); 2196f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 21978e6960569e9de6350d7da89aa02efe0e4b924d6fIan Rogers irb_.CreateCondBr(equal_class, block_cont, block_test_sub_class, kLikely); 2198f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2199f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Test: Is the object instantiated from the subclass of the given class? 2200f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_test_sub_class); 2201f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2202f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 2203f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 22043e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom irb_.CreateCall2(irb_.GetRuntime(CheckCast), 2205f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa type_object_addr, object_type_object_addr); 2206f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2207f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 2208f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2209f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateBr(block_cont); 2210f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2211f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_cont); 2212f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2213f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return; 2214f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2215f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2216f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_InstanceOf(llvm::CallInst& call_inst) { 2217f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2218f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0)); 2219f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_addr = call_inst.getArgOperand(1); 2220f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2221f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_nullp = 2222f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "nullp"); 2223f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2224f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_test_class = 2225f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "test_class"); 2226f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2227f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_class_equals = 2228f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "class_eq"); 2229f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2230f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_test_sub_class = 2231f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "test_sub_class"); 2232f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2233f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::BasicBlock* block_cont = 2234f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa CreateBasicBlockWithDexPC(dex_pc, "instance_of_cont"); 2235f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2236f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Overview of the following code : 2237f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // We check for null, if so, then false, otherwise check for class == . If so 2238f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // then true, otherwise do callout slowpath. 2239f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // 2240f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Test: Is the reference equal to null? Set 0 when it is null. 2241f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* equal_null = irb_.CreateICmpEQ(object_addr, irb_.getJNull()); 2242f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 22438e6960569e9de6350d7da89aa02efe0e4b924d6fIan Rogers irb_.CreateCondBr(equal_null, block_nullp, block_test_class, kUnlikely); 2244f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2245f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_nullp); 2246f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateBr(block_cont); 2247f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2248f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Test: Is the object instantiated from the given class? 2249f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_test_class); 2250f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, type_idx); 225198573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers DCHECK_EQ(art::mirror::Object::ClassOffset().Int32Value(), 0); 2252f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2253f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::PointerType* jobject_ptr_ty = irb_.getJObjectTy(); 2254f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2255f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_type_field_addr = 2256f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateBitCast(object_addr, jobject_ptr_ty->getPointerTo()); 2257f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2258f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_type_object_addr = 2259f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateLoad(object_type_field_addr, kTBAAConstJObject); 2260f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2261f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* equal_class = 2262f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateICmpEQ(type_object_addr, object_type_object_addr); 2263f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 22648e6960569e9de6350d7da89aa02efe0e4b924d6fIan Rogers irb_.CreateCondBr(equal_class, block_class_equals, block_test_sub_class, kLikely); 2265f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2266f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_class_equals); 2267f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateBr(block_cont); 2268f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2269f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Test: Is the object instantiated from the subclass of the given class? 2270f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_test_sub_class); 2271f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* result = 22723e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom irb_.CreateCall2(irb_.GetRuntime(IsAssignable), 2273f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa type_object_addr, object_type_object_addr); 2274f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateBr(block_cont); 2275f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2276f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.SetInsertPoint(block_cont); 2277f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2278f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::PHINode* phi = irb_.CreatePHI(irb_.getJIntTy(), 3); 2279f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2280f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa phi->addIncoming(irb_.getJInt(0), block_nullp); 2281f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa phi->addIncoming(irb_.getJInt(1), block_class_equals); 2282f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa phi->addIncoming(result, block_test_sub_class); 2283f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2284f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return phi; 2285f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2286f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2287f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_NewInstance(llvm::CallInst& call_inst) { 2288f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2289f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0)); 2290f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2291f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Function* runtime_func; 229289756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers if (driver_->CanAccessInstantiableTypeWithoutChecks(dex_compilation_unit_->GetDexMethodIndex(), 229389756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers *dex_compilation_unit_->GetDexFile(), 229489756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers type_idx)) { 22953e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(AllocObject); 2296f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } else { 22973e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(AllocObjectWithAccessCheck); 2298f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2299f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2300f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Constant* type_index_value = irb_.getInt32(type_idx); 2301f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2302f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 2303f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2304f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread(); 2305f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2306f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 2307f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2308f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_addr = 2309f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCall3(runtime_func, type_index_value, method_object_addr, thread_object_addr); 2310f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2311f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 2312f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2313f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return object_addr; 2314f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2315f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2316f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_HLInvoke(llvm::CallInst& call_inst) { 2317920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::InvokeType invoke_type = static_cast<art::InvokeType>(LV2UInt(call_inst.getArgOperand(0))); 2318920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa bool is_static = (invoke_type == art::kStatic); 2319f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2320f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa if (!is_static) { 2321f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Test: Is *this* parameter equal to null? 2322901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2323901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz llvm::Value* this_addr = call_inst.getArgOperand(3); 2324901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz int opt_flags = LV2UInt(call_inst.getArgOperand(2)); 2325f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2326901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz EmitGuard_NullPointerException(dex_pc, this_addr, opt_flags); 2327f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2328f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2329901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz llvm::Value* result = NULL; 2330901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz if (EmitIntrinsic(call_inst, &result)) { 2331901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz return result; 2332f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2333f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2334901d5bafa63629792c697273f2fde66eae89b1c9Sebastien Hertz return EmitInvoke(call_inst); 2335f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2336f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2337f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_OptArrayLength(llvm::CallInst& call_inst) { 2338f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2339f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Get the array object address 2340f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* array_addr = call_inst.getArgOperand(1); 2341920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 2342f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 23432ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz EmitGuard_NullPointerException(dex_pc, array_addr, opt_flags); 2344f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2345f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Get the array length and store it to the register 2346f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return EmitLoadArrayLength(array_addr); 2347f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2348f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2349f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_NewArray(llvm::CallInst& call_inst) { 2350f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2351f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0)); 2352f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* length = call_inst.getArgOperand(1); 2353f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2354f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return EmitAllocNewArray(dex_pc, length, type_idx, false); 2355f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2356f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2357f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::Expand_HLFilledNewArray(llvm::CallInst& call_inst) { 2358f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2359f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_idx = LV2UInt(call_inst.getArgOperand(1)); 2360f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t length = call_inst.getNumArgOperands() - 3; 2361f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2362f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_addr = 2363f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitAllocNewArray(dex_pc, irb_.getInt32(length), type_idx, true); 2364f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2365f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa if (length > 0) { 2366f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // Check for the element type 2367f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_desc_len = 0; 2368f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa const char* type_desc = 236989756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers dex_compilation_unit_->GetDexFile()->StringByTypeIdx(type_idx, &type_desc_len); 2370f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 23717934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom DCHECK_GE(type_desc_len, 2u); // should be guaranteed by verifier 23727934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom DCHECK_EQ(type_desc[0], '['); // should be guaranteed by verifier 2373f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa bool is_elem_int_ty = (type_desc[1] == 'I'); 2374f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2375f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t alignment; 2376f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Constant* elem_size; 2377f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::PointerType* field_type; 2378f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2379f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // NOTE: Currently filled-new-array only supports 'L', '[', and 'I' 2380f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // as the element, thus we are only checking 2 cases: primitive int and 2381f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // non-primitive type. 2382f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa if (is_elem_int_ty) { 2383f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa alignment = sizeof(int32_t); 2384f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa elem_size = irb_.getPtrEquivInt(sizeof(int32_t)); 2385f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa field_type = irb_.getJIntTy()->getPointerTo(); 2386f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } else { 2387f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa alignment = irb_.getSizeOfPtrEquivInt(); 2388f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa elem_size = irb_.getSizeOfPtrEquivIntValue(); 2389f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa field_type = irb_.getJObjectTy()->getPointerTo(); 2390f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2391f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2392f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* data_field_offset = 239398573f907b2f5d1ccb4f6549a487f567599a82d3Ian Rogers irb_.getPtrEquivInt(art::mirror::Array::DataOffset(alignment).Int32Value()); 2394f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2395f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* data_field_addr = 2396f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreatePtrDisp(object_addr, data_field_offset, field_type); 2397f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2398f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // TODO: Tune this code. Currently we are generating one instruction for 2399f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // one element which may be very space consuming. Maybe changing to use 2400f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // memcpy may help; however, since we can't guarantee that the alloca of 2401f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // dalvik register are continuous, we can't perform such optimization yet. 2402f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa for (uint32_t i = 0; i < length; ++i) { 2403f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* reg_value = call_inst.getArgOperand(i+3); 2404f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2405f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateStore(reg_value, data_field_addr, kTBAAHeapArray); 2406f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2407f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa data_field_addr = 2408f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreatePtrDisp(data_field_addr, elem_size, field_type); 2409f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2410f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2411f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2412f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return object_addr; 2413f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2414f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2415f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYavoid GBCExpanderPass::Expand_HLFillArrayData(llvm::CallInst& call_inst) { 2416f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2417f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa int32_t payload_offset = static_cast<int32_t>(dex_pc) + 2418f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa LV2SInt(call_inst.getArgOperand(0)); 2419f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* array_addr = call_inst.getArgOperand(1); 2420f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2421920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa const art::Instruction::ArrayDataPayload* payload = 2422920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa reinterpret_cast<const art::Instruction::ArrayDataPayload*>( 242389756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers dex_compilation_unit_->GetCodeItem()->insns_ + payload_offset); 2424f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2425f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa if (payload->element_count == 0) { 2426f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // When the number of the elements in the payload is zero, we don't have 2427f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // to copy any numbers. However, we should check whether the array object 2428f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // address is equal to null or not. 24292ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz EmitGuard_NullPointerException(dex_pc, array_addr, 0); 2430f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } else { 2431f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // To save the code size, we are going to call the runtime function to 2432f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // copy the content from DexFile. 2433f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2434f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa // NOTE: We will check for the NullPointerException in the runtime. 2435f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 24363e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom llvm::Function* runtime_func = irb_.GetRuntime(FillArrayData); 2437f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2438f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 2439f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2440f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 2441f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2442f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCall4(runtime_func, 2443f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa method_object_addr, irb_.getInt32(dex_pc), 2444f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa array_addr, irb_.getInt32(payload_offset)); 2445f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2446f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 2447f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2448f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2449f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return; 2450f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2451f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2452f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass::EmitAllocNewArray(uint32_t dex_pc, 2453f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* array_length_value, 2454f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t type_idx, 2455f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa bool is_filled_new_array) { 2456f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Function* runtime_func; 2457f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2458f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa bool skip_access_check = 245989756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers driver_->CanAccessTypeWithoutChecks(dex_compilation_unit_->GetDexMethodIndex(), 246089756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers *dex_compilation_unit_->GetDexFile(), type_idx); 2461f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2462f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2463f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa if (is_filled_new_array) { 2464f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa runtime_func = skip_access_check ? 24653e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom irb_.GetRuntime(CheckAndAllocArray) : 24663e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom irb_.GetRuntime(CheckAndAllocArrayWithAccessCheck); 2467f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } else { 2468f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa runtime_func = skip_access_check ? 24693e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom irb_.GetRuntime(AllocArray) : 24703e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom irb_.GetRuntime(AllocArrayWithAccessCheck); 2471f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2472f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2473f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Constant* type_index_value = irb_.getInt32(type_idx); 2474f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2475f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 2476f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2477f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread(); 2478f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2479f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 2480f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2481f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* object_addr = 2482f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCall4(runtime_func, type_index_value, method_object_addr, 2483f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa array_length_value, thread_object_addr); 2484f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2485f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 2486f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2487f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return object_addr; 2488f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2489f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2490f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYallvm::Value* GBCExpanderPass:: 2491f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYaEmitCallRuntimeForCalleeMethodObjectAddr(uint32_t callee_method_idx, 2492920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::InvokeType invoke_type, 2493f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* this_addr, 2494f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc, 2495f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa bool is_fast_path) { 2496f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Function* runtime_func = NULL; 2497f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2498f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa switch (invoke_type) { 2499920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case art::kStatic: 25003e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(FindStaticMethodWithAccessCheck); 2501f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa break; 2502f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2503920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case art::kDirect: 25043e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(FindDirectMethodWithAccessCheck); 2505f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa break; 2506f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2507920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case art::kVirtual: 25083e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(FindVirtualMethodWithAccessCheck); 2509f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa break; 2510f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2511920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case art::kSuper: 25123e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(FindSuperMethodWithAccessCheck); 2513f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa break; 2514f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2515920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case art::kInterface: 2516f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa if (is_fast_path) { 25173e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(FindInterfaceMethod); 2518f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } else { 25193e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom runtime_func = irb_.GetRuntime(FindInterfaceMethodWithAccessCheck); 2520f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2521f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa break; 2522f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2523f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2524f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* callee_method_idx_value = irb_.getInt32(callee_method_idx); 2525f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2526f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa if (this_addr == NULL) { 2527920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa DCHECK_EQ(invoke_type, art::kStatic); 2528f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa this_addr = irb_.getJNull(); 2529f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 2530f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2531f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* caller_method_object_addr = EmitLoadMethodObjectAddr(); 2532f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2533f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread(); 2534f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2535f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 2536f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2537f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa llvm::Value* callee_method_object_addr = 2538f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa irb_.CreateCall4(runtime_func, 2539f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa callee_method_idx_value, 2540f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa this_addr, 2541f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa caller_method_object_addr, 2542f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa thread_object_addr); 2543f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2544f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 2545f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2546f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return callee_method_object_addr; 2547f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa} 2548f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 25495e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::EmitMarkGCCard(llvm::Value* value, llvm::Value* target_addr) { 25505e869b6560f918837cc6be3a50234deb2be46385TDYa // Using runtime support, let the target can override by InlineAssembly. 25515e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.Runtime().EmitMarkGCCard(value, target_addr); 25525e869b6560f918837cc6be3a50234deb2be46385TDYa} 25535e869b6560f918837cc6be3a50234deb2be46385TDYa 25545e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::EmitUpdateDexPC(uint32_t dex_pc) { 2555bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao if (shadow_frame_ == NULL) { 2556bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao return; 2557bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao } 25585e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.StoreToObjectOffset(shadow_frame_, 2559920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::ShadowFrame::DexPCOffset(), 25605e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.getInt32(dex_pc), 25615e869b6560f918837cc6be3a50234deb2be46385TDYa kTBAAShadowFrame); 25625e869b6560f918837cc6be3a50234deb2be46385TDYa} 25635e869b6560f918837cc6be3a50234deb2be46385TDYa 25645e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::EmitGuard_DivZeroException(uint32_t dex_pc, 25655e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* denominator, 25665e869b6560f918837cc6be3a50234deb2be46385TDYa JType op_jty) { 25675e869b6560f918837cc6be3a50234deb2be46385TDYa DCHECK(op_jty == kInt || op_jty == kLong) << op_jty; 25685e869b6560f918837cc6be3a50234deb2be46385TDYa 25695e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Constant* zero = irb_.getJZero(op_jty); 25705e869b6560f918837cc6be3a50234deb2be46385TDYa 25715e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* equal_zero = irb_.CreateICmpEQ(denominator, zero); 25725e869b6560f918837cc6be3a50234deb2be46385TDYa 25735e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* block_exception = CreateBasicBlockWithDexPC(dex_pc, "div0"); 25745e869b6560f918837cc6be3a50234deb2be46385TDYa 25755e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* block_continue = CreateBasicBlockWithDexPC(dex_pc, "cont"); 25765e869b6560f918837cc6be3a50234deb2be46385TDYa 25775e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateCondBr(equal_zero, block_exception, block_continue, kUnlikely); 25785e869b6560f918837cc6be3a50234deb2be46385TDYa 25795e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.SetInsertPoint(block_exception); 25805e869b6560f918837cc6be3a50234deb2be46385TDYa EmitUpdateDexPC(dex_pc); 25813e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom irb_.CreateCall(irb_.GetRuntime(ThrowDivZeroException)); 25825e869b6560f918837cc6be3a50234deb2be46385TDYa EmitBranchExceptionLandingPad(dex_pc); 25835e869b6560f918837cc6be3a50234deb2be46385TDYa 25845e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.SetInsertPoint(block_continue); 25855e869b6560f918837cc6be3a50234deb2be46385TDYa} 25865e869b6560f918837cc6be3a50234deb2be46385TDYa 25875e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::EmitGuard_NullPointerException(uint32_t dex_pc, 25882ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz llvm::Value* object, 25892ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz int opt_flags) { 25902ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz bool ignore_null_check = ((opt_flags & MIR_IGNORE_NULL_CHECK) != 0); 25912ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz if (ignore_null_check) { 25922ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc); 25932ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz if (lpad) { 25942ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz // There is at least one catch: create a "fake" conditional branch to 25952ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz // keep the exception edge to the catch block. 25962ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz landing_pad_phi_mapping_[lpad].push_back( 25972ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz std::make_pair(current_bb_->getUniquePredecessor(), 25982ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz irb_.GetInsertBlock())); 25992ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz 26002ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz llvm::BasicBlock* block_continue = 26012ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz CreateBasicBlockWithDexPC(dex_pc, "cont"); 26022ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz 26038e6960569e9de6350d7da89aa02efe0e4b924d6fIan Rogers irb_.CreateCondBr(irb_.getFalse(), lpad, block_continue, kUnlikely); 26042ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz 26052ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz irb_.SetInsertPoint(block_continue); 26062ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz } 26072ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz } else { 26082ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz llvm::Value* equal_null = irb_.CreateICmpEQ(object, irb_.getJNull()); 26095e869b6560f918837cc6be3a50234deb2be46385TDYa 26102ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz llvm::BasicBlock* block_exception = 26112ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz CreateBasicBlockWithDexPC(dex_pc, "nullp"); 26125e869b6560f918837cc6be3a50234deb2be46385TDYa 26132ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz llvm::BasicBlock* block_continue = 26142ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz CreateBasicBlockWithDexPC(dex_pc, "cont"); 26155e869b6560f918837cc6be3a50234deb2be46385TDYa 26162ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz irb_.CreateCondBr(equal_null, block_exception, block_continue, kUnlikely); 26175e869b6560f918837cc6be3a50234deb2be46385TDYa 26182ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz irb_.SetInsertPoint(block_exception); 26192ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz EmitUpdateDexPC(dex_pc); 26203e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom irb_.CreateCall(irb_.GetRuntime(ThrowNullPointerException), 26212ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz irb_.getInt32(dex_pc)); 26222ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz EmitBranchExceptionLandingPad(dex_pc); 26235e869b6560f918837cc6be3a50234deb2be46385TDYa 26242ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz irb_.SetInsertPoint(block_continue); 26252ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz } 26265e869b6560f918837cc6be3a50234deb2be46385TDYa} 26275e869b6560f918837cc6be3a50234deb2be46385TDYa 26285e869b6560f918837cc6be3a50234deb2be46385TDYavoid 26295e869b6560f918837cc6be3a50234deb2be46385TDYaGBCExpanderPass::EmitGuard_ArrayIndexOutOfBoundsException(uint32_t dex_pc, 26305e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* array, 26312ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz llvm::Value* index, 26322ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz int opt_flags) { 26332ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz bool ignore_range_check = ((opt_flags & MIR_IGNORE_RANGE_CHECK) != 0); 26342ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz if (ignore_range_check) { 26352ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc); 26362ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz if (lpad) { 26372ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz // There is at least one catch: create a "fake" conditional branch to 26382ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz // keep the exception edge to the catch block. 26392ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz landing_pad_phi_mapping_[lpad].push_back( 26402ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz std::make_pair(current_bb_->getUniquePredecessor(), 26412ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz irb_.GetInsertBlock())); 26422ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz 26432ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz llvm::BasicBlock* block_continue = 26442ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz CreateBasicBlockWithDexPC(dex_pc, "cont"); 26452ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz 26468e6960569e9de6350d7da89aa02efe0e4b924d6fIan Rogers irb_.CreateCondBr(irb_.getFalse(), lpad, block_continue, kUnlikely); 26472ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz 26482ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz irb_.SetInsertPoint(block_continue); 26492ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz } 26502ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz } else { 26512ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz llvm::Value* array_len = EmitLoadArrayLength(array); 26525e869b6560f918837cc6be3a50234deb2be46385TDYa 26532ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz llvm::Value* cmp = irb_.CreateICmpUGE(index, array_len); 26545e869b6560f918837cc6be3a50234deb2be46385TDYa 26552ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz llvm::BasicBlock* block_exception = 26562ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz CreateBasicBlockWithDexPC(dex_pc, "overflow"); 26575e869b6560f918837cc6be3a50234deb2be46385TDYa 26582ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz llvm::BasicBlock* block_continue = 26592ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz CreateBasicBlockWithDexPC(dex_pc, "cont"); 26605e869b6560f918837cc6be3a50234deb2be46385TDYa 26612ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz irb_.CreateCondBr(cmp, block_exception, block_continue, kUnlikely); 26625e869b6560f918837cc6be3a50234deb2be46385TDYa 26632ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz irb_.SetInsertPoint(block_exception); 26645e869b6560f918837cc6be3a50234deb2be46385TDYa 26652ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz EmitUpdateDexPC(dex_pc); 26663e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom irb_.CreateCall2(irb_.GetRuntime(ThrowIndexOutOfBounds), index, array_len); 26672ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz EmitBranchExceptionLandingPad(dex_pc); 26685e869b6560f918837cc6be3a50234deb2be46385TDYa 26692ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz irb_.SetInsertPoint(block_continue); 26702ffe4f1352b877b9139697015c45a877847042f4Sebastien Hertz } 26715e869b6560f918837cc6be3a50234deb2be46385TDYa} 26725e869b6560f918837cc6be3a50234deb2be46385TDYa 26738e6960569e9de6350d7da89aa02efe0e4b924d6fIan Rogersllvm::FunctionType* GBCExpanderPass::GetFunctionType(llvm::Type* ret_type, uint32_t method_idx, 26745e869b6560f918837cc6be3a50234deb2be46385TDYa bool is_static) { 26755e869b6560f918837cc6be3a50234deb2be46385TDYa // Get method signature 26768e6960569e9de6350d7da89aa02efe0e4b924d6fIan Rogers art::DexFile::MethodId const& method_id = 267789756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers dex_compilation_unit_->GetDexFile()->GetMethodId(method_idx); 26785e869b6560f918837cc6be3a50234deb2be46385TDYa 26795e869b6560f918837cc6be3a50234deb2be46385TDYa uint32_t shorty_size; 268089756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers const char* shorty = dex_compilation_unit_->GetDexFile()->GetMethodShorty(method_id, &shorty_size); 26815e869b6560f918837cc6be3a50234deb2be46385TDYa CHECK_GE(shorty_size, 1u); 26825e869b6560f918837cc6be3a50234deb2be46385TDYa 26835e869b6560f918837cc6be3a50234deb2be46385TDYa // Get argument type 26845e869b6560f918837cc6be3a50234deb2be46385TDYa std::vector<llvm::Type*> args_type; 26855e869b6560f918837cc6be3a50234deb2be46385TDYa 26867934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom args_type.push_back(irb_.getJObjectTy()); // method object pointer 26875e869b6560f918837cc6be3a50234deb2be46385TDYa 26885e869b6560f918837cc6be3a50234deb2be46385TDYa if (!is_static) { 26897934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom args_type.push_back(irb_.getJType('L')); // "this" object pointer 26905e869b6560f918837cc6be3a50234deb2be46385TDYa } 26915e869b6560f918837cc6be3a50234deb2be46385TDYa 26925e869b6560f918837cc6be3a50234deb2be46385TDYa for (uint32_t i = 1; i < shorty_size; ++i) { 269326f10eed520942d3db754c31941e457048475f61buzbee char shorty_type = art::RemapShorty(shorty[i]); 269476ae4fe651c77619aeeb4dd395c7ec8fc29685fcIan Rogers args_type.push_back(irb_.getJType(shorty_type)); 26955e869b6560f918837cc6be3a50234deb2be46385TDYa } 26965e869b6560f918837cc6be3a50234deb2be46385TDYa 26975e869b6560f918837cc6be3a50234deb2be46385TDYa return llvm::FunctionType::get(ret_type, args_type, false); 26985e869b6560f918837cc6be3a50234deb2be46385TDYa} 26995e869b6560f918837cc6be3a50234deb2be46385TDYa 27005e869b6560f918837cc6be3a50234deb2be46385TDYa 27015e869b6560f918837cc6be3a50234deb2be46385TDYallvm::BasicBlock* GBCExpanderPass:: 27025e869b6560f918837cc6be3a50234deb2be46385TDYaCreateBasicBlockWithDexPC(uint32_t dex_pc, const char* postfix) { 27035e869b6560f918837cc6be3a50234deb2be46385TDYa std::string name; 27045e869b6560f918837cc6be3a50234deb2be46385TDYa 27055e869b6560f918837cc6be3a50234deb2be46385TDYa#if !defined(NDEBUG) 2706920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::StringAppendF(&name, "B%04x.%s", dex_pc, postfix); 27075e869b6560f918837cc6be3a50234deb2be46385TDYa#endif 27085e869b6560f918837cc6be3a50234deb2be46385TDYa 27095e869b6560f918837cc6be3a50234deb2be46385TDYa return llvm::BasicBlock::Create(context_, name, func_); 27105e869b6560f918837cc6be3a50234deb2be46385TDYa} 27115e869b6560f918837cc6be3a50234deb2be46385TDYa 27125e869b6560f918837cc6be3a50234deb2be46385TDYallvm::BasicBlock* GBCExpanderPass::GetBasicBlock(uint32_t dex_pc) { 271389756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers DCHECK(dex_pc < dex_compilation_unit_->GetCodeItem()->insns_size_in_code_units_); 2714bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao CHECK(basic_blocks_[dex_pc] != NULL); 27155e869b6560f918837cc6be3a50234deb2be46385TDYa return basic_blocks_[dex_pc]; 27165e869b6560f918837cc6be3a50234deb2be46385TDYa} 27175e869b6560f918837cc6be3a50234deb2be46385TDYa 27185e869b6560f918837cc6be3a50234deb2be46385TDYaint32_t GBCExpanderPass::GetTryItemOffset(uint32_t dex_pc) { 27195e869b6560f918837cc6be3a50234deb2be46385TDYa int32_t min = 0; 272089756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers int32_t max = dex_compilation_unit_->GetCodeItem()->tries_size_ - 1; 27215e869b6560f918837cc6be3a50234deb2be46385TDYa 27225e869b6560f918837cc6be3a50234deb2be46385TDYa while (min <= max) { 27235e869b6560f918837cc6be3a50234deb2be46385TDYa int32_t mid = min + (max - min) / 2; 27245e869b6560f918837cc6be3a50234deb2be46385TDYa 272589756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers const art::DexFile::TryItem* ti = 272689756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers art::DexFile::GetTryItems(*dex_compilation_unit_->GetCodeItem(), mid); 27275e869b6560f918837cc6be3a50234deb2be46385TDYa uint32_t start = ti->start_addr_; 27285e869b6560f918837cc6be3a50234deb2be46385TDYa uint32_t end = start + ti->insn_count_; 27295e869b6560f918837cc6be3a50234deb2be46385TDYa 27305e869b6560f918837cc6be3a50234deb2be46385TDYa if (dex_pc < start) { 27315e869b6560f918837cc6be3a50234deb2be46385TDYa max = mid - 1; 27325e869b6560f918837cc6be3a50234deb2be46385TDYa } else if (dex_pc >= end) { 27335e869b6560f918837cc6be3a50234deb2be46385TDYa min = mid + 1; 27345e869b6560f918837cc6be3a50234deb2be46385TDYa } else { 27357934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom return mid; // found 27365e869b6560f918837cc6be3a50234deb2be46385TDYa } 27375e869b6560f918837cc6be3a50234deb2be46385TDYa } 27385e869b6560f918837cc6be3a50234deb2be46385TDYa 27397934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom return -1; // not found 27405e869b6560f918837cc6be3a50234deb2be46385TDYa} 27415e869b6560f918837cc6be3a50234deb2be46385TDYa 27425e869b6560f918837cc6be3a50234deb2be46385TDYallvm::BasicBlock* GBCExpanderPass::GetLandingPadBasicBlock(uint32_t dex_pc) { 27435e869b6560f918837cc6be3a50234deb2be46385TDYa // Find the try item for this address in this method 27445e869b6560f918837cc6be3a50234deb2be46385TDYa int32_t ti_offset = GetTryItemOffset(dex_pc); 27455e869b6560f918837cc6be3a50234deb2be46385TDYa 27465e869b6560f918837cc6be3a50234deb2be46385TDYa if (ti_offset == -1) { 27477934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom return NULL; // No landing pad is available for this address. 27485e869b6560f918837cc6be3a50234deb2be46385TDYa } 27495e869b6560f918837cc6be3a50234deb2be46385TDYa 27505e869b6560f918837cc6be3a50234deb2be46385TDYa // Check for the existing landing pad basic block 27515e869b6560f918837cc6be3a50234deb2be46385TDYa DCHECK_GT(basic_block_landing_pads_.size(), static_cast<size_t>(ti_offset)); 27525e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock* block_lpad = basic_block_landing_pads_[ti_offset]; 27535e869b6560f918837cc6be3a50234deb2be46385TDYa 27545e869b6560f918837cc6be3a50234deb2be46385TDYa if (block_lpad) { 27555e869b6560f918837cc6be3a50234deb2be46385TDYa // We have generated landing pad for this try item already. Return the 27565e869b6560f918837cc6be3a50234deb2be46385TDYa // same basic block. 27575e869b6560f918837cc6be3a50234deb2be46385TDYa return block_lpad; 27585e869b6560f918837cc6be3a50234deb2be46385TDYa } 27595e869b6560f918837cc6be3a50234deb2be46385TDYa 27605e869b6560f918837cc6be3a50234deb2be46385TDYa // Get try item from code item 276189756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers const art::DexFile::TryItem* ti = art::DexFile::GetTryItems(*dex_compilation_unit_->GetCodeItem(), 27628e6960569e9de6350d7da89aa02efe0e4b924d6fIan Rogers ti_offset); 27635e869b6560f918837cc6be3a50234deb2be46385TDYa 27645e869b6560f918837cc6be3a50234deb2be46385TDYa std::string lpadname; 27655e869b6560f918837cc6be3a50234deb2be46385TDYa 27665e869b6560f918837cc6be3a50234deb2be46385TDYa#if !defined(NDEBUG) 2767920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa art::StringAppendF(&lpadname, "lpad%d_%04x_to_%04x", ti_offset, ti->start_addr_, ti->handler_off_); 27685e869b6560f918837cc6be3a50234deb2be46385TDYa#endif 27695e869b6560f918837cc6be3a50234deb2be46385TDYa 27705e869b6560f918837cc6be3a50234deb2be46385TDYa // Create landing pad basic block 27715e869b6560f918837cc6be3a50234deb2be46385TDYa block_lpad = llvm::BasicBlock::Create(context_, lpadname, func_); 27725e869b6560f918837cc6be3a50234deb2be46385TDYa 27735e869b6560f918837cc6be3a50234deb2be46385TDYa // Change IRBuilder insert point 27745e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP(); 27755e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.SetInsertPoint(block_lpad); 27765e869b6560f918837cc6be3a50234deb2be46385TDYa 27775e869b6560f918837cc6be3a50234deb2be46385TDYa // Find catch block with matching type 27785e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 27795e869b6560f918837cc6be3a50234deb2be46385TDYa 27805e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* ti_offset_value = irb_.getInt32(ti_offset); 27815e869b6560f918837cc6be3a50234deb2be46385TDYa 27825e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::Value* catch_handler_index_value = 27833e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom irb_.CreateCall2(irb_.GetRuntime(FindCatchBlock), 27845e869b6560f918837cc6be3a50234deb2be46385TDYa method_object_addr, ti_offset_value); 27855e869b6560f918837cc6be3a50234deb2be46385TDYa 27865e869b6560f918837cc6be3a50234deb2be46385TDYa // Switch instruction (Go to unwind basic block by default) 27875e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::SwitchInst* sw = 27885e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateSwitch(catch_handler_index_value, GetUnwindBasicBlock()); 27895e869b6560f918837cc6be3a50234deb2be46385TDYa 27905e869b6560f918837cc6be3a50234deb2be46385TDYa // Cases with matched catch block 279189756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers art::CatchHandlerIterator iter(*dex_compilation_unit_->GetCodeItem(), ti->start_addr_); 27925e869b6560f918837cc6be3a50234deb2be46385TDYa 27935e869b6560f918837cc6be3a50234deb2be46385TDYa for (uint32_t c = 0; iter.HasNext(); iter.Next(), ++c) { 27945e869b6560f918837cc6be3a50234deb2be46385TDYa sw->addCase(irb_.getInt32(c), GetBasicBlock(iter.GetHandlerAddress())); 27955e869b6560f918837cc6be3a50234deb2be46385TDYa } 27965e869b6560f918837cc6be3a50234deb2be46385TDYa 27975e869b6560f918837cc6be3a50234deb2be46385TDYa // Restore the orignal insert point for IRBuilder 27985e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.restoreIP(irb_ip_original); 27995e869b6560f918837cc6be3a50234deb2be46385TDYa 28005e869b6560f918837cc6be3a50234deb2be46385TDYa // Cache this landing pad 28015e869b6560f918837cc6be3a50234deb2be46385TDYa DCHECK_GT(basic_block_landing_pads_.size(), static_cast<size_t>(ti_offset)); 28025e869b6560f918837cc6be3a50234deb2be46385TDYa basic_block_landing_pads_[ti_offset] = block_lpad; 28035e869b6560f918837cc6be3a50234deb2be46385TDYa 28045e869b6560f918837cc6be3a50234deb2be46385TDYa return block_lpad; 28055e869b6560f918837cc6be3a50234deb2be46385TDYa} 28065e869b6560f918837cc6be3a50234deb2be46385TDYa 28075e869b6560f918837cc6be3a50234deb2be46385TDYallvm::BasicBlock* GBCExpanderPass::GetUnwindBasicBlock() { 28085e869b6560f918837cc6be3a50234deb2be46385TDYa // Check the existing unwinding baisc block block 28095e869b6560f918837cc6be3a50234deb2be46385TDYa if (basic_block_unwind_ != NULL) { 28105e869b6560f918837cc6be3a50234deb2be46385TDYa return basic_block_unwind_; 28115e869b6560f918837cc6be3a50234deb2be46385TDYa } 28125e869b6560f918837cc6be3a50234deb2be46385TDYa 28135e869b6560f918837cc6be3a50234deb2be46385TDYa // Create new basic block for unwinding 28145e869b6560f918837cc6be3a50234deb2be46385TDYa basic_block_unwind_ = 28155e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::BasicBlock::Create(context_, "exception_unwind", func_); 28165e869b6560f918837cc6be3a50234deb2be46385TDYa 28175e869b6560f918837cc6be3a50234deb2be46385TDYa // Change IRBuilder insert point 28185e869b6560f918837cc6be3a50234deb2be46385TDYa llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP(); 28195e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.SetInsertPoint(basic_block_unwind_); 28205e869b6560f918837cc6be3a50234deb2be46385TDYa 28215e869b6560f918837cc6be3a50234deb2be46385TDYa // Pop the shadow frame 28225e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_PopShadowFrame(); 28235e869b6560f918837cc6be3a50234deb2be46385TDYa 28245e869b6560f918837cc6be3a50234deb2be46385TDYa // Emit the code to return default value (zero) for the given return type. 282589756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers char ret_shorty = dex_compilation_unit_->GetShorty()[0]; 282626f10eed520942d3db754c31941e457048475f61buzbee ret_shorty = art::RemapShorty(ret_shorty); 28275e869b6560f918837cc6be3a50234deb2be46385TDYa if (ret_shorty == 'V') { 28285e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateRetVoid(); 28295e869b6560f918837cc6be3a50234deb2be46385TDYa } else { 28305e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateRet(irb_.getJZero(ret_shorty)); 28315e869b6560f918837cc6be3a50234deb2be46385TDYa } 28325e869b6560f918837cc6be3a50234deb2be46385TDYa 28335e869b6560f918837cc6be3a50234deb2be46385TDYa // Restore the orignal insert point for IRBuilder 28345e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.restoreIP(irb_ip_original); 28355e869b6560f918837cc6be3a50234deb2be46385TDYa 28365e869b6560f918837cc6be3a50234deb2be46385TDYa return basic_block_unwind_; 28375e869b6560f918837cc6be3a50234deb2be46385TDYa} 28385e869b6560f918837cc6be3a50234deb2be46385TDYa 28395e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::EmitBranchExceptionLandingPad(uint32_t dex_pc) { 28405e869b6560f918837cc6be3a50234deb2be46385TDYa if (llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc)) { 284155e5e6c5702e3f1f68bd83ae741af769740d9a74TDYa landing_pad_phi_mapping_[lpad].push_back(std::make_pair(current_bb_->getUniquePredecessor(), 2842aa55887fd30484a77e7775dfbcddbee883ce6380TDYa irb_.GetInsertBlock())); 28435e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateBr(lpad); 28445e869b6560f918837cc6be3a50234deb2be46385TDYa } else { 28455e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.CreateBr(GetUnwindBasicBlock()); 28465e869b6560f918837cc6be3a50234deb2be46385TDYa } 28475e869b6560f918837cc6be3a50234deb2be46385TDYa} 28485e869b6560f918837cc6be3a50234deb2be46385TDYa 28495e869b6560f918837cc6be3a50234deb2be46385TDYavoid GBCExpanderPass::EmitGuard_ExceptionLandingPad(uint32_t dex_pc) { 28509a14265c911b2e63bec51a814b8b6fd157745b57Jeff Hao llvm::Value* exception_pending = irb_.Runtime().EmitIsExceptionPending(); 2851a1ae861c673ab5160a2a7afee2ada806cb61966bjeffhao 28529a14265c911b2e63bec51a814b8b6fd157745b57Jeff Hao llvm::BasicBlock* block_cont = CreateBasicBlockWithDexPC(dex_pc, "cont"); 28535e869b6560f918837cc6be3a50234deb2be46385TDYa 28545e869b6560f918837cc6be3a50234deb2be46385TDYa if (llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc)) { 285555e5e6c5702e3f1f68bd83ae741af769740d9a74TDYa landing_pad_phi_mapping_[lpad].push_back(std::make_pair(current_bb_->getUniquePredecessor(), 2856aa55887fd30484a77e7775dfbcddbee883ce6380TDYa irb_.GetInsertBlock())); 28579a14265c911b2e63bec51a814b8b6fd157745b57Jeff Hao irb_.CreateCondBr(exception_pending, lpad, block_cont, kUnlikely); 28585e869b6560f918837cc6be3a50234deb2be46385TDYa } else { 28599a14265c911b2e63bec51a814b8b6fd157745b57Jeff Hao irb_.CreateCondBr(exception_pending, GetUnwindBasicBlock(), block_cont, kUnlikely); 28605e869b6560f918837cc6be3a50234deb2be46385TDYa } 28615e869b6560f918837cc6be3a50234deb2be46385TDYa 28625e869b6560f918837cc6be3a50234deb2be46385TDYa irb_.SetInsertPoint(block_cont); 28635e869b6560f918837cc6be3a50234deb2be46385TDYa} 28645e869b6560f918837cc6be3a50234deb2be46385TDYa 286521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaollvm::Value* 286621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei LiaoGBCExpanderPass::ExpandIntrinsic(IntrinsicHelper::IntrinsicId intr_id, 286721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao llvm::CallInst& call_inst) { 286821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao switch (intr_id) { 286921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Thread -----------------------------------------------------------==// 287021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::GetCurrentThread: { 2871b672d1e48b6e02bb69c7cd9bcfa7509c81514c07TDYa return irb_.Runtime().EmitGetCurrentThread(); 287221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 287375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::CheckSuspend: { 2874ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa Expand_TestSuspend(call_inst); 2875890ea89879ba555a08433146058d516575646c59TDYa return NULL; 2876890ea89879ba555a08433146058d516575646c59TDYa } 2877890ea89879ba555a08433146058d516575646c59TDYa case IntrinsicHelper::TestSuspend: { 2878d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien Expand_TestSuspend(call_inst); 287975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 288075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 288121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::MarkGCCard: { 28829a129457c233b653c7a8f65c963509267252b0a7TDYa Expand_MarkGCCard(call_inst); 28839a129457c233b653c7a8f65c963509267252b0a7TDYa return NULL; 288421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 288575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 288621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Exception --------------------------------------------------------==// 288721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ThrowException: { 28883e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(ThrowException, call_inst); 288921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 2890f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa case IntrinsicHelper::HLThrowException: { 2891f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2892f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2893f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitUpdateDexPC(dex_pc); 2894f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 28953e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom irb_.CreateCall(irb_.GetRuntime(ThrowException), 2896f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa call_inst.getArgOperand(0)); 2897f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa 2898f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa EmitGuard_ExceptionLandingPad(dex_pc); 2899f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return NULL; 2900f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa } 290121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::GetException: { 2902823433dbf4afec17169d5ca738031af5b374e140TDYa return irb_.Runtime().EmitGetAndClearException(); 290321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 290421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::IsExceptionPending: { 290521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return irb_.Runtime().EmitIsExceptionPending(); 290621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 290721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::FindCatchBlock: { 29083e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(FindCatchBlock, call_inst); 290921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 291021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ThrowDivZeroException: { 29113e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(ThrowDivZeroException, call_inst); 291221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 291321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ThrowNullPointerException: { 29143e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(ThrowNullPointerException, call_inst); 291521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 291621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ThrowIndexOutOfBounds: { 29173e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(ThrowIndexOutOfBounds, call_inst); 291821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 291975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 292075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Const String -----------------------------------------------------==// 292175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::ConstString: { 2922f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return Expand_ConstString(call_inst); 292375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 292421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::LoadStringFromDexCache: { 292521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_LoadStringFromDexCache(call_inst.getArgOperand(0)); 292621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 292721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ResolveString: { 29283e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(ResolveString, call_inst); 292921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 293075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 293175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Const Class ------------------------------------------------------==// 293275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::ConstClass: { 2933f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return Expand_ConstClass(call_inst); 293475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 293521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InitializeTypeAndVerifyAccess: { 29363e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(InitializeTypeAndVerifyAccess, call_inst); 293721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 293821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::LoadTypeFromDexCache: { 293921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_LoadTypeFromDexCache(call_inst.getArgOperand(0)); 294021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 294121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InitializeType: { 29423e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(InitializeType, call_inst); 294321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 294475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 294521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Lock -------------------------------------------------------------==// 294621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::LockObject: { 294721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_LockObject(call_inst.getArgOperand(0)); 294821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 294921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 295021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::UnlockObject: { 295121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_UnlockObject(call_inst.getArgOperand(0)); 295221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 295321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 295475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 295521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Cast -------------------------------------------------------------==// 295621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::CheckCast: { 29573e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(CheckCast, call_inst); 295821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 295975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLCheckCast: { 2960f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa Expand_HLCheckCast(call_inst); 296175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 296275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 296321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::IsAssignable: { 29643e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(IsAssignable, call_inst); 296521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 296675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 296721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Alloc ------------------------------------------------------------==// 296821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::AllocObject: { 29693e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(AllocObject, call_inst); 297021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 297121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::AllocObjectWithAccessCheck: { 29723e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(AllocObjectWithAccessCheck, call_inst); 297321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 297475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 297575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Instance ---------------------------------------------------------==// 297675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::NewInstance: { 2977f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return Expand_NewInstance(call_inst); 297875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 297975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::InstanceOf: { 2980f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return Expand_InstanceOf(call_inst); 298175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 298275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 298321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Array ------------------------------------------------------------==// 298475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::NewArray: { 2985f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return Expand_NewArray(call_inst); 298675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 298775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::OptArrayLength: { 2988f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return Expand_OptArrayLength(call_inst); 298975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 299021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayLength: { 299121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return EmitLoadArrayLength(call_inst.getArgOperand(0)); 299221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 299321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::AllocArray: { 29943e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(AllocArray, call_inst); 299521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 299621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::AllocArrayWithAccessCheck: { 29973e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(AllocArrayWithAccessCheck, 299821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst); 299921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 300021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::CheckAndAllocArray: { 30013e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(CheckAndAllocArray, call_inst); 300221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 300321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::CheckAndAllocArrayWithAccessCheck: { 30043e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(CheckAndAllocArrayWithAccessCheck, 300521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst); 300621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 300721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayGet: { 300821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_ArrayGet(call_inst.getArgOperand(0), 300921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 301021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kInt); 301121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 301221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayGetWide: { 301321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_ArrayGet(call_inst.getArgOperand(0), 301421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 301521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kLong); 301621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 301721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayGetObject: { 301821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_ArrayGet(call_inst.getArgOperand(0), 301921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 302021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kObject); 302121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 302221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayGetBoolean: { 302321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_ArrayGet(call_inst.getArgOperand(0), 302421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 302521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kBoolean); 302621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 302721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayGetByte: { 302821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_ArrayGet(call_inst.getArgOperand(0), 302921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 303021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kByte); 303121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 303221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayGetChar: { 303321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_ArrayGet(call_inst.getArgOperand(0), 303421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 303521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kChar); 303621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 303721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayGetShort: { 303821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_ArrayGet(call_inst.getArgOperand(0), 303921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 304021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kShort); 304121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 304221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayPut: { 304321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_ArrayPut(call_inst.getArgOperand(0), 304421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 304521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 304621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kInt); 304721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 304821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 304921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayPutWide: { 305021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_ArrayPut(call_inst.getArgOperand(0), 305121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 305221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 305321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kLong); 305421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 305521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 305621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayPutObject: { 305721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_ArrayPut(call_inst.getArgOperand(0), 305821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 305921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 306021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kObject); 306121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 306221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 306321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayPutBoolean: { 306421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_ArrayPut(call_inst.getArgOperand(0), 306521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 306621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 306721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kBoolean); 306821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 306921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 307021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayPutByte: { 307121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_ArrayPut(call_inst.getArgOperand(0), 307221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 307321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 307421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kByte); 307521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 307621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 307721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayPutChar: { 307821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_ArrayPut(call_inst.getArgOperand(0), 307921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 308021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 308121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kChar); 308221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 308321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 308421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::ArrayPutShort: { 308521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_ArrayPut(call_inst.getArgOperand(0), 308621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 308721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 308821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kShort); 308921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 309021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 309121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::CheckPutArrayElement: { 30923e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(CheckPutArrayElement, call_inst); 309321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 309421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::FilledNewArray: { 309521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_FilledNewArray(call_inst); 309621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 309721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 309821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::FillArrayData: { 30993e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(FillArrayData, call_inst); 310021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 310175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLFillArrayData: { 3102f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa Expand_HLFillArrayData(call_inst); 310375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 310475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 310575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLFilledNewArray: { 3106f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return Expand_HLFilledNewArray(call_inst); 310775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 310875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 310921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Instance Field ---------------------------------------------------==// 311021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGet: 311121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetBoolean: 311221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetByte: 311321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetChar: 311421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetShort: { 31153e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(Get32Instance, call_inst); 311621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 311721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetWide: { 31183e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(Get64Instance, call_inst); 311921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 312021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetObject: { 31213e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(GetObjectInstance, call_inst); 312221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 312321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetFast: { 312421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_IGetFast(call_inst.getArgOperand(0), 312521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 312621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 312721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kInt); 312821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 312921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetWideFast: { 313021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_IGetFast(call_inst.getArgOperand(0), 313121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 313221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 313321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kLong); 313421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 313521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetObjectFast: { 313621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_IGetFast(call_inst.getArgOperand(0), 313721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 313821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 313921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kObject); 314021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 314121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetBooleanFast: { 314221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_IGetFast(call_inst.getArgOperand(0), 314321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 314421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 314521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kBoolean); 314621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 314721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetByteFast: { 314821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_IGetFast(call_inst.getArgOperand(0), 314921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 315021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 315121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kByte); 315221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 315321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetCharFast: { 315421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_IGetFast(call_inst.getArgOperand(0), 315521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 315621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 315721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kChar); 315821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 315921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldGetShortFast: { 316021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_IGetFast(call_inst.getArgOperand(0), 316121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 316221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 316321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kShort); 316421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 316521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPut: 316621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutBoolean: 316721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutByte: 316821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutChar: 316921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutShort: { 31703e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(Set32Instance, call_inst); 317121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 317221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutWide: { 31733e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(Set64Instance, call_inst); 317421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 317521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutObject: { 31763e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(SetObjectInstance, call_inst); 317721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 317821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutFast: { 317921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_IPutFast(call_inst.getArgOperand(0), 318021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 318121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 318221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 318321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kInt); 318421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 318521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 318621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutWideFast: { 318721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_IPutFast(call_inst.getArgOperand(0), 318821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 318921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 319021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 319121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kLong); 319221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 319321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 319421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutObjectFast: { 319521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_IPutFast(call_inst.getArgOperand(0), 319621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 319721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 319821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 319921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kObject); 320021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 320121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 320221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutBooleanFast: { 320321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_IPutFast(call_inst.getArgOperand(0), 320421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 320521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 320621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 320721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kBoolean); 320821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 320921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 321021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutByteFast: { 321121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_IPutFast(call_inst.getArgOperand(0), 321221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 321321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 321421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 321521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kByte); 321621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 321721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 321821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutCharFast: { 321921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_IPutFast(call_inst.getArgOperand(0), 322021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 322121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 322221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 322321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kChar); 322421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 322521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 322621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InstanceFieldPutShortFast: { 322721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_IPutFast(call_inst.getArgOperand(0), 322821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 322921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 323021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 323121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kShort); 323221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 323321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 323475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 323521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Static Field -----------------------------------------------------==// 323621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGet: 323721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetBoolean: 323821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetByte: 323921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetChar: 324021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetShort: { 32413e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(Get32Static, call_inst); 324221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 324321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetWide: { 32443e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(Get64Static, call_inst); 324521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 324621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetObject: { 32473e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(GetObjectStatic, call_inst); 324821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 324921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetFast: { 325021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_SGetFast(call_inst.getArgOperand(0), 325121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 325221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 325321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kInt); 325421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 325521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetWideFast: { 325621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_SGetFast(call_inst.getArgOperand(0), 325721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 325821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 325921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kLong); 326021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 326121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetObjectFast: { 326221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_SGetFast(call_inst.getArgOperand(0), 326321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 326421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 326521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kObject); 326621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 326721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetBooleanFast: { 326821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_SGetFast(call_inst.getArgOperand(0), 326921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 327021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 327121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kBoolean); 327221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 327321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetByteFast: { 327421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_SGetFast(call_inst.getArgOperand(0), 327521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 327621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 327721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kByte); 327821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 327921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetCharFast: { 328021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_SGetFast(call_inst.getArgOperand(0), 328121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 328221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 328321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kChar); 328421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 328521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldGetShortFast: { 328621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_SGetFast(call_inst.getArgOperand(0), 328721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 328821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 328921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kShort); 329021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 329121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPut: 329221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutBoolean: 329321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutByte: 329421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutChar: 329521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutShort: { 32963e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(Set32Static, call_inst); 329721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 329821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutWide: { 32993e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(Set64Static, call_inst); 330021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 330121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutObject: { 33023e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(SetObjectStatic, call_inst); 330321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 330421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutFast: { 330521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_SPutFast(call_inst.getArgOperand(0), 330621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 330721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 330821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 330921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kInt); 331021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 331121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 331221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutWideFast: { 331321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_SPutFast(call_inst.getArgOperand(0), 331421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 331521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 331621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 331721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kLong); 331821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 331921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 332021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutObjectFast: { 332121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_SPutFast(call_inst.getArgOperand(0), 332221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 332321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 332421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 332521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kObject); 332621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 332721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 332821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutBooleanFast: { 332921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_SPutFast(call_inst.getArgOperand(0), 333021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 333121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 333221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 333321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kBoolean); 333421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 333521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 333621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutByteFast: { 333721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_SPutFast(call_inst.getArgOperand(0), 333821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 333921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 334021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 334121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kByte); 334221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 334321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 334421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutCharFast: { 334521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_SPutFast(call_inst.getArgOperand(0), 334621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 334721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 334821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 334921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kChar); 335021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 335121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 335221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::StaticFieldPutShortFast: { 335321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_SPutFast(call_inst.getArgOperand(0), 335421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(1), 335521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(2), 335621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(3), 335721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao kShort); 335821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 335921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 336021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::LoadDeclaringClassSSB: { 336121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_LoadDeclaringClassSSB(call_inst.getArgOperand(0)); 336221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 336321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::LoadClassSSBFromDexCache: { 336421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_LoadClassSSBFromDexCache(call_inst.getArgOperand(0)); 336521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 336621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InitializeAndLoadClassSSB: { 33673e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(InitializeStaticStorage, call_inst); 336821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 336975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 337075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- High-level Array -------------------------------------------------==// 337175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayGet: { 33725a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLArrayGet(call_inst, kInt); 337375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 337475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayGetBoolean: { 33755a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLArrayGet(call_inst, kBoolean); 337675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 337775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayGetByte: { 33785a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLArrayGet(call_inst, kByte); 337975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 338075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayGetChar: { 33815a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLArrayGet(call_inst, kChar); 338275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 338375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayGetShort: { 33845a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLArrayGet(call_inst, kShort); 338575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 338675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayGetFloat: { 33875a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLArrayGet(call_inst, kFloat); 338875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 338975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayGetWide: { 33905a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLArrayGet(call_inst, kLong); 339175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 339275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayGetDouble: { 33935a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLArrayGet(call_inst, kDouble); 339475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 339575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayGetObject: { 33965a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLArrayGet(call_inst, kObject); 339775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 339875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayPut: { 33995a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLArrayPut(call_inst, kInt); 340075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 340175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 340275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayPutBoolean: { 34035a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLArrayPut(call_inst, kBoolean); 340475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 340575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 340675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayPutByte: { 34075a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLArrayPut(call_inst, kByte); 340875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 340975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 341075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayPutChar: { 34115a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLArrayPut(call_inst, kChar); 341275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 341375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 341475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayPutShort: { 34155a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLArrayPut(call_inst, kShort); 341675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 341775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 341875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayPutFloat: { 34195a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLArrayPut(call_inst, kFloat); 342075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 342175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 342275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayPutWide: { 34235a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLArrayPut(call_inst, kLong); 342475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 342575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 342675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayPutDouble: { 34275a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLArrayPut(call_inst, kDouble); 342875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 342975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 343075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLArrayPutObject: { 34315a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLArrayPut(call_inst, kObject); 343275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 343375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 343475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 343575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- High-level Instance ----------------------------------------------==// 343675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIGet: { 34375e869b6560f918837cc6be3a50234deb2be46385TDYa return Expand_HLIGet(call_inst, kInt); 343875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 343975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIGetBoolean: { 34405e869b6560f918837cc6be3a50234deb2be46385TDYa return Expand_HLIGet(call_inst, kBoolean); 344175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 344275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIGetByte: { 34435e869b6560f918837cc6be3a50234deb2be46385TDYa return Expand_HLIGet(call_inst, kByte); 344475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 344575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIGetChar: { 34465e869b6560f918837cc6be3a50234deb2be46385TDYa return Expand_HLIGet(call_inst, kChar); 344775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 344875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIGetShort: { 34495e869b6560f918837cc6be3a50234deb2be46385TDYa return Expand_HLIGet(call_inst, kShort); 345075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 345175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIGetFloat: { 34525e869b6560f918837cc6be3a50234deb2be46385TDYa return Expand_HLIGet(call_inst, kFloat); 345375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 345475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIGetWide: { 34555e869b6560f918837cc6be3a50234deb2be46385TDYa return Expand_HLIGet(call_inst, kLong); 345675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 345775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIGetDouble: { 34585e869b6560f918837cc6be3a50234deb2be46385TDYa return Expand_HLIGet(call_inst, kDouble); 345975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 346075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIGetObject: { 34615e869b6560f918837cc6be3a50234deb2be46385TDYa return Expand_HLIGet(call_inst, kObject); 346275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 346375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIPut: { 34645e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_HLIPut(call_inst, kInt); 346575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 346675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 346775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIPutBoolean: { 34685e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_HLIPut(call_inst, kBoolean); 346975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 347075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 347175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIPutByte: { 34725e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_HLIPut(call_inst, kByte); 347375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 347475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 347575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIPutChar: { 34765e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_HLIPut(call_inst, kChar); 347775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 347875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 347975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIPutShort: { 34805e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_HLIPut(call_inst, kShort); 348175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 348275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 348375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIPutFloat: { 34845e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_HLIPut(call_inst, kFloat); 348575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 348675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 348775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIPutWide: { 34885e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_HLIPut(call_inst, kLong); 348975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 349075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 349175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIPutDouble: { 34925e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_HLIPut(call_inst, kDouble); 349375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 349475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 349575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLIPutObject: { 34965e869b6560f918837cc6be3a50234deb2be46385TDYa Expand_HLIPut(call_inst, kObject); 349775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 349875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 349975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 350075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- High-level Invoke ------------------------------------------------==// 3501f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa case IntrinsicHelper::HLInvokeVoid: 3502f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa case IntrinsicHelper::HLInvokeObj: 3503f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa case IntrinsicHelper::HLInvokeInt: 3504f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa case IntrinsicHelper::HLInvokeFloat: 3505f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa case IntrinsicHelper::HLInvokeLong: 350675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLInvokeDouble: { 3507f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa return Expand_HLInvoke(call_inst); 350875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 350975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 351021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Invoke -----------------------------------------------------------==// 351121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::FindStaticMethodWithAccessCheck: { 35123e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(FindStaticMethodWithAccessCheck, call_inst); 351321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 351421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::FindDirectMethodWithAccessCheck: { 35153e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(FindDirectMethodWithAccessCheck, call_inst); 351621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 351721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::FindVirtualMethodWithAccessCheck: { 35183e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(FindVirtualMethodWithAccessCheck, call_inst); 351921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 352021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::FindSuperMethodWithAccessCheck: { 35213e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(FindSuperMethodWithAccessCheck, call_inst); 352221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 352321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::FindInterfaceMethodWithAccessCheck: { 35243e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(FindInterfaceMethodWithAccessCheck, call_inst); 352521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 352621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::GetSDCalleeMethodObjAddrFast: { 352721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_GetSDCalleeMethodObjAddrFast(call_inst.getArgOperand(0)); 352821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 352921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::GetVirtualCalleeMethodObjAddrFast: { 353021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_GetVirtualCalleeMethodObjAddrFast( 353121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao call_inst.getArgOperand(0), call_inst.getArgOperand(1)); 353221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 353321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::GetInterfaceCalleeMethodObjAddrFast: { 35343e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(FindInterfaceMethod, call_inst); 353521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 353621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetVoid: 353721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetBoolean: 353821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetByte: 353921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetChar: 354021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetShort: 354121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetInt: 354221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetLong: 354321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetFloat: 354421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetDouble: 354521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::InvokeRetObject: { 354621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return Expand_Invoke(call_inst); 354721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 354875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 354921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Math -------------------------------------------------------------==// 355021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::DivInt: { 35514ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa return Expand_DivRem(call_inst, /* is_div */true, kInt); 355221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 355321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::RemInt: { 35544ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa return Expand_DivRem(call_inst, /* is_div */false, kInt); 355521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 355621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::DivLong: { 35574ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa return Expand_DivRem(call_inst, /* is_div */true, kLong); 355821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 355921d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::RemLong: { 35604ec8ccdaeee1c4af1a70e1ac0dd482e83df72f38TDYa return Expand_DivRem(call_inst, /* is_div */false, kLong); 356121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 356221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::D2L: { 35633e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(art_d2l, call_inst); 356421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 356521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::D2I: { 35663e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(art_d2i, call_inst); 356721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 356821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::F2L: { 35693e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(art_f2l, call_inst); 357021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 357121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::F2I: { 35723e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstrom return ExpandToRuntime(art_f2i, call_inst); 357321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 357475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 357575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- High-level Static ------------------------------------------------==// 357675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSget: { 35775a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLSget(call_inst, kInt); 357875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 357975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSgetBoolean: { 35805a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLSget(call_inst, kBoolean); 358175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 358275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSgetByte: { 35835a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLSget(call_inst, kByte); 358475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 358575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSgetChar: { 35865a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLSget(call_inst, kChar); 358775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 358875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSgetShort: { 35895a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLSget(call_inst, kShort); 359075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 359175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSgetFloat: { 35925a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLSget(call_inst, kFloat); 359375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 359475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSgetWide: { 35955a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLSget(call_inst, kLong); 359675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 359775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSgetDouble: { 35985a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLSget(call_inst, kDouble); 359975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 360075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSgetObject: { 36015a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa return Expand_HLSget(call_inst, kObject); 360275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 360375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSput: { 36045a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLSput(call_inst, kInt); 360575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 360675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 360775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSputBoolean: { 36085a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLSput(call_inst, kBoolean); 360975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 361075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 361175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSputByte: { 36125a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLSput(call_inst, kByte); 361375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 361475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 361575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSputChar: { 36165a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLSput(call_inst, kChar); 361775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 361875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 361975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSputShort: { 36205a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLSput(call_inst, kShort); 362175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 362275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 362375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSputFloat: { 36245a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLSput(call_inst, kFloat); 362575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 362675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 362775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSputWide: { 36285a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLSput(call_inst, kLong); 362975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 363075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 363175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSputDouble: { 36325a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLSput(call_inst, kDouble); 363375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 363475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 363575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::HLSputObject: { 36365a26d44dc8e6fe59a3619ee5951a54bc53d7c9f1TDYa Expand_HLSput(call_inst, kObject); 363775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 363875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 363975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 364075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- High-level Monitor -----------------------------------------------==// 364175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::MonitorEnter: { 3642f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa Expand_MonitorEnter(call_inst); 364375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 364475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 364575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::MonitorExit: { 3646f71bf5ad4e1872e4dfc71de65641ed518e2b38daTDYa Expand_MonitorExit(call_inst); 364775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 364875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 364975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 365021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao //==- Shadow Frame -----------------------------------------------------==// 365121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::AllocaShadowFrame: { 3652ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa Expand_AllocaShadowFrame(call_inst.getArgOperand(0)); 365321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 365421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 36558e950c117975d23f50ed7e32ca5db01a813c25d0TDYa case IntrinsicHelper::SetVReg: { 36568e950c117975d23f50ed7e32ca5db01a813c25d0TDYa Expand_SetVReg(call_inst.getArgOperand(0), 36578e950c117975d23f50ed7e32ca5db01a813c25d0TDYa call_inst.getArgOperand(1)); 36588e950c117975d23f50ed7e32ca5db01a813c25d0TDYa return NULL; 36598e950c117975d23f50ed7e32ca5db01a813c25d0TDYa } 366021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::PopShadowFrame: { 366121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_PopShadowFrame(); 366221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 366321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 366421d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao case IntrinsicHelper::UpdateDexPC: { 366521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao Expand_UpdateDexPC(call_inst.getArgOperand(0)); 366621d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 366721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 3668a1b2185820e6080864d18a35759cc046dc4ee578TDYa 366975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Comparison -------------------------------------------------------==// 3670a1b2185820e6080864d18a35759cc046dc4ee578TDYa case IntrinsicHelper::CmplFloat: 3671a1b2185820e6080864d18a35759cc046dc4ee578TDYa case IntrinsicHelper::CmplDouble: { 367275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return Expand_FPCompare(call_inst.getArgOperand(0), 367375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien call_inst.getArgOperand(1), 367475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien false); 3675a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 3676a1b2185820e6080864d18a35759cc046dc4ee578TDYa case IntrinsicHelper::CmpgFloat: 3677a1b2185820e6080864d18a35759cc046dc4ee578TDYa case IntrinsicHelper::CmpgDouble: { 367875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return Expand_FPCompare(call_inst.getArgOperand(0), 367975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien call_inst.getArgOperand(1), 368075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien true); 3681a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 3682a1b2185820e6080864d18a35759cc046dc4ee578TDYa case IntrinsicHelper::CmpLong: { 368375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return Expand_LongCompare(call_inst.getArgOperand(0), 368475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien call_inst.getArgOperand(1)); 368575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 368675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 368775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Const ------------------------------------------------------------==// 3688920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::ConstInt: 3689920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::ConstLong: { 3690d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien return call_inst.getArgOperand(0); 369175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 3692920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::ConstFloat: { 3693d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien return irb_.CreateBitCast(call_inst.getArgOperand(0), 3694d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien irb_.getJFloatTy()); 369575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 3696920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::ConstDouble: { 3697d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien return irb_.CreateBitCast(call_inst.getArgOperand(0), 3698d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien irb_.getJDoubleTy()); 3699d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien } 3700920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::ConstObj: { 37014274889d48ef82369bf2c1ca70d84689b4f9e93aBrian Carlstrom CHECK_EQ(LV2UInt(call_inst.getArgOperand(0)), 0U); 3702bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao return irb_.getJNull(); 3703a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 370475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 370575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Method Info ------------------------------------------------------==// 3706920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::MethodInfo: { 3707b259652a72293b4bd3c346bb0e40fb8a7f878fa2Shih-wei Liao // Nothing to be done, because MethodInfo carries optional hints that are 3708b259652a72293b4bd3c346bb0e40fb8a7f878fa2Shih-wei Liao // not needed by the portable path. 370975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return NULL; 371075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 371175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 371275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Copy -------------------------------------------------------------==// 3713920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::CopyInt: 3714920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::CopyFloat: 3715920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::CopyLong: 3716920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::CopyDouble: 3717920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::CopyObj: { 3718d54a23d0bfe93e4b0d14d857ac9cc0d317a1c4bbLogan Chien return call_inst.getArgOperand(0); 371975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 372075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 372175e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Shift ------------------------------------------------------------==// 3722920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::SHLLong: { 372375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return Expand_IntegerShift(call_inst.getArgOperand(0), 372475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien call_inst.getArgOperand(1), 372575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien kIntegerSHL, kLong); 3726a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 3727920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::SHRLong: { 372875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return Expand_IntegerShift(call_inst.getArgOperand(0), 372975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien call_inst.getArgOperand(1), 373075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien kIntegerSHR, kLong); 3731a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 3732920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::USHRLong: { 373375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return Expand_IntegerShift(call_inst.getArgOperand(0), 373475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien call_inst.getArgOperand(1), 373575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien kIntegerUSHR, kLong); 3736a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 3737920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::SHLInt: { 373875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return Expand_IntegerShift(call_inst.getArgOperand(0), 373975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien call_inst.getArgOperand(1), 374075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien kIntegerSHL, kInt); 3741a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 3742920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::SHRInt: { 374375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return Expand_IntegerShift(call_inst.getArgOperand(0), 374475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien call_inst.getArgOperand(1), 374575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien kIntegerSHR, kInt); 3746a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 3747920be7cac2aa06f9d5c8b2db87db116b1cad3159TDYa case IntrinsicHelper::USHRInt: { 374875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return Expand_IntegerShift(call_inst.getArgOperand(0), 374975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien call_inst.getArgOperand(1), 375075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien kIntegerUSHR, kInt); 3751a1b2185820e6080864d18a35759cc046dc4ee578TDYa } 375221d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 375375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Conversion -------------------------------------------------------==// 375475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::IntToChar: { 375575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return irb_.CreateZExt(irb_.CreateTrunc(call_inst.getArgOperand(0), irb_.getJCharTy()), 375675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien irb_.getJIntTy()); 375775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 375875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::IntToShort: { 375975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return irb_.CreateSExt(irb_.CreateTrunc(call_inst.getArgOperand(0), irb_.getJShortTy()), 376075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien irb_.getJIntTy()); 376121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 376275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::IntToByte: { 376375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien return irb_.CreateSExt(irb_.CreateTrunc(call_inst.getArgOperand(0), irb_.getJByteTy()), 376475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien irb_.getJIntTy()); 376575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien } 376675e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien 376787caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa //==- Exception --------------------------------------------------------==// 376887caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa case IntrinsicHelper::CatchTargets: { 376955e5e6c5702e3f1f68bd83ae741af769740d9a74TDYa UpdatePhiInstruction(current_bb_, irb_.GetInsertBlock()); 377087caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa llvm::SwitchInst* si = llvm::dyn_cast<llvm::SwitchInst>(call_inst.getNextNode()); 377187caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa CHECK(si != NULL); 377287caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa irb_.CreateBr(si->getDefaultDest()); 377387caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa si->eraseFromParent(); 377487caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa return call_inst.getArgOperand(0); 377587caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa } 377687caa7e1eb7a9ed56285062ef2feb650d42e3bb6TDYa 37770d43d5465f43eb8838e8ad3c02045d4d8c7ee380Sebastien Hertz //==- Constructor barrier-----------------------------------------------==// 37780d43d5465f43eb8838e8ad3c02045d4d8c7ee380Sebastien Hertz case IntrinsicHelper::ConstructorBarrier: { 37790d43d5465f43eb8838e8ad3c02045d4d8c7ee380Sebastien Hertz irb_.CreateMemoryBarrier(art::kStoreStore); 37800d43d5465f43eb8838e8ad3c02045d4d8c7ee380Sebastien Hertz return NULL; 37810d43d5465f43eb8838e8ad3c02045d4d8c7ee380Sebastien Hertz } 37820d43d5465f43eb8838e8ad3c02045d4d8c7ee380Sebastien Hertz 378375e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien //==- Unknown Cases ----------------------------------------------------==// 378475e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::MaxIntrinsicId: 378575e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien case IntrinsicHelper::UnknownId: 37867934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom // default: 378775e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien // NOTE: "default" is intentionally commented so that C/C++ compiler will 378875e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien // give some warning on unmatched cases. 378975e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien // NOTE: We should not implement these cases. 379075e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien break; 379121d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao } 379275e4b60d28355d4c33d50093d9d2603ffdea82dcLogan Chien UNIMPLEMENTED(FATAL) << "Unexpected GBC intrinsic: " << static_cast<int>(intr_id); 379321d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao return NULL; 37941895ea386ca78573302483f589ebabd8ce1480e7Brian Carlstrom} // NOLINT(readability/fn_size) 379521d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 37967934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom} // anonymous namespace 379721d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 379821d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liaonamespace art { 37994c1c283a7410784e9cab309f868248690b788a9cIan Rogersnamespace llvm { 380021d28f510eb590f52810c83f1f3f37fe5f4adf46Shih-wei Liao 38014c1c283a7410784e9cab309f868248690b788a9cIan Rogers::llvm::FunctionPass* 3802bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei LiaoCreateGBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb, 3803265091e581c9f643b37e7966890911f09e223269Brian Carlstrom CompilerDriver* driver, const DexCompilationUnit* dex_compilation_unit) { 380489756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogers return new GBCExpanderPass(intrinsic_helper, irb, driver, dex_compilation_unit); 3805bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao} 3806bb33f2fa8e462937574a8cd1b744b86c2f762571Shih-wei Liao 38077934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom} // namespace llvm 38087934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom} // namespace art 3809