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