blob: cedf3b7530039d007d6e485acf39a792448ffc96 [file] [log] [blame]
buzbee2cfc6392012-05-07 14:51:40 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
buzbee2cfc6392012-05-07 14:51:40 -070017#include "object_utils.h"
18
19#include <llvm/Support/ToolOutputFile.h>
20#include <llvm/Bitcode/ReaderWriter.h>
21#include <llvm/Analysis/Verifier.h>
22#include <llvm/Metadata.h>
23#include <llvm/ADT/DepthFirstIterator.h>
24#include <llvm/Instruction.h>
25#include <llvm/Type.h>
26#include <llvm/Instructions.h>
27#include <llvm/Support/Casting.h>
buzbeead8f15e2012-06-18 14:49:45 -070028#include <llvm/Support/InstIterator.h>
buzbee2cfc6392012-05-07 14:51:40 -070029
buzbee1bc37c62012-11-20 13:35:41 -080030#include "../compiler_internals.h"
buzbeeeaf09bc2012-11-15 14:51:41 -080031#include "method_codegen_driver.h"
32#include "local_optimizations.h"
buzbee1bc37c62012-11-20 13:35:41 -080033#include "codegen_util.h"
34#include "ralloc_util.h"
buzbeeeaf09bc2012-11-15 14:51:41 -080035
buzbee8320f382012-09-11 16:29:42 -070036static const char* kLabelFormat = "%c0x%x_%d";
buzbee951c0a12012-10-03 16:31:39 -070037static const char kInvalidBlock = 0xff;
buzbee8320f382012-09-11 16:29:42 -070038static const char kNormalBlock = 'L';
39static const char kCatchBlock = 'C';
buzbee2cfc6392012-05-07 14:51:40 -070040
41namespace art {
buzbeefa57c472012-11-21 12:06:18 -080042// TODO: unify bad_loc
43const RegLocation bad_loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0,
buzbee1bc37c62012-11-20 13:35:41 -080044 INVALID_REG, INVALID_REG, INVALID_SREG,
45 INVALID_SREG};
buzbeefa57c472012-11-21 12:06:18 -080046static RegLocation GetLoc(CompilationUnit* cu, llvm::Value* val);
buzbee2cfc6392012-05-07 14:51:40 -070047
buzbeefa57c472012-11-21 12:06:18 -080048static llvm::BasicBlock* GetLLVMBlock(CompilationUnit* cu, int id)
buzbee2cfc6392012-05-07 14:51:40 -070049{
buzbeefa57c472012-11-21 12:06:18 -080050 return cu->id_to_block_map.Get(id);
buzbee2cfc6392012-05-07 14:51:40 -070051}
52
buzbeefa57c472012-11-21 12:06:18 -080053static llvm::Value* GetLLVMValue(CompilationUnit* cu, int s_reg)
buzbee2cfc6392012-05-07 14:51:40 -070054{
buzbeefa57c472012-11-21 12:06:18 -080055 return reinterpret_cast<llvm::Value*>(GrowableListGetElement(&cu->llvm_values, s_reg));
buzbee2cfc6392012-05-07 14:51:40 -070056}
57
58// Replace the placeholder value with the real definition
buzbeefa57c472012-11-21 12:06:18 -080059static void DefineValue(CompilationUnit* cu, llvm::Value* val, int s_reg)
buzbee2cfc6392012-05-07 14:51:40 -070060{
buzbeefa57c472012-11-21 12:06:18 -080061 llvm::Value* placeholder = GetLLVMValue(cu, s_reg);
buzbee9a2487f2012-07-26 14:01:13 -070062 if (placeholder == NULL) {
63 // This can happen on instruction rewrite on verification failure
Bill Buzbeec9f40dd2012-08-15 11:35:25 -070064 LOG(WARNING) << "Null placeholder";
buzbee9a2487f2012-07-26 14:01:13 -070065 return;
66 }
buzbee2cfc6392012-05-07 14:51:40 -070067 placeholder->replaceAllUsesWith(val);
68 val->takeName(placeholder);
buzbeefa57c472012-11-21 12:06:18 -080069 cu->llvm_values.elem_list[s_reg] = reinterpret_cast<uintptr_t>(val);
buzbee4be777b2012-07-12 14:38:18 -070070 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(placeholder);
71 DCHECK(inst != NULL);
72 inst->eraseFromParent();
TDYa1278e950c12012-11-02 09:58:19 -070073
74 // Set vreg for debugging
buzbeefa57c472012-11-21 12:06:18 -080075 if (!cu->compiler->IsDebuggingSupported()) {
TDYa1278e950c12012-11-02 09:58:19 -070076 greenland::IntrinsicHelper::IntrinsicId id =
77 greenland::IntrinsicHelper::SetVReg;
buzbeefa57c472012-11-21 12:06:18 -080078 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id);
79 int v_reg = SRegToVReg(cu, s_reg);
80 llvm::Value* table_slot = cu->irb->getInt32(v_reg);
81 llvm::Value* args[] = { table_slot, val };
82 cu->irb->CreateCall(func, args);
TDYa1278e950c12012-11-02 09:58:19 -070083 }
buzbee2cfc6392012-05-07 14:51:40 -070084}
85
buzbeefa57c472012-11-21 12:06:18 -080086static llvm::Type* LlvmTypeFromLocRec(CompilationUnit* cu, RegLocation loc)
buzbee2cfc6392012-05-07 14:51:40 -070087{
88 llvm::Type* res = NULL;
89 if (loc.wide) {
90 if (loc.fp)
buzbeefa57c472012-11-21 12:06:18 -080091 res = cu->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070092 else
buzbeefa57c472012-11-21 12:06:18 -080093 res = cu->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070094 } else {
95 if (loc.fp) {
buzbeefa57c472012-11-21 12:06:18 -080096 res = cu->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -070097 } else {
98 if (loc.ref)
buzbeefa57c472012-11-21 12:06:18 -080099 res = cu->irb->GetJObjectTy();
buzbee2cfc6392012-05-07 14:51:40 -0700100 else
buzbeefa57c472012-11-21 12:06:18 -0800101 res = cu->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -0700102 }
103 }
104 return res;
105}
106
buzbeead8f15e2012-06-18 14:49:45 -0700107/* Create an in-memory RegLocation from an llvm Value. */
buzbeefa57c472012-11-21 12:06:18 -0800108static void CreateLocFromValue(CompilationUnit* cu, llvm::Value* val)
buzbeead8f15e2012-06-18 14:49:45 -0700109{
110 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
111 std::string s(val->getName().str());
buzbeefa57c472012-11-21 12:06:18 -0800112 const char* val_name = s.c_str();
113 SafeMap<llvm::Value*, RegLocation>::iterator it = cu->loc_map.find(val);
114 DCHECK(it == cu->loc_map.end()) << " - already defined: " << val_name;
115 int base_sreg = INVALID_SREG;
buzbeead8f15e2012-06-18 14:49:45 -0700116 int subscript = -1;
buzbeefa57c472012-11-21 12:06:18 -0800117 sscanf(val_name, "v%d_%d", &base_sreg, &subscript);
118 if ((base_sreg == INVALID_SREG) && (!strcmp(val_name, "method"))) {
119 base_sreg = SSA_METHOD_BASEREG;
buzbeead8f15e2012-06-18 14:49:45 -0700120 subscript = 0;
121 }
buzbeefa57c472012-11-21 12:06:18 -0800122 DCHECK_NE(base_sreg, INVALID_SREG);
buzbeead8f15e2012-06-18 14:49:45 -0700123 DCHECK_NE(subscript, -1);
124 // TODO: redo during C++'ification
125 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
126 INVALID_REG, INVALID_SREG, INVALID_SREG};
127 llvm::Type* ty = val->getType();
buzbeefa57c472012-11-21 12:06:18 -0800128 loc.wide = ((ty == cu->irb->getInt64Ty()) ||
129 (ty == cu->irb->getDoubleTy()));
buzbeead8f15e2012-06-18 14:49:45 -0700130 loc.defined = true;
buzbeeca7a5e42012-08-20 11:12:18 -0700131 loc.home = false; // May change during promotion
buzbeefa57c472012-11-21 12:06:18 -0800132 loc.s_reg_low = base_sreg;
133 loc.orig_sreg = cu->loc_map.size();
134 PromotionMap p_map = cu->promotion_map[base_sreg];
135 if (ty == cu->irb->getFloatTy()) {
buzbeeca7a5e42012-08-20 11:12:18 -0700136 loc.fp = true;
buzbeefa57c472012-11-21 12:06:18 -0800137 if (p_map.fp_location == kLocPhysReg) {
138 loc.low_reg = p_map.FpReg;
buzbeeca7a5e42012-08-20 11:12:18 -0700139 loc.location = kLocPhysReg;
140 loc.home = true;
141 }
buzbeefa57c472012-11-21 12:06:18 -0800142 } else if (ty == cu->irb->getDoubleTy()) {
buzbeeca7a5e42012-08-20 11:12:18 -0700143 loc.fp = true;
buzbeefa57c472012-11-21 12:06:18 -0800144 PromotionMap p_map_high = cu->promotion_map[base_sreg + 1];
145 if ((p_map.fp_location == kLocPhysReg) &&
146 (p_map_high.fp_location == kLocPhysReg) &&
147 ((p_map.FpReg & 0x1) == 0) &&
148 (p_map.FpReg + 1 == p_map_high.FpReg)) {
149 loc.low_reg = p_map.FpReg;
150 loc.high_reg = p_map_high.FpReg;
buzbeeca7a5e42012-08-20 11:12:18 -0700151 loc.location = kLocPhysReg;
152 loc.home = true;
153 }
buzbeefa57c472012-11-21 12:06:18 -0800154 } else if (ty == cu->irb->GetJObjectTy()) {
buzbeeca7a5e42012-08-20 11:12:18 -0700155 loc.ref = true;
buzbeefa57c472012-11-21 12:06:18 -0800156 if (p_map.core_location == kLocPhysReg) {
157 loc.low_reg = p_map.core_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700158 loc.location = kLocPhysReg;
159 loc.home = true;
160 }
buzbeefa57c472012-11-21 12:06:18 -0800161 } else if (ty == cu->irb->getInt64Ty()) {
buzbeeca7a5e42012-08-20 11:12:18 -0700162 loc.core = true;
buzbeefa57c472012-11-21 12:06:18 -0800163 PromotionMap p_map_high = cu->promotion_map[base_sreg + 1];
164 if ((p_map.core_location == kLocPhysReg) &&
165 (p_map_high.core_location == kLocPhysReg)) {
166 loc.low_reg = p_map.core_reg;
167 loc.high_reg = p_map_high.core_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700168 loc.location = kLocPhysReg;
169 loc.home = true;
170 }
171 } else {
172 loc.core = true;
buzbeefa57c472012-11-21 12:06:18 -0800173 if (p_map.core_location == kLocPhysReg) {
174 loc.low_reg = p_map.core_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700175 loc.location = kLocPhysReg;
176 loc.home = true;
177 }
178 }
179
buzbeefa57c472012-11-21 12:06:18 -0800180 if (cu->verbose && loc.home) {
buzbeeca7a5e42012-08-20 11:12:18 -0700181 if (loc.wide) {
buzbeefa57c472012-11-21 12:06:18 -0800182 LOG(INFO) << "Promoted wide " << s << " to regs " << loc.low_reg << "/" << loc.high_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700183 } else {
buzbeefa57c472012-11-21 12:06:18 -0800184 LOG(INFO) << "Promoted " << s << " to reg " << loc.low_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700185 }
186 }
buzbeefa57c472012-11-21 12:06:18 -0800187 cu->loc_map.Put(val, loc);
buzbeead8f15e2012-06-18 14:49:45 -0700188}
buzbeeaad94382012-11-21 07:40:50 -0800189
buzbeefa57c472012-11-21 12:06:18 -0800190static void InitIR(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -0700191{
buzbeefa57c472012-11-21 12:06:18 -0800192 LLVMInfo* llvm_info = cu->llvm_info;
193 if (llvm_info == NULL) {
194 CompilerTls* tls = cu->compiler->GetTls();
buzbee4df2bbd2012-10-11 14:46:06 -0700195 CHECK(tls != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800196 llvm_info = static_cast<LLVMInfo*>(tls->GetLLVMInfo());
197 if (llvm_info == NULL) {
198 llvm_info = new LLVMInfo();
199 tls->SetLLVMInfo(llvm_info);
buzbee4df2bbd2012-10-11 14:46:06 -0700200 }
201 }
buzbeefa57c472012-11-21 12:06:18 -0800202 cu->context = llvm_info->GetLLVMContext();
203 cu->module = llvm_info->GetLLVMModule();
204 cu->intrinsic_helper = llvm_info->GetIntrinsicHelper();
205 cu->irb = llvm_info->GetIRBuilder();
buzbee2cfc6392012-05-07 14:51:40 -0700206}
207
buzbeefa57c472012-11-21 12:06:18 -0800208static const char* LlvmSSAName(CompilationUnit* cu, int ssa_reg) {
209 return GET_ELEM_N(cu->ssa_strings, char*, ssa_reg);
buzbee2cfc6392012-05-07 14:51:40 -0700210}
211
buzbeefa57c472012-11-21 12:06:18 -0800212llvm::BasicBlock* FindCaseTarget(CompilationUnit* cu, uint32_t vaddr)
buzbeef58c12c2012-07-03 15:06:29 -0700213{
buzbeefa57c472012-11-21 12:06:18 -0800214 BasicBlock* bb = FindBlock(cu, vaddr);
buzbeef58c12c2012-07-03 15:06:29 -0700215 DCHECK(bb != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800216 return GetLLVMBlock(cu, bb->id);
buzbeef58c12c2012-07-03 15:06:29 -0700217}
218
buzbeefa57c472012-11-21 12:06:18 -0800219static void ConvertPackedSwitch(CompilationUnit* cu, BasicBlock* bb,
220 int32_t table_offset, RegLocation rl_src)
buzbeef58c12c2012-07-03 15:06:29 -0700221{
222 const Instruction::PackedSwitchPayload* payload =
223 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
buzbeefa57c472012-11-21 12:06:18 -0800224 cu->insns + cu->current_dalvik_offset + table_offset);
buzbeef58c12c2012-07-03 15:06:29 -0700225
buzbeefa57c472012-11-21 12:06:18 -0800226 llvm::Value* value = GetLLVMValue(cu, rl_src.orig_sreg);
buzbeef58c12c2012-07-03 15:06:29 -0700227
228 llvm::SwitchInst* sw =
buzbeefa57c472012-11-21 12:06:18 -0800229 cu->irb->CreateSwitch(value, GetLLVMBlock(cu, bb->fall_through->id),
buzbeef58c12c2012-07-03 15:06:29 -0700230 payload->case_count);
231
232 for (uint16_t i = 0; i < payload->case_count; ++i) {
buzbeefa57c472012-11-21 12:06:18 -0800233 llvm::BasicBlock* llvm_bb =
234 FindCaseTarget(cu, cu->current_dalvik_offset + payload->targets[i]);
235 sw->addCase(cu->irb->getInt32(payload->first_key + i), llvm_bb);
buzbeef58c12c2012-07-03 15:06:29 -0700236 }
buzbeefa57c472012-11-21 12:06:18 -0800237 llvm::MDNode* switch_node =
238 llvm::MDNode::get(*cu->context, cu->irb->getInt32(table_offset));
239 sw->setMetadata("SwitchTable", switch_node);
buzbeef58c12c2012-07-03 15:06:29 -0700240 bb->taken = NULL;
buzbeefa57c472012-11-21 12:06:18 -0800241 bb->fall_through = NULL;
buzbeef58c12c2012-07-03 15:06:29 -0700242}
243
buzbeefa57c472012-11-21 12:06:18 -0800244static void ConvertSparseSwitch(CompilationUnit* cu, BasicBlock* bb,
245 int32_t table_offset, RegLocation rl_src)
buzbeea1da8a52012-07-09 14:00:21 -0700246{
247 const Instruction::SparseSwitchPayload* payload =
248 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
buzbeefa57c472012-11-21 12:06:18 -0800249 cu->insns + cu->current_dalvik_offset + table_offset);
buzbeea1da8a52012-07-09 14:00:21 -0700250
251 const int32_t* keys = payload->GetKeys();
252 const int32_t* targets = payload->GetTargets();
253
buzbeefa57c472012-11-21 12:06:18 -0800254 llvm::Value* value = GetLLVMValue(cu, rl_src.orig_sreg);
buzbeea1da8a52012-07-09 14:00:21 -0700255
256 llvm::SwitchInst* sw =
buzbeefa57c472012-11-21 12:06:18 -0800257 cu->irb->CreateSwitch(value, GetLLVMBlock(cu, bb->fall_through->id),
buzbeea1da8a52012-07-09 14:00:21 -0700258 payload->case_count);
259
260 for (size_t i = 0; i < payload->case_count; ++i) {
buzbeefa57c472012-11-21 12:06:18 -0800261 llvm::BasicBlock* llvm_bb =
262 FindCaseTarget(cu, cu->current_dalvik_offset + targets[i]);
263 sw->addCase(cu->irb->getInt32(keys[i]), llvm_bb);
buzbeea1da8a52012-07-09 14:00:21 -0700264 }
buzbeefa57c472012-11-21 12:06:18 -0800265 llvm::MDNode* switch_node =
266 llvm::MDNode::get(*cu->context, cu->irb->getInt32(table_offset));
267 sw->setMetadata("SwitchTable", switch_node);
buzbeea1da8a52012-07-09 14:00:21 -0700268 bb->taken = NULL;
buzbeefa57c472012-11-21 12:06:18 -0800269 bb->fall_through = NULL;
buzbeea1da8a52012-07-09 14:00:21 -0700270}
271
buzbeefa57c472012-11-21 12:06:18 -0800272static void ConvertSget(CompilationUnit* cu, int32_t field_index,
273 greenland::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest)
buzbee4f1181f2012-06-22 13:52:12 -0700274{
buzbeefa57c472012-11-21 12:06:18 -0800275 llvm::Constant* field_idx = cu->irb->getInt32(field_index);
276 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
277 llvm::Value* res = cu->irb->CreateCall(intr, field_idx);
278 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700279}
280
buzbeefa57c472012-11-21 12:06:18 -0800281static void ConvertSput(CompilationUnit* cu, int32_t field_index,
282 greenland::IntrinsicHelper::IntrinsicId id, RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700283{
284 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800285 args.push_back(cu->irb->getInt32(field_index));
286 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
287 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
288 cu->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700289}
290
buzbeefa57c472012-11-21 12:06:18 -0800291static void ConvertFillArrayData(CompilationUnit* cu, int32_t offset, RegLocation rl_array)
buzbee101305f2012-06-28 18:00:56 -0700292{
293 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700294 id = greenland::IntrinsicHelper::HLFillArrayData;
buzbee101305f2012-06-28 18:00:56 -0700295 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800296 args.push_back(cu->irb->getInt32(offset));
297 args.push_back(GetLLVMValue(cu, rl_array.orig_sreg));
298 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
299 cu->irb->CreateCall(intr, args);
buzbee101305f2012-06-28 18:00:56 -0700300}
301
buzbeefa57c472012-11-21 12:06:18 -0800302static llvm::Value* EmitConst(CompilationUnit* cu, llvm::ArrayRef<llvm::Value*> src,
buzbeeaad94382012-11-21 07:40:50 -0800303 RegLocation loc)
buzbee2cfc6392012-05-07 14:51:40 -0700304{
305 greenland::IntrinsicHelper::IntrinsicId id;
306 if (loc.wide) {
307 if (loc.fp) {
308 id = greenland::IntrinsicHelper::ConstDouble;
309 } else {
310 id = greenland::IntrinsicHelper::ConstLong;
311 }
312 } else {
313 if (loc.fp) {
314 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700315 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700316 id = greenland::IntrinsicHelper::ConstObj;
317 } else {
318 id = greenland::IntrinsicHelper::ConstInt;
319 }
320 }
buzbeefa57c472012-11-21 12:06:18 -0800321 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
322 return cu->irb->CreateCall(intr, src);
buzbee2cfc6392012-05-07 14:51:40 -0700323}
buzbeeb03f4872012-06-11 15:22:11 -0700324
buzbeefa57c472012-11-21 12:06:18 -0800325static void EmitPopShadowFrame(CompilationUnit* cu)
buzbeeb03f4872012-06-11 15:22:11 -0700326{
buzbeefa57c472012-11-21 12:06:18 -0800327 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(
buzbeeb03f4872012-06-11 15:22:11 -0700328 greenland::IntrinsicHelper::PopShadowFrame);
buzbeefa57c472012-11-21 12:06:18 -0800329 cu->irb->CreateCall(intr);
buzbeeb03f4872012-06-11 15:22:11 -0700330}
331
buzbeefa57c472012-11-21 12:06:18 -0800332static llvm::Value* EmitCopy(CompilationUnit* cu, llvm::ArrayRef<llvm::Value*> src,
buzbeeaad94382012-11-21 07:40:50 -0800333 RegLocation loc)
buzbee2cfc6392012-05-07 14:51:40 -0700334{
335 greenland::IntrinsicHelper::IntrinsicId id;
336 if (loc.wide) {
337 if (loc.fp) {
338 id = greenland::IntrinsicHelper::CopyDouble;
339 } else {
340 id = greenland::IntrinsicHelper::CopyLong;
341 }
342 } else {
343 if (loc.fp) {
344 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700345 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700346 id = greenland::IntrinsicHelper::CopyObj;
347 } else {
348 id = greenland::IntrinsicHelper::CopyInt;
349 }
350 }
buzbeefa57c472012-11-21 12:06:18 -0800351 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
352 return cu->irb->CreateCall(intr, src);
buzbee2cfc6392012-05-07 14:51:40 -0700353}
354
buzbeefa57c472012-11-21 12:06:18 -0800355static void ConvertMoveException(CompilationUnit* cu, RegLocation rl_dest)
buzbee32412962012-06-26 16:27:56 -0700356{
buzbeefa57c472012-11-21 12:06:18 -0800357 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(
buzbee32412962012-06-26 16:27:56 -0700358 greenland::IntrinsicHelper::GetException);
buzbeefa57c472012-11-21 12:06:18 -0800359 llvm::Value* res = cu->irb->CreateCall(func);
360 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee32412962012-06-26 16:27:56 -0700361}
362
buzbeefa57c472012-11-21 12:06:18 -0800363static void ConvertThrow(CompilationUnit* cu, RegLocation rl_src)
buzbee32412962012-06-26 16:27:56 -0700364{
buzbeefa57c472012-11-21 12:06:18 -0800365 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
366 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(
TDYa127f71bf5a2012-07-29 20:09:52 -0700367 greenland::IntrinsicHelper::HLThrowException);
buzbeefa57c472012-11-21 12:06:18 -0800368 cu->irb->CreateCall(func, src);
buzbee32412962012-06-26 16:27:56 -0700369}
370
buzbeefa57c472012-11-21 12:06:18 -0800371static void ConvertMonitorEnterExit(CompilationUnit* cu, int opt_flags,
buzbeeaad94382012-11-21 07:40:50 -0800372 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800373 RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700374{
375 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800376 args.push_back(cu->irb->getInt32(opt_flags));
377 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
378 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id);
379 cu->irb->CreateCall(func, args);
buzbee8fa0fda2012-06-27 15:44:52 -0700380}
381
buzbeefa57c472012-11-21 12:06:18 -0800382static void ConvertArrayLength(CompilationUnit* cu, int opt_flags,
383 RegLocation rl_dest, RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700384{
385 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800386 args.push_back(cu->irb->getInt32(opt_flags));
387 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
388 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700389 greenland::IntrinsicHelper::OptArrayLength);
buzbeefa57c472012-11-21 12:06:18 -0800390 llvm::Value* res = cu->irb->CreateCall(func, args);
391 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700392}
393
buzbeefa57c472012-11-21 12:06:18 -0800394static void EmitSuspendCheck(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -0700395{
396 greenland::IntrinsicHelper::IntrinsicId id =
397 greenland::IntrinsicHelper::CheckSuspend;
buzbeefa57c472012-11-21 12:06:18 -0800398 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
399 cu->irb->CreateCall(intr);
buzbee2cfc6392012-05-07 14:51:40 -0700400}
401
buzbeefa57c472012-11-21 12:06:18 -0800402static llvm::Value* ConvertCompare(CompilationUnit* cu, ConditionCode cc,
buzbeeaad94382012-11-21 07:40:50 -0800403 llvm::Value* src1, llvm::Value* src2)
buzbee2cfc6392012-05-07 14:51:40 -0700404{
405 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700406 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700407 switch(cc) {
buzbeefa57c472012-11-21 12:06:18 -0800408 case kCondEq: res = cu->irb->CreateICmpEQ(src1, src2); break;
409 case kCondNe: res = cu->irb->CreateICmpNE(src1, src2); break;
410 case kCondLt: res = cu->irb->CreateICmpSLT(src1, src2); break;
411 case kCondGe: res = cu->irb->CreateICmpSGE(src1, src2); break;
412 case kCondGt: res = cu->irb->CreateICmpSGT(src1, src2); break;
413 case kCondLe: res = cu->irb->CreateICmpSLE(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700414 default: LOG(FATAL) << "Unexpected cc value " << cc;
415 }
416 return res;
417}
418
buzbeefa57c472012-11-21 12:06:18 -0800419static void ConvertCompareAndBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
420 ConditionCode cc, RegLocation rl_src1, RegLocation rl_src2)
buzbee2cfc6392012-05-07 14:51:40 -0700421{
buzbeefa57c472012-11-21 12:06:18 -0800422 if (bb->taken->start_offset <= mir->offset) {
423 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -0700424 }
buzbeefa57c472012-11-21 12:06:18 -0800425 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
426 llvm::Value* src2 = GetLLVMValue(cu, rl_src2.orig_sreg);
427 llvm::Value* cond_value = ConvertCompare(cu, cc, src1, src2);
428 cond_value->setName(StringPrintf("t%d", cu->temp_name++));
429 cu->irb->CreateCondBr(cond_value, GetLLVMBlock(cu, bb->taken->id),
430 GetLLVMBlock(cu, bb->fall_through->id));
buzbee6969d502012-06-15 16:40:31 -0700431 // Don't redo the fallthrough branch in the BB driver
buzbeefa57c472012-11-21 12:06:18 -0800432 bb->fall_through = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700433}
434
buzbeefa57c472012-11-21 12:06:18 -0800435static void ConvertCompareZeroAndBranch(CompilationUnit* cu, BasicBlock* bb,
436 MIR* mir, ConditionCode cc, RegLocation rl_src1)
buzbee2cfc6392012-05-07 14:51:40 -0700437{
buzbeefa57c472012-11-21 12:06:18 -0800438 if (bb->taken->start_offset <= mir->offset) {
439 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -0700440 }
buzbeefa57c472012-11-21 12:06:18 -0800441 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700442 llvm::Value* src2;
buzbeefa57c472012-11-21 12:06:18 -0800443 if (rl_src1.ref) {
444 src2 = cu->irb->GetJNull();
buzbee2cfc6392012-05-07 14:51:40 -0700445 } else {
buzbeefa57c472012-11-21 12:06:18 -0800446 src2 = cu->irb->getInt32(0);
buzbee2cfc6392012-05-07 14:51:40 -0700447 }
buzbeefa57c472012-11-21 12:06:18 -0800448 llvm::Value* cond_value = ConvertCompare(cu, cc, src1, src2);
449 cu->irb->CreateCondBr(cond_value, GetLLVMBlock(cu, bb->taken->id),
450 GetLLVMBlock(cu, bb->fall_through->id));
buzbee6969d502012-06-15 16:40:31 -0700451 // Don't redo the fallthrough branch in the BB driver
buzbeefa57c472012-11-21 12:06:18 -0800452 bb->fall_through = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700453}
454
buzbeefa57c472012-11-21 12:06:18 -0800455static llvm::Value* GenDivModOp(CompilationUnit* cu, bool is_div, bool is_long,
buzbeeaad94382012-11-21 07:40:50 -0800456 llvm::Value* src1, llvm::Value* src2)
buzbee2cfc6392012-05-07 14:51:40 -0700457{
458 greenland::IntrinsicHelper::IntrinsicId id;
buzbeefa57c472012-11-21 12:06:18 -0800459 if (is_long) {
460 if (is_div) {
buzbee2cfc6392012-05-07 14:51:40 -0700461 id = greenland::IntrinsicHelper::DivLong;
462 } else {
463 id = greenland::IntrinsicHelper::RemLong;
464 }
Logan Chien554e6072012-07-23 20:00:01 -0700465 } else {
buzbeefa57c472012-11-21 12:06:18 -0800466 if (is_div) {
buzbee2cfc6392012-05-07 14:51:40 -0700467 id = greenland::IntrinsicHelper::DivInt;
468 } else {
469 id = greenland::IntrinsicHelper::RemInt;
Logan Chien554e6072012-07-23 20:00:01 -0700470 }
buzbee2cfc6392012-05-07 14:51:40 -0700471 }
buzbeefa57c472012-11-21 12:06:18 -0800472 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee2cfc6392012-05-07 14:51:40 -0700473 llvm::SmallVector<llvm::Value*, 2>args;
474 args.push_back(src1);
475 args.push_back(src2);
buzbeefa57c472012-11-21 12:06:18 -0800476 return cu->irb->CreateCall(intr, args);
buzbee2cfc6392012-05-07 14:51:40 -0700477}
478
buzbeefa57c472012-11-21 12:06:18 -0800479static llvm::Value* GenArithOp(CompilationUnit* cu, OpKind op, bool is_long,
buzbeeaad94382012-11-21 07:40:50 -0800480 llvm::Value* src1, llvm::Value* src2)
buzbee2cfc6392012-05-07 14:51:40 -0700481{
482 llvm::Value* res = NULL;
483 switch(op) {
buzbeefa57c472012-11-21 12:06:18 -0800484 case kOpAdd: res = cu->irb->CreateAdd(src1, src2); break;
485 case kOpSub: res = cu->irb->CreateSub(src1, src2); break;
486 case kOpRsub: res = cu->irb->CreateSub(src2, src1); break;
487 case kOpMul: res = cu->irb->CreateMul(src1, src2); break;
488 case kOpOr: res = cu->irb->CreateOr(src1, src2); break;
489 case kOpAnd: res = cu->irb->CreateAnd(src1, src2); break;
490 case kOpXor: res = cu->irb->CreateXor(src1, src2); break;
491 case kOpDiv: res = GenDivModOp(cu, true, is_long, src1, src2); break;
492 case kOpRem: res = GenDivModOp(cu, false, is_long, src1, src2); break;
493 case kOpLsl: res = cu->irb->CreateShl(src1, src2); break;
494 case kOpLsr: res = cu->irb->CreateLShr(src1, src2); break;
495 case kOpAsr: res = cu->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700496 default:
497 LOG(FATAL) << "Invalid op " << op;
498 }
499 return res;
500}
501
buzbeefa57c472012-11-21 12:06:18 -0800502static void ConvertFPArithOp(CompilationUnit* cu, OpKind op, RegLocation rl_dest,
503 RegLocation rl_src1, RegLocation rl_src2)
buzbee2cfc6392012-05-07 14:51:40 -0700504{
buzbeefa57c472012-11-21 12:06:18 -0800505 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
506 llvm::Value* src2 = GetLLVMValue(cu, rl_src2.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700507 llvm::Value* res = NULL;
508 switch(op) {
buzbeefa57c472012-11-21 12:06:18 -0800509 case kOpAdd: res = cu->irb->CreateFAdd(src1, src2); break;
510 case kOpSub: res = cu->irb->CreateFSub(src1, src2); break;
511 case kOpMul: res = cu->irb->CreateFMul(src1, src2); break;
512 case kOpDiv: res = cu->irb->CreateFDiv(src1, src2); break;
513 case kOpRem: res = cu->irb->CreateFRem(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700514 default:
515 LOG(FATAL) << "Invalid op " << op;
516 }
buzbeefa57c472012-11-21 12:06:18 -0800517 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700518}
519
buzbeefa57c472012-11-21 12:06:18 -0800520static void ConvertShift(CompilationUnit* cu, greenland::IntrinsicHelper::IntrinsicId id,
521 RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2)
buzbee4f1181f2012-06-22 13:52:12 -0700522{
buzbeefa57c472012-11-21 12:06:18 -0800523 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee2a83e8f2012-07-13 16:42:30 -0700524 llvm::SmallVector<llvm::Value*, 2>args;
buzbeefa57c472012-11-21 12:06:18 -0800525 args.push_back(GetLLVMValue(cu, rl_src1.orig_sreg));
526 args.push_back(GetLLVMValue(cu, rl_src2.orig_sreg));
527 llvm::Value* res = cu->irb->CreateCall(intr, args);
528 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2a83e8f2012-07-13 16:42:30 -0700529}
530
buzbeefa57c472012-11-21 12:06:18 -0800531static void ConvertShiftLit(CompilationUnit* cu, greenland::IntrinsicHelper::IntrinsicId id,
532 RegLocation rl_dest, RegLocation rl_src, int shift_amount)
buzbee2a83e8f2012-07-13 16:42:30 -0700533{
buzbeefa57c472012-11-21 12:06:18 -0800534 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee2a83e8f2012-07-13 16:42:30 -0700535 llvm::SmallVector<llvm::Value*, 2>args;
buzbeefa57c472012-11-21 12:06:18 -0800536 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
537 args.push_back(cu->irb->getInt32(shift_amount));
538 llvm::Value* res = cu->irb->CreateCall(intr, args);
539 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee4f1181f2012-06-22 13:52:12 -0700540}
541
buzbeefa57c472012-11-21 12:06:18 -0800542static void ConvertArithOp(CompilationUnit* cu, OpKind op, RegLocation rl_dest,
543 RegLocation rl_src1, RegLocation rl_src2)
buzbee2cfc6392012-05-07 14:51:40 -0700544{
buzbeefa57c472012-11-21 12:06:18 -0800545 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
546 llvm::Value* src2 = GetLLVMValue(cu, rl_src2.orig_sreg);
buzbee4f4dfc72012-07-02 14:54:44 -0700547 DCHECK_EQ(src1->getType(), src2->getType());
buzbeefa57c472012-11-21 12:06:18 -0800548 llvm::Value* res = GenArithOp(cu, op, rl_dest.wide, src1, src2);
549 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700550}
551
buzbeefa57c472012-11-21 12:06:18 -0800552static void SetShadowFrameEntry(CompilationUnit* cu, llvm::Value* new_val)
buzbeeb03f4872012-06-11 15:22:11 -0700553{
554 int index = -1;
buzbeefa57c472012-11-21 12:06:18 -0800555 DCHECK(new_val != NULL);
556 int v_reg = SRegToVReg(cu, GetLoc(cu, new_val).orig_sreg);
557 for (int i = 0; i < cu->num_shadow_frame_entries; i++) {
558 if (cu->shadow_map[i] == v_reg) {
buzbeeb03f4872012-06-11 15:22:11 -0700559 index = i;
560 break;
561 }
562 }
TDYa127347166a2012-08-23 12:23:44 -0700563 if (index == -1) {
564 return;
565 }
buzbeefa57c472012-11-21 12:06:18 -0800566 llvm::Type* ty = new_val->getType();
buzbeeb03f4872012-06-11 15:22:11 -0700567 greenland::IntrinsicHelper::IntrinsicId id =
568 greenland::IntrinsicHelper::SetShadowFrameEntry;
buzbeefa57c472012-11-21 12:06:18 -0800569 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id);
570 llvm::Value* table_slot = cu->irb->getInt32(index);
571 // If new_val is a Null pointer, we'll see it here as a const int. Replace
buzbee6459e7c2012-10-02 14:42:41 -0700572 if (!ty->isPointerTy()) {
buzbeefa57c472012-11-21 12:06:18 -0800573 // TODO: assert new_val created w/ dex_lang_const_int(0) or dex_lang_const_float(0)
574 new_val = cu->irb->GetJNull();
buzbee6459e7c2012-10-02 14:42:41 -0700575 }
buzbeefa57c472012-11-21 12:06:18 -0800576 llvm::Value* args[] = { new_val, table_slot };
577 cu->irb->CreateCall(func, args);
buzbeeb03f4872012-06-11 15:22:11 -0700578}
579
buzbeefa57c472012-11-21 12:06:18 -0800580static void ConvertArithOpLit(CompilationUnit* cu, OpKind op, RegLocation rl_dest,
581 RegLocation rl_src1, int32_t imm)
buzbee2cfc6392012-05-07 14:51:40 -0700582{
buzbeefa57c472012-11-21 12:06:18 -0800583 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
584 llvm::Value* src2 = cu->irb->getInt32(imm);
585 llvm::Value* res = GenArithOp(cu, op, rl_dest.wide, src1, src2);
586 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700587}
588
buzbee101305f2012-06-28 18:00:56 -0700589/*
590 * Process arguments for invoke. Note: this code is also used to
591 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
592 * The requirements are similar.
593 */
buzbeefa57c472012-11-21 12:06:18 -0800594static void ConvertInvoke(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
595 InvokeType invoke_type, bool is_range, bool is_filled_new_array)
buzbee6969d502012-06-15 16:40:31 -0700596{
buzbeefa57c472012-11-21 12:06:18 -0800597 CallInfo* info = NewMemCallInfo(cu, bb, mir, invoke_type, is_range);
buzbee6969d502012-06-15 16:40:31 -0700598 llvm::SmallVector<llvm::Value*, 10> args;
buzbeefa57c472012-11-21 12:06:18 -0800599 // Insert the invoke_type
600 args.push_back(cu->irb->getInt32(static_cast<int>(invoke_type)));
buzbee6969d502012-06-15 16:40:31 -0700601 // Insert the method_idx
buzbeefa57c472012-11-21 12:06:18 -0800602 args.push_back(cu->irb->getInt32(info->index));
buzbee6969d502012-06-15 16:40:31 -0700603 // Insert the optimization flags
buzbeefa57c472012-11-21 12:06:18 -0800604 args.push_back(cu->irb->getInt32(info->opt_flags));
buzbee6969d502012-06-15 16:40:31 -0700605 // Now, insert the actual arguments
buzbeefa57c472012-11-21 12:06:18 -0800606 for (int i = 0; i < info->num_arg_words;) {
607 llvm::Value* val = GetLLVMValue(cu, info->args[i].orig_sreg);
buzbee6969d502012-06-15 16:40:31 -0700608 args.push_back(val);
609 i += info->args[i].wide ? 2 : 1;
610 }
611 /*
612 * Choose the invoke return type based on actual usage. Note: may
613 * be different than shorty. For example, if a function return value
614 * is not used, we'll treat this as a void invoke.
615 */
616 greenland::IntrinsicHelper::IntrinsicId id;
buzbeefa57c472012-11-21 12:06:18 -0800617 if (is_filled_new_array) {
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700618 id = greenland::IntrinsicHelper::HLFilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700619 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700620 id = greenland::IntrinsicHelper::HLInvokeVoid;
621 } else {
622 if (info->result.wide) {
623 if (info->result.fp) {
624 id = greenland::IntrinsicHelper::HLInvokeDouble;
625 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700626 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700627 }
628 } else if (info->result.ref) {
629 id = greenland::IntrinsicHelper::HLInvokeObj;
630 } else if (info->result.fp) {
631 id = greenland::IntrinsicHelper::HLInvokeFloat;
632 } else {
633 id = greenland::IntrinsicHelper::HLInvokeInt;
634 }
635 }
buzbeefa57c472012-11-21 12:06:18 -0800636 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
637 llvm::Value* res = cu->irb->CreateCall(intr, args);
buzbee6969d502012-06-15 16:40:31 -0700638 if (info->result.location != kLocInvalid) {
buzbeefa57c472012-11-21 12:06:18 -0800639 DefineValue(cu, res, info->result.orig_sreg);
TDYa127890ea892012-08-22 10:49:42 -0700640 if (info->result.ref) {
buzbeefa57c472012-11-21 12:06:18 -0800641 SetShadowFrameEntry(cu, reinterpret_cast<llvm::Value*>
642 (cu->llvm_values.elem_list[info->result.orig_sreg]));
TDYa127890ea892012-08-22 10:49:42 -0700643 }
buzbee6969d502012-06-15 16:40:31 -0700644 }
645}
646
buzbeefa57c472012-11-21 12:06:18 -0800647static void ConvertConstObject(CompilationUnit* cu, uint32_t idx,
648 greenland::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest)
buzbee6969d502012-06-15 16:40:31 -0700649{
buzbeefa57c472012-11-21 12:06:18 -0800650 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
651 llvm::Value* index = cu->irb->getInt32(idx);
652 llvm::Value* res = cu->irb->CreateCall(intr, index);
653 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee6969d502012-06-15 16:40:31 -0700654}
655
buzbeefa57c472012-11-21 12:06:18 -0800656static void ConvertCheckCast(CompilationUnit* cu, uint32_t type_idx, RegLocation rl_src)
buzbee101305f2012-06-28 18:00:56 -0700657{
658 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700659 id = greenland::IntrinsicHelper::HLCheckCast;
buzbeefa57c472012-11-21 12:06:18 -0800660 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700661 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800662 args.push_back(cu->irb->getInt32(type_idx));
663 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
664 cu->irb->CreateCall(intr, args);
buzbee101305f2012-06-28 18:00:56 -0700665}
666
buzbeefa57c472012-11-21 12:06:18 -0800667static void ConvertNewInstance(CompilationUnit* cu, uint32_t type_idx, RegLocation rl_dest)
buzbee4f1181f2012-06-22 13:52:12 -0700668{
669 greenland::IntrinsicHelper::IntrinsicId id;
670 id = greenland::IntrinsicHelper::NewInstance;
buzbeefa57c472012-11-21 12:06:18 -0800671 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
672 llvm::Value* index = cu->irb->getInt32(type_idx);
673 llvm::Value* res = cu->irb->CreateCall(intr, index);
674 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee4f1181f2012-06-22 13:52:12 -0700675}
676
buzbeefa57c472012-11-21 12:06:18 -0800677static void ConvertNewArray(CompilationUnit* cu, uint32_t type_idx,
678 RegLocation rl_dest, RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700679{
680 greenland::IntrinsicHelper::IntrinsicId id;
681 id = greenland::IntrinsicHelper::NewArray;
buzbeefa57c472012-11-21 12:06:18 -0800682 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700683 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800684 args.push_back(cu->irb->getInt32(type_idx));
685 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
686 llvm::Value* res = cu->irb->CreateCall(intr, args);
687 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700688}
689
buzbeefa57c472012-11-21 12:06:18 -0800690static void ConvertAget(CompilationUnit* cu, int opt_flags,
buzbeeaad94382012-11-21 07:40:50 -0800691 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800692 RegLocation rl_dest, RegLocation rl_array, RegLocation rl_index)
buzbee8fa0fda2012-06-27 15:44:52 -0700693{
694 llvm::SmallVector<llvm::Value*, 3> args;
buzbeefa57c472012-11-21 12:06:18 -0800695 args.push_back(cu->irb->getInt32(opt_flags));
696 args.push_back(GetLLVMValue(cu, rl_array.orig_sreg));
697 args.push_back(GetLLVMValue(cu, rl_index.orig_sreg));
698 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
699 llvm::Value* res = cu->irb->CreateCall(intr, args);
700 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700701}
702
buzbeefa57c472012-11-21 12:06:18 -0800703static void ConvertAput(CompilationUnit* cu, int opt_flags,
buzbeeaad94382012-11-21 07:40:50 -0800704 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800705 RegLocation rl_src, RegLocation rl_array, RegLocation rl_index)
buzbee8fa0fda2012-06-27 15:44:52 -0700706{
707 llvm::SmallVector<llvm::Value*, 4> args;
buzbeefa57c472012-11-21 12:06:18 -0800708 args.push_back(cu->irb->getInt32(opt_flags));
709 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
710 args.push_back(GetLLVMValue(cu, rl_array.orig_sreg));
711 args.push_back(GetLLVMValue(cu, rl_index.orig_sreg));
712 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
713 cu->irb->CreateCall(intr, args);
buzbee8fa0fda2012-06-27 15:44:52 -0700714}
715
buzbeefa57c472012-11-21 12:06:18 -0800716static void ConvertIget(CompilationUnit* cu, int opt_flags,
buzbeeaad94382012-11-21 07:40:50 -0800717 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800718 RegLocation rl_dest, RegLocation rl_obj, int field_index)
buzbee101305f2012-06-28 18:00:56 -0700719{
720 llvm::SmallVector<llvm::Value*, 3> args;
buzbeefa57c472012-11-21 12:06:18 -0800721 args.push_back(cu->irb->getInt32(opt_flags));
722 args.push_back(GetLLVMValue(cu, rl_obj.orig_sreg));
723 args.push_back(cu->irb->getInt32(field_index));
724 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
725 llvm::Value* res = cu->irb->CreateCall(intr, args);
726 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee101305f2012-06-28 18:00:56 -0700727}
728
buzbeefa57c472012-11-21 12:06:18 -0800729static void ConvertIput(CompilationUnit* cu, int opt_flags,
buzbeeaad94382012-11-21 07:40:50 -0800730 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800731 RegLocation rl_src, RegLocation rl_obj, int field_index)
buzbee101305f2012-06-28 18:00:56 -0700732{
733 llvm::SmallVector<llvm::Value*, 4> args;
buzbeefa57c472012-11-21 12:06:18 -0800734 args.push_back(cu->irb->getInt32(opt_flags));
735 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
736 args.push_back(GetLLVMValue(cu, rl_obj.orig_sreg));
737 args.push_back(cu->irb->getInt32(field_index));
738 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
739 cu->irb->CreateCall(intr, args);
buzbee101305f2012-06-28 18:00:56 -0700740}
741
buzbeefa57c472012-11-21 12:06:18 -0800742static void ConvertInstanceOf(CompilationUnit* cu, uint32_t type_idx,
743 RegLocation rl_dest, RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700744{
745 greenland::IntrinsicHelper::IntrinsicId id;
746 id = greenland::IntrinsicHelper::InstanceOf;
buzbeefa57c472012-11-21 12:06:18 -0800747 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700748 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800749 args.push_back(cu->irb->getInt32(type_idx));
750 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
751 llvm::Value* res = cu->irb->CreateCall(intr, args);
752 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700753}
754
buzbeefa57c472012-11-21 12:06:18 -0800755static void ConvertIntToLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee101305f2012-06-28 18:00:56 -0700756{
buzbeefa57c472012-11-21 12:06:18 -0800757 llvm::Value* res = cu->irb->CreateSExt(GetLLVMValue(cu, rl_src.orig_sreg),
758 cu->irb->getInt64Ty());
759 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee101305f2012-06-28 18:00:56 -0700760}
761
buzbeefa57c472012-11-21 12:06:18 -0800762static void ConvertLongToInt(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700763{
buzbeefa57c472012-11-21 12:06:18 -0800764 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
765 llvm::Value* res = cu->irb->CreateTrunc(src, cu->irb->getInt32Ty());
766 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700767}
768
buzbeefa57c472012-11-21 12:06:18 -0800769static void ConvertFloatToDouble(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700770{
buzbeefa57c472012-11-21 12:06:18 -0800771 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
772 llvm::Value* res = cu->irb->CreateFPExt(src, cu->irb->getDoubleTy());
773 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700774}
775
buzbeefa57c472012-11-21 12:06:18 -0800776static void ConvertDoubleToFloat(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700777{
buzbeefa57c472012-11-21 12:06:18 -0800778 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
779 llvm::Value* res = cu->irb->CreateFPTrunc(src, cu->irb->getFloatTy());
780 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700781}
782
buzbeefa57c472012-11-21 12:06:18 -0800783static void ConvertWideComparison(CompilationUnit* cu,
buzbeeaad94382012-11-21 07:40:50 -0800784 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800785 RegLocation rl_dest, RegLocation rl_src1,
786 RegLocation rl_src2)
buzbee76592632012-06-29 15:18:35 -0700787{
buzbeefa57c472012-11-21 12:06:18 -0800788 DCHECK_EQ(rl_src1.fp, rl_src2.fp);
789 DCHECK_EQ(rl_src1.wide, rl_src2.wide);
790 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700791 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800792 args.push_back(GetLLVMValue(cu, rl_src1.orig_sreg));
793 args.push_back(GetLLVMValue(cu, rl_src2.orig_sreg));
794 llvm::Value* res = cu->irb->CreateCall(intr, args);
795 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700796}
797
buzbeefa57c472012-11-21 12:06:18 -0800798static void ConvertIntNarrowing(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src,
buzbeeaad94382012-11-21 07:40:50 -0800799 greenland::IntrinsicHelper::IntrinsicId id)
buzbee101305f2012-06-28 18:00:56 -0700800{
buzbeefa57c472012-11-21 12:06:18 -0800801 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700802 llvm::Value* res =
buzbeefa57c472012-11-21 12:06:18 -0800803 cu->irb->CreateCall(intr, GetLLVMValue(cu, rl_src.orig_sreg));
804 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700805}
806
buzbeefa57c472012-11-21 12:06:18 -0800807static void ConvertNeg(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700808{
buzbeefa57c472012-11-21 12:06:18 -0800809 llvm::Value* res = cu->irb->CreateNeg(GetLLVMValue(cu, rl_src.orig_sreg));
810 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700811}
812
buzbeefa57c472012-11-21 12:06:18 -0800813static void ConvertIntToFP(CompilationUnit* cu, llvm::Type* ty, RegLocation rl_dest,
814 RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700815{
816 llvm::Value* res =
buzbeefa57c472012-11-21 12:06:18 -0800817 cu->irb->CreateSIToFP(GetLLVMValue(cu, rl_src.orig_sreg), ty);
818 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700819}
820
buzbeefa57c472012-11-21 12:06:18 -0800821static void ConvertFPToInt(CompilationUnit* cu, greenland::IntrinsicHelper::IntrinsicId id,
822 RegLocation rl_dest,
823 RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700824{
buzbeefa57c472012-11-21 12:06:18 -0800825 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
826 llvm::Value* res = cu->irb->CreateCall(intr, GetLLVMValue(cu, rl_src.orig_sreg));
827 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700828}
829
830
buzbeefa57c472012-11-21 12:06:18 -0800831static void ConvertNegFP(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700832{
833 llvm::Value* res =
buzbeefa57c472012-11-21 12:06:18 -0800834 cu->irb->CreateFNeg(GetLLVMValue(cu, rl_src.orig_sreg));
835 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700836}
837
buzbeefa57c472012-11-21 12:06:18 -0800838static void ConvertNot(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700839{
buzbeefa57c472012-11-21 12:06:18 -0800840 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
841 llvm::Value* res = cu->irb->CreateXor(src, static_cast<uint64_t>(-1));
842 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee101305f2012-06-28 18:00:56 -0700843}
844
buzbee2cfc6392012-05-07 14:51:40 -0700845/*
846 * Target-independent code generation. Use only high-level
847 * load/store utilities here, or target-dependent genXX() handlers
848 * when necessary.
849 */
buzbeefa57c472012-11-21 12:06:18 -0800850static bool ConvertMIRNode(CompilationUnit* cu, MIR* mir, BasicBlock* bb,
851 llvm::BasicBlock* llvm_bb, LIR* label_list)
buzbee2cfc6392012-05-07 14:51:40 -0700852{
853 bool res = false; // Assume success
buzbeefa57c472012-11-21 12:06:18 -0800854 RegLocation rl_src[3];
855 RegLocation rl_dest = bad_loc;
buzbee2cfc6392012-05-07 14:51:40 -0700856 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -0800857 int op_val = opcode;
buzbee6969d502012-06-15 16:40:31 -0700858 uint32_t vB = mir->dalvikInsn.vB;
859 uint32_t vC = mir->dalvikInsn.vC;
buzbeefa57c472012-11-21 12:06:18 -0800860 int opt_flags = mir->optimization_flags;
buzbee6969d502012-06-15 16:40:31 -0700861
buzbeefa57c472012-11-21 12:06:18 -0800862 bool object_definition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700863
buzbeefa57c472012-11-21 12:06:18 -0800864 if (cu->verbose) {
865 if (op_val < kMirOpFirst) {
866 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x" << std::hex << op_val;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700867 } else {
buzbeefa57c472012-11-21 12:06:18 -0800868 LOG(INFO) << extended_mir_op_names[op_val - kMirOpFirst] << " 0x" << std::hex << op_val;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700869 }
870 }
871
buzbee2cfc6392012-05-07 14:51:40 -0700872 /* Prep Src and Dest locations */
buzbeefa57c472012-11-21 12:06:18 -0800873 int next_sreg = 0;
874 int next_loc = 0;
875 int attrs = oat_data_flow_attributes[opcode];
876 rl_src[0] = rl_src[1] = rl_src[2] = bad_loc;
buzbee2cfc6392012-05-07 14:51:40 -0700877 if (attrs & DF_UA) {
878 if (attrs & DF_A_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -0800879 rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
880 next_sreg+= 2;
buzbee2cfc6392012-05-07 14:51:40 -0700881 } else {
buzbeefa57c472012-11-21 12:06:18 -0800882 rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
883 next_sreg++;
buzbee2cfc6392012-05-07 14:51:40 -0700884 }
885 }
886 if (attrs & DF_UB) {
887 if (attrs & DF_B_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -0800888 rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
889 next_sreg+= 2;
buzbee2cfc6392012-05-07 14:51:40 -0700890 } else {
buzbeefa57c472012-11-21 12:06:18 -0800891 rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
892 next_sreg++;
buzbee2cfc6392012-05-07 14:51:40 -0700893 }
894 }
895 if (attrs & DF_UC) {
896 if (attrs & DF_C_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -0800897 rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700898 } else {
buzbeefa57c472012-11-21 12:06:18 -0800899 rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700900 }
901 }
902 if (attrs & DF_DA) {
903 if (attrs & DF_A_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -0800904 rl_dest = GetDestWide(cu, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700905 } else {
buzbeefa57c472012-11-21 12:06:18 -0800906 rl_dest = GetDest(cu, mir);
907 if (rl_dest.ref) {
908 object_definition = true;
buzbeeb03f4872012-06-11 15:22:11 -0700909 }
buzbee2cfc6392012-05-07 14:51:40 -0700910 }
911 }
912
913 switch (opcode) {
914 case Instruction::NOP:
915 break;
916
917 case Instruction::MOVE:
918 case Instruction::MOVE_OBJECT:
919 case Instruction::MOVE_16:
920 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700921 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700922 case Instruction::MOVE_FROM16:
923 case Instruction::MOVE_WIDE:
924 case Instruction::MOVE_WIDE_16:
925 case Instruction::MOVE_WIDE_FROM16: {
926 /*
927 * Moves/copies are meaningless in pure SSA register form,
928 * but we need to preserve them for the conversion back into
929 * MIR (at least until we stop using the Dalvik register maps).
930 * Insert a dummy intrinsic copy call, which will be recognized
931 * by the quick path and removed by the portable path.
932 */
buzbeefa57c472012-11-21 12:06:18 -0800933 llvm::Value* src = GetLLVMValue(cu, rl_src[0].orig_sreg);
934 llvm::Value* res = EmitCopy(cu, src, rl_dest);
935 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700936 }
937 break;
938
939 case Instruction::CONST:
940 case Instruction::CONST_4:
941 case Instruction::CONST_16: {
TDYa127347166a2012-08-23 12:23:44 -0700942 if (vB == 0) {
buzbeefa57c472012-11-21 12:06:18 -0800943 object_definition = true;
TDYa127347166a2012-08-23 12:23:44 -0700944 }
buzbeefa57c472012-11-21 12:06:18 -0800945 llvm::Constant* imm_value = cu->irb->GetJInt(vB);
946 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
947 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700948 }
949 break;
950
951 case Instruction::CONST_WIDE_16:
952 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700953 // Sign extend to 64 bits
954 int64_t imm = static_cast<int32_t>(vB);
buzbeefa57c472012-11-21 12:06:18 -0800955 llvm::Constant* imm_value = cu->irb->GetJLong(imm);
956 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
957 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700958 }
959 break;
960
961 case Instruction::CONST_HIGH16: {
buzbeefa57c472012-11-21 12:06:18 -0800962 llvm::Constant* imm_value = cu->irb->GetJInt(vB << 16);
963 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
964 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700965 }
966 break;
967
968 case Instruction::CONST_WIDE: {
buzbeefa57c472012-11-21 12:06:18 -0800969 llvm::Constant* imm_value =
970 cu->irb->GetJLong(mir->dalvikInsn.vB_wide);
971 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
972 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee4f1181f2012-06-22 13:52:12 -0700973 }
974 break;
buzbee2cfc6392012-05-07 14:51:40 -0700975 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700976 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbeefa57c472012-11-21 12:06:18 -0800977 llvm::Constant* imm_value = cu->irb->GetJLong(imm);
978 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
979 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee4f1181f2012-06-22 13:52:12 -0700980 }
981 break;
982
buzbee8fa0fda2012-06-27 15:44:52 -0700983 case Instruction::SPUT_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -0800984 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputObject,
985 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700986 break;
987 case Instruction::SPUT:
buzbeefa57c472012-11-21 12:06:18 -0800988 if (rl_src[0].fp) {
989 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputFloat,
990 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700991 } else {
buzbeefa57c472012-11-21 12:06:18 -0800992 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSput, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700993 }
994 break;
995 case Instruction::SPUT_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -0800996 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputBoolean,
997 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700998 break;
999 case Instruction::SPUT_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001000 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputByte, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001001 break;
1002 case Instruction::SPUT_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001003 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputChar, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001004 break;
1005 case Instruction::SPUT_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001006 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputShort, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001007 break;
1008 case Instruction::SPUT_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001009 if (rl_src[0].fp) {
1010 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputDouble,
1011 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001012 } else {
buzbeefa57c472012-11-21 12:06:18 -08001013 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputWide,
1014 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001015 }
1016 break;
1017
1018 case Instruction::SGET_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -08001019 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetObject, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001020 break;
1021 case Instruction::SGET:
buzbeefa57c472012-11-21 12:06:18 -08001022 if (rl_dest.fp) {
1023 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetFloat, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001024 } else {
buzbeefa57c472012-11-21 12:06:18 -08001025 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSget, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001026 }
1027 break;
1028 case Instruction::SGET_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -08001029 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetBoolean, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001030 break;
1031 case Instruction::SGET_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001032 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetByte, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001033 break;
1034 case Instruction::SGET_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001035 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetChar, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001036 break;
1037 case Instruction::SGET_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001038 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetShort, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001039 break;
1040 case Instruction::SGET_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001041 if (rl_dest.fp) {
1042 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetDouble,
1043 rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001044 } else {
buzbeefa57c472012-11-21 12:06:18 -08001045 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetWide, rl_dest);
buzbee4f1181f2012-06-22 13:52:12 -07001046 }
1047 break;
buzbee2cfc6392012-05-07 14:51:40 -07001048
1049 case Instruction::RETURN_WIDE:
1050 case Instruction::RETURN:
1051 case Instruction::RETURN_OBJECT: {
buzbeefa57c472012-11-21 12:06:18 -08001052 if (!(cu->attrs & METHOD_IS_LEAF)) {
1053 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -07001054 }
buzbeefa57c472012-11-21 12:06:18 -08001055 EmitPopShadowFrame(cu);
1056 cu->irb->CreateRet(GetLLVMValue(cu, rl_src[0].orig_sreg));
1057 bb->has_return = true;
buzbee2cfc6392012-05-07 14:51:40 -07001058 }
1059 break;
1060
1061 case Instruction::RETURN_VOID: {
buzbeefa57c472012-11-21 12:06:18 -08001062 if (!(cu->attrs & METHOD_IS_LEAF)) {
1063 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -07001064 }
buzbeefa57c472012-11-21 12:06:18 -08001065 EmitPopShadowFrame(cu);
1066 cu->irb->CreateRetVoid();
1067 bb->has_return = true;
buzbee2cfc6392012-05-07 14:51:40 -07001068 }
1069 break;
1070
1071 case Instruction::IF_EQ:
buzbeefa57c472012-11-21 12:06:18 -08001072 ConvertCompareAndBranch(cu, bb, mir, kCondEq, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001073 break;
1074 case Instruction::IF_NE:
buzbeefa57c472012-11-21 12:06:18 -08001075 ConvertCompareAndBranch(cu, bb, mir, kCondNe, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001076 break;
1077 case Instruction::IF_LT:
buzbeefa57c472012-11-21 12:06:18 -08001078 ConvertCompareAndBranch(cu, bb, mir, kCondLt, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001079 break;
1080 case Instruction::IF_GE:
buzbeefa57c472012-11-21 12:06:18 -08001081 ConvertCompareAndBranch(cu, bb, mir, kCondGe, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001082 break;
1083 case Instruction::IF_GT:
buzbeefa57c472012-11-21 12:06:18 -08001084 ConvertCompareAndBranch(cu, bb, mir, kCondGt, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001085 break;
1086 case Instruction::IF_LE:
buzbeefa57c472012-11-21 12:06:18 -08001087 ConvertCompareAndBranch(cu, bb, mir, kCondLe, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001088 break;
1089 case Instruction::IF_EQZ:
buzbeefa57c472012-11-21 12:06:18 -08001090 ConvertCompareZeroAndBranch(cu, bb, mir, kCondEq, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001091 break;
1092 case Instruction::IF_NEZ:
buzbeefa57c472012-11-21 12:06:18 -08001093 ConvertCompareZeroAndBranch(cu, bb, mir, kCondNe, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001094 break;
1095 case Instruction::IF_LTZ:
buzbeefa57c472012-11-21 12:06:18 -08001096 ConvertCompareZeroAndBranch(cu, bb, mir, kCondLt, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001097 break;
1098 case Instruction::IF_GEZ:
buzbeefa57c472012-11-21 12:06:18 -08001099 ConvertCompareZeroAndBranch(cu, bb, mir, kCondGe, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001100 break;
1101 case Instruction::IF_GTZ:
buzbeefa57c472012-11-21 12:06:18 -08001102 ConvertCompareZeroAndBranch(cu, bb, mir, kCondGt, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001103 break;
1104 case Instruction::IF_LEZ:
buzbeefa57c472012-11-21 12:06:18 -08001105 ConvertCompareZeroAndBranch(cu, bb, mir, kCondLe, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001106 break;
1107
1108 case Instruction::GOTO:
1109 case Instruction::GOTO_16:
1110 case Instruction::GOTO_32: {
buzbeefa57c472012-11-21 12:06:18 -08001111 if (bb->taken->start_offset <= bb->start_offset) {
1112 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -07001113 }
buzbeefa57c472012-11-21 12:06:18 -08001114 cu->irb->CreateBr(GetLLVMBlock(cu, bb->taken->id));
buzbee2cfc6392012-05-07 14:51:40 -07001115 }
1116 break;
1117
1118 case Instruction::ADD_LONG:
1119 case Instruction::ADD_LONG_2ADDR:
1120 case Instruction::ADD_INT:
1121 case Instruction::ADD_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001122 ConvertArithOp(cu, kOpAdd, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001123 break;
1124 case Instruction::SUB_LONG:
1125 case Instruction::SUB_LONG_2ADDR:
1126 case Instruction::SUB_INT:
1127 case Instruction::SUB_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001128 ConvertArithOp(cu, kOpSub, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001129 break;
1130 case Instruction::MUL_LONG:
1131 case Instruction::MUL_LONG_2ADDR:
1132 case Instruction::MUL_INT:
1133 case Instruction::MUL_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001134 ConvertArithOp(cu, kOpMul, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001135 break;
1136 case Instruction::DIV_LONG:
1137 case Instruction::DIV_LONG_2ADDR:
1138 case Instruction::DIV_INT:
1139 case Instruction::DIV_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001140 ConvertArithOp(cu, kOpDiv, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001141 break;
1142 case Instruction::REM_LONG:
1143 case Instruction::REM_LONG_2ADDR:
1144 case Instruction::REM_INT:
1145 case Instruction::REM_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001146 ConvertArithOp(cu, kOpRem, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001147 break;
1148 case Instruction::AND_LONG:
1149 case Instruction::AND_LONG_2ADDR:
1150 case Instruction::AND_INT:
1151 case Instruction::AND_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001152 ConvertArithOp(cu, kOpAnd, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001153 break;
1154 case Instruction::OR_LONG:
1155 case Instruction::OR_LONG_2ADDR:
1156 case Instruction::OR_INT:
1157 case Instruction::OR_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001158 ConvertArithOp(cu, kOpOr, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001159 break;
1160 case Instruction::XOR_LONG:
1161 case Instruction::XOR_LONG_2ADDR:
1162 case Instruction::XOR_INT:
1163 case Instruction::XOR_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001164 ConvertArithOp(cu, kOpXor, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001165 break;
1166 case Instruction::SHL_LONG:
1167 case Instruction::SHL_LONG_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001168 ConvertShift(cu, greenland::IntrinsicHelper::SHLLong,
1169 rl_dest, rl_src[0], rl_src[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001170 break;
buzbee2cfc6392012-05-07 14:51:40 -07001171 case Instruction::SHL_INT:
1172 case Instruction::SHL_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001173 ConvertShift(cu, greenland::IntrinsicHelper::SHLInt,
1174 rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001175 break;
1176 case Instruction::SHR_LONG:
1177 case Instruction::SHR_LONG_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001178 ConvertShift(cu, greenland::IntrinsicHelper::SHRLong,
1179 rl_dest, rl_src[0], rl_src[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001180 break;
buzbee2cfc6392012-05-07 14:51:40 -07001181 case Instruction::SHR_INT:
1182 case Instruction::SHR_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001183 ConvertShift(cu, greenland::IntrinsicHelper::SHRInt,
1184 rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001185 break;
1186 case Instruction::USHR_LONG:
1187 case Instruction::USHR_LONG_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001188 ConvertShift(cu, greenland::IntrinsicHelper::USHRLong,
1189 rl_dest, rl_src[0], rl_src[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001190 break;
buzbee2cfc6392012-05-07 14:51:40 -07001191 case Instruction::USHR_INT:
1192 case Instruction::USHR_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001193 ConvertShift(cu, greenland::IntrinsicHelper::USHRInt,
1194 rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001195 break;
1196
1197 case Instruction::ADD_INT_LIT16:
1198 case Instruction::ADD_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001199 ConvertArithOpLit(cu, kOpAdd, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001200 break;
1201 case Instruction::RSUB_INT:
1202 case Instruction::RSUB_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001203 ConvertArithOpLit(cu, kOpRsub, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001204 break;
1205 case Instruction::MUL_INT_LIT16:
1206 case Instruction::MUL_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001207 ConvertArithOpLit(cu, kOpMul, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001208 break;
1209 case Instruction::DIV_INT_LIT16:
1210 case Instruction::DIV_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001211 ConvertArithOpLit(cu, kOpDiv, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001212 break;
1213 case Instruction::REM_INT_LIT16:
1214 case Instruction::REM_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001215 ConvertArithOpLit(cu, kOpRem, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001216 break;
1217 case Instruction::AND_INT_LIT16:
1218 case Instruction::AND_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001219 ConvertArithOpLit(cu, kOpAnd, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001220 break;
1221 case Instruction::OR_INT_LIT16:
1222 case Instruction::OR_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001223 ConvertArithOpLit(cu, kOpOr, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001224 break;
1225 case Instruction::XOR_INT_LIT16:
1226 case Instruction::XOR_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001227 ConvertArithOpLit(cu, kOpXor, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001228 break;
1229 case Instruction::SHL_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001230 ConvertShiftLit(cu, greenland::IntrinsicHelper::SHLInt,
1231 rl_dest, rl_src[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001232 break;
1233 case Instruction::SHR_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001234 ConvertShiftLit(cu, greenland::IntrinsicHelper::SHRInt,
1235 rl_dest, rl_src[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001236 break;
1237 case Instruction::USHR_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001238 ConvertShiftLit(cu, greenland::IntrinsicHelper::USHRInt,
1239 rl_dest, rl_src[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001240 break;
1241
1242 case Instruction::ADD_FLOAT:
1243 case Instruction::ADD_FLOAT_2ADDR:
1244 case Instruction::ADD_DOUBLE:
1245 case Instruction::ADD_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001246 ConvertFPArithOp(cu, kOpAdd, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001247 break;
1248
1249 case Instruction::SUB_FLOAT:
1250 case Instruction::SUB_FLOAT_2ADDR:
1251 case Instruction::SUB_DOUBLE:
1252 case Instruction::SUB_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001253 ConvertFPArithOp(cu, kOpSub, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001254 break;
1255
1256 case Instruction::MUL_FLOAT:
1257 case Instruction::MUL_FLOAT_2ADDR:
1258 case Instruction::MUL_DOUBLE:
1259 case Instruction::MUL_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001260 ConvertFPArithOp(cu, kOpMul, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001261 break;
1262
1263 case Instruction::DIV_FLOAT:
1264 case Instruction::DIV_FLOAT_2ADDR:
1265 case Instruction::DIV_DOUBLE:
1266 case Instruction::DIV_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001267 ConvertFPArithOp(cu, kOpDiv, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001268 break;
1269
1270 case Instruction::REM_FLOAT:
1271 case Instruction::REM_FLOAT_2ADDR:
1272 case Instruction::REM_DOUBLE:
1273 case Instruction::REM_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001274 ConvertFPArithOp(cu, kOpRem, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001275 break;
1276
buzbee6969d502012-06-15 16:40:31 -07001277 case Instruction::INVOKE_STATIC:
buzbeefa57c472012-11-21 12:06:18 -08001278 ConvertInvoke(cu, bb, mir, kStatic, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001279 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001280 break;
1281 case Instruction::INVOKE_STATIC_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001282 ConvertInvoke(cu, bb, mir, kStatic, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001283 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001284 break;
1285
1286 case Instruction::INVOKE_DIRECT:
buzbeefa57c472012-11-21 12:06:18 -08001287 ConvertInvoke(cu, bb, mir, kDirect, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001288 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001289 break;
1290 case Instruction::INVOKE_DIRECT_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001291 ConvertInvoke(cu, bb, mir, kDirect, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001292 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001293 break;
1294
1295 case Instruction::INVOKE_VIRTUAL:
buzbeefa57c472012-11-21 12:06:18 -08001296 ConvertInvoke(cu, bb, mir, kVirtual, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001297 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001298 break;
1299 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001300 ConvertInvoke(cu, bb, mir, kVirtual, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001301 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001302 break;
1303
1304 case Instruction::INVOKE_SUPER:
buzbeefa57c472012-11-21 12:06:18 -08001305 ConvertInvoke(cu, bb, mir, kSuper, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001306 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001307 break;
1308 case Instruction::INVOKE_SUPER_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001309 ConvertInvoke(cu, bb, mir, kSuper, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001310 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001311 break;
1312
1313 case Instruction::INVOKE_INTERFACE:
buzbeefa57c472012-11-21 12:06:18 -08001314 ConvertInvoke(cu, bb, mir, kInterface, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001315 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001316 break;
1317 case Instruction::INVOKE_INTERFACE_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001318 ConvertInvoke(cu, bb, mir, kInterface, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001319 false /* NewFilledArray */);
1320 break;
1321 case Instruction::FILLED_NEW_ARRAY:
buzbeefa57c472012-11-21 12:06:18 -08001322 ConvertInvoke(cu, bb, mir, kInterface, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001323 true /* NewFilledArray */);
1324 break;
1325 case Instruction::FILLED_NEW_ARRAY_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001326 ConvertInvoke(cu, bb, mir, kInterface, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001327 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001328 break;
1329
1330 case Instruction::CONST_STRING:
1331 case Instruction::CONST_STRING_JUMBO:
buzbeefa57c472012-11-21 12:06:18 -08001332 ConvertConstObject(cu, vB, greenland::IntrinsicHelper::ConstString,
1333 rl_dest);
buzbee101305f2012-06-28 18:00:56 -07001334 break;
1335
1336 case Instruction::CONST_CLASS:
buzbeefa57c472012-11-21 12:06:18 -08001337 ConvertConstObject(cu, vB, greenland::IntrinsicHelper::ConstClass,
1338 rl_dest);
buzbee101305f2012-06-28 18:00:56 -07001339 break;
1340
1341 case Instruction::CHECK_CAST:
buzbeefa57c472012-11-21 12:06:18 -08001342 ConvertCheckCast(cu, vB, rl_src[0]);
buzbee6969d502012-06-15 16:40:31 -07001343 break;
1344
buzbee4f1181f2012-06-22 13:52:12 -07001345 case Instruction::NEW_INSTANCE:
buzbeefa57c472012-11-21 12:06:18 -08001346 ConvertNewInstance(cu, vB, rl_dest);
buzbee4f1181f2012-06-22 13:52:12 -07001347 break;
1348
buzbee32412962012-06-26 16:27:56 -07001349 case Instruction::MOVE_EXCEPTION:
buzbeefa57c472012-11-21 12:06:18 -08001350 ConvertMoveException(cu, rl_dest);
buzbee32412962012-06-26 16:27:56 -07001351 break;
1352
1353 case Instruction::THROW:
buzbeefa57c472012-11-21 12:06:18 -08001354 ConvertThrow(cu, rl_src[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001355 /*
1356 * If this throw is standalone, terminate.
1357 * If it might rethrow, force termination
1358 * of the following block.
1359 */
buzbeefa57c472012-11-21 12:06:18 -08001360 if (bb->fall_through == NULL) {
1361 cu->irb->CreateUnreachable();
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001362 } else {
buzbeefa57c472012-11-21 12:06:18 -08001363 bb->fall_through->fall_through = NULL;
1364 bb->fall_through->taken = NULL;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001365 }
buzbee32412962012-06-26 16:27:56 -07001366 break;
1367
buzbee2cfc6392012-05-07 14:51:40 -07001368 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001369 case Instruction::MOVE_RESULT:
1370 case Instruction::MOVE_RESULT_OBJECT:
buzbee9a2487f2012-07-26 14:01:13 -07001371 /*
jeffhao9a4f0032012-08-30 16:17:40 -07001372 * All move_results should have been folded into the preceeding invoke.
buzbee9a2487f2012-07-26 14:01:13 -07001373 */
jeffhao9a4f0032012-08-30 16:17:40 -07001374 LOG(FATAL) << "Unexpected move_result";
buzbee2cfc6392012-05-07 14:51:40 -07001375 break;
1376
1377 case Instruction::MONITOR_ENTER:
buzbeefa57c472012-11-21 12:06:18 -08001378 ConvertMonitorEnterExit(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001379 greenland::IntrinsicHelper::MonitorEnter,
buzbeefa57c472012-11-21 12:06:18 -08001380 rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001381 break;
1382
1383 case Instruction::MONITOR_EXIT:
buzbeefa57c472012-11-21 12:06:18 -08001384 ConvertMonitorEnterExit(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001385 greenland::IntrinsicHelper::MonitorExit,
buzbeefa57c472012-11-21 12:06:18 -08001386 rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001387 break;
1388
1389 case Instruction::ARRAY_LENGTH:
buzbeefa57c472012-11-21 12:06:18 -08001390 ConvertArrayLength(cu, opt_flags, rl_dest, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001391 break;
1392
1393 case Instruction::NEW_ARRAY:
buzbeefa57c472012-11-21 12:06:18 -08001394 ConvertNewArray(cu, vC, rl_dest, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001395 break;
1396
1397 case Instruction::INSTANCE_OF:
buzbeefa57c472012-11-21 12:06:18 -08001398 ConvertInstanceOf(cu, vC, rl_dest, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001399 break;
1400
1401 case Instruction::AGET:
buzbeefa57c472012-11-21 12:06:18 -08001402 if (rl_dest.fp) {
1403 ConvertAget(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001404 greenland::IntrinsicHelper::HLArrayGetFloat,
buzbeefa57c472012-11-21 12:06:18 -08001405 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001406 } else {
buzbeefa57c472012-11-21 12:06:18 -08001407 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGet,
1408 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001409 }
1410 break;
1411 case Instruction::AGET_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -08001412 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetObject,
1413 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001414 break;
1415 case Instruction::AGET_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -08001416 ConvertAget(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001417 greenland::IntrinsicHelper::HLArrayGetBoolean,
buzbeefa57c472012-11-21 12:06:18 -08001418 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001419 break;
1420 case Instruction::AGET_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001421 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetByte,
1422 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001423 break;
1424 case Instruction::AGET_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001425 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetChar,
1426 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001427 break;
1428 case Instruction::AGET_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001429 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetShort,
1430 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001431 break;
1432 case Instruction::AGET_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001433 if (rl_dest.fp) {
1434 ConvertAget(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001435 greenland::IntrinsicHelper::HLArrayGetDouble,
buzbeefa57c472012-11-21 12:06:18 -08001436 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001437 } else {
buzbeefa57c472012-11-21 12:06:18 -08001438 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetWide,
1439 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001440 }
1441 break;
1442
1443 case Instruction::APUT:
buzbeefa57c472012-11-21 12:06:18 -08001444 if (rl_src[0].fp) {
1445 ConvertAput(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001446 greenland::IntrinsicHelper::HLArrayPutFloat,
buzbeefa57c472012-11-21 12:06:18 -08001447 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001448 } else {
buzbeefa57c472012-11-21 12:06:18 -08001449 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPut,
1450 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001451 }
1452 break;
1453 case Instruction::APUT_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -08001454 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutObject,
1455 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001456 break;
1457 case Instruction::APUT_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -08001458 ConvertAput(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001459 greenland::IntrinsicHelper::HLArrayPutBoolean,
buzbeefa57c472012-11-21 12:06:18 -08001460 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001461 break;
1462 case Instruction::APUT_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001463 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutByte,
1464 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001465 break;
1466 case Instruction::APUT_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001467 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutChar,
1468 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001469 break;
1470 case Instruction::APUT_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001471 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutShort,
1472 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001473 break;
1474 case Instruction::APUT_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001475 if (rl_src[0].fp) {
1476 ConvertAput(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001477 greenland::IntrinsicHelper::HLArrayPutDouble,
buzbeefa57c472012-11-21 12:06:18 -08001478 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001479 } else {
buzbeefa57c472012-11-21 12:06:18 -08001480 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutWide,
1481 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001482 }
1483 break;
1484
buzbee101305f2012-06-28 18:00:56 -07001485 case Instruction::IGET:
buzbeefa57c472012-11-21 12:06:18 -08001486 if (rl_dest.fp) {
1487 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetFloat,
1488 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001489 } else {
buzbeefa57c472012-11-21 12:06:18 -08001490 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGet,
1491 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001492 }
buzbee2cfc6392012-05-07 14:51:40 -07001493 break;
buzbee101305f2012-06-28 18:00:56 -07001494 case Instruction::IGET_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -08001495 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetObject,
1496 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001497 break;
1498 case Instruction::IGET_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -08001499 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetBoolean,
1500 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001501 break;
1502 case Instruction::IGET_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001503 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetByte,
1504 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001505 break;
1506 case Instruction::IGET_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001507 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetChar,
1508 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001509 break;
1510 case Instruction::IGET_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001511 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetShort,
1512 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001513 break;
1514 case Instruction::IGET_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001515 if (rl_dest.fp) {
1516 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetDouble,
1517 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001518 } else {
buzbeefa57c472012-11-21 12:06:18 -08001519 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetWide,
1520 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001521 }
1522 break;
1523 case Instruction::IPUT:
buzbeefa57c472012-11-21 12:06:18 -08001524 if (rl_src[0].fp) {
1525 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutFloat,
1526 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001527 } else {
buzbeefa57c472012-11-21 12:06:18 -08001528 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPut,
1529 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001530 }
1531 break;
1532 case Instruction::IPUT_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -08001533 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutObject,
1534 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001535 break;
1536 case Instruction::IPUT_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -08001537 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutBoolean,
1538 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001539 break;
1540 case Instruction::IPUT_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001541 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutByte,
1542 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001543 break;
1544 case Instruction::IPUT_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001545 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutChar,
1546 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001547 break;
1548 case Instruction::IPUT_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001549 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutShort,
1550 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001551 break;
1552 case Instruction::IPUT_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001553 if (rl_src[0].fp) {
1554 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutDouble,
1555 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001556 } else {
buzbeefa57c472012-11-21 12:06:18 -08001557 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutWide,
1558 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001559 }
buzbee2cfc6392012-05-07 14:51:40 -07001560 break;
1561
1562 case Instruction::FILL_ARRAY_DATA:
buzbeefa57c472012-11-21 12:06:18 -08001563 ConvertFillArrayData(cu, vB, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001564 break;
1565
buzbee76592632012-06-29 15:18:35 -07001566 case Instruction::LONG_TO_INT:
buzbeefa57c472012-11-21 12:06:18 -08001567 ConvertLongToInt(cu, rl_dest, rl_src[0]);
buzbee76592632012-06-29 15:18:35 -07001568 break;
1569
buzbee101305f2012-06-28 18:00:56 -07001570 case Instruction::INT_TO_LONG:
buzbeefa57c472012-11-21 12:06:18 -08001571 ConvertIntToLong(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001572 break;
1573
buzbee101305f2012-06-28 18:00:56 -07001574 case Instruction::INT_TO_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001575 ConvertIntNarrowing(cu, rl_dest, rl_src[0],
buzbee101305f2012-06-28 18:00:56 -07001576 greenland::IntrinsicHelper::IntToChar);
1577 break;
1578 case Instruction::INT_TO_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001579 ConvertIntNarrowing(cu, rl_dest, rl_src[0],
buzbee101305f2012-06-28 18:00:56 -07001580 greenland::IntrinsicHelper::IntToByte);
1581 break;
1582 case Instruction::INT_TO_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001583 ConvertIntNarrowing(cu, rl_dest, rl_src[0],
buzbee101305f2012-06-28 18:00:56 -07001584 greenland::IntrinsicHelper::IntToShort);
1585 break;
1586
buzbee76592632012-06-29 15:18:35 -07001587 case Instruction::INT_TO_FLOAT:
1588 case Instruction::LONG_TO_FLOAT:
buzbeefa57c472012-11-21 12:06:18 -08001589 ConvertIntToFP(cu, cu->irb->getFloatTy(), rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001590 break;
1591
buzbee76592632012-06-29 15:18:35 -07001592 case Instruction::INT_TO_DOUBLE:
1593 case Instruction::LONG_TO_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001594 ConvertIntToFP(cu, cu->irb->getDoubleTy(), rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001595 break;
1596
buzbee76592632012-06-29 15:18:35 -07001597 case Instruction::FLOAT_TO_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001598 ConvertFloatToDouble(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001599 break;
1600
buzbee76592632012-06-29 15:18:35 -07001601 case Instruction::DOUBLE_TO_FLOAT:
buzbeefa57c472012-11-21 12:06:18 -08001602 ConvertDoubleToFloat(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001603 break;
1604
1605 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001606 case Instruction::NEG_INT:
buzbeefa57c472012-11-21 12:06:18 -08001607 ConvertNeg(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001608 break;
1609
1610 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001611 case Instruction::NEG_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001612 ConvertNegFP(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001613 break;
1614
buzbee76592632012-06-29 15:18:35 -07001615 case Instruction::NOT_LONG:
1616 case Instruction::NOT_INT:
buzbeefa57c472012-11-21 12:06:18 -08001617 ConvertNot(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001618 break;
1619
buzbee2cfc6392012-05-07 14:51:40 -07001620 case Instruction::FLOAT_TO_INT:
buzbeefa57c472012-11-21 12:06:18 -08001621 ConvertFPToInt(cu, greenland::IntrinsicHelper::F2I, rl_dest, rl_src[0]);
TDYa1274ec8ccd2012-08-11 07:04:57 -07001622 break;
1623
buzbee2cfc6392012-05-07 14:51:40 -07001624 case Instruction::DOUBLE_TO_INT:
buzbeefa57c472012-11-21 12:06:18 -08001625 ConvertFPToInt(cu, greenland::IntrinsicHelper::D2I, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001626 break;
1627
buzbee76592632012-06-29 15:18:35 -07001628 case Instruction::FLOAT_TO_LONG:
buzbeefa57c472012-11-21 12:06:18 -08001629 ConvertFPToInt(cu, greenland::IntrinsicHelper::F2L, rl_dest, rl_src[0]);
TDYa1274ec8ccd2012-08-11 07:04:57 -07001630 break;
1631
buzbee76592632012-06-29 15:18:35 -07001632 case Instruction::DOUBLE_TO_LONG:
buzbeefa57c472012-11-21 12:06:18 -08001633 ConvertFPToInt(cu, greenland::IntrinsicHelper::D2L, rl_dest, rl_src[0]);
buzbee76592632012-06-29 15:18:35 -07001634 break;
1635
1636 case Instruction::CMPL_FLOAT:
buzbeefa57c472012-11-21 12:06:18 -08001637 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmplFloat,
1638 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001639 break;
1640 case Instruction::CMPG_FLOAT:
buzbeefa57c472012-11-21 12:06:18 -08001641 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmpgFloat,
1642 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001643 break;
1644 case Instruction::CMPL_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001645 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmplDouble,
1646 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001647 break;
1648 case Instruction::CMPG_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001649 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmpgDouble,
1650 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001651 break;
1652 case Instruction::CMP_LONG:
buzbeefa57c472012-11-21 12:06:18 -08001653 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmpLong,
1654 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001655 break;
1656
buzbee76592632012-06-29 15:18:35 -07001657 case Instruction::PACKED_SWITCH:
buzbeefa57c472012-11-21 12:06:18 -08001658 ConvertPackedSwitch(cu, bb, vB, rl_src[0]);
buzbee76592632012-06-29 15:18:35 -07001659 break;
1660
1661 case Instruction::SPARSE_SWITCH:
buzbeefa57c472012-11-21 12:06:18 -08001662 ConvertSparseSwitch(cu, bb, vB, rl_src[0]);
buzbee76592632012-06-29 15:18:35 -07001663 break;
buzbee2cfc6392012-05-07 14:51:40 -07001664
1665 default:
buzbee32412962012-06-26 16:27:56 -07001666 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001667 res = true;
1668 }
buzbeefa57c472012-11-21 12:06:18 -08001669 if (object_definition) {
1670 SetShadowFrameEntry(cu, reinterpret_cast<llvm::Value*>
1671 (cu->llvm_values.elem_list[rl_dest.orig_sreg]));
buzbeeb03f4872012-06-11 15:22:11 -07001672 }
buzbee2cfc6392012-05-07 14:51:40 -07001673 return res;
1674}
1675
1676/* Extended MIR instructions like PHI */
buzbeefa57c472012-11-21 12:06:18 -08001677static void ConvertExtendedMIR(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
1678 llvm::BasicBlock* llvm_bb)
buzbee2cfc6392012-05-07 14:51:40 -07001679{
1680
buzbeecbd6d442012-11-17 14:11:25 -08001681 switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) {
buzbee2cfc6392012-05-07 14:51:40 -07001682 case kMirOpPhi: {
buzbeefa57c472012-11-21 12:06:18 -08001683 RegLocation rl_dest = cu->reg_location[mir->ssa_rep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001684 /*
1685 * The Art compiler's Phi nodes only handle 32-bit operands,
1686 * representing wide values using a matched set of Phi nodes
1687 * for the lower and upper halves. In the llvm world, we only
1688 * want a single Phi for wides. Here we will simply discard
1689 * the Phi node representing the high word.
1690 */
buzbeefa57c472012-11-21 12:06:18 -08001691 if (rl_dest.high_word) {
buzbee2a83e8f2012-07-13 16:42:30 -07001692 return; // No Phi node - handled via low word
1693 }
buzbeecbd6d442012-11-17 14:11:25 -08001694 int* incoming = reinterpret_cast<int*>(mir->dalvikInsn.vB);
buzbeefa57c472012-11-21 12:06:18 -08001695 llvm::Type* phi_type =
1696 LlvmTypeFromLocRec(cu, rl_dest);
1697 llvm::PHINode* phi = cu->irb->CreatePHI(phi_type, mir->ssa_rep->num_uses);
1698 for (int i = 0; i < mir->ssa_rep->num_uses; i++) {
buzbee2cfc6392012-05-07 14:51:40 -07001699 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001700 // Don't check width here.
buzbeefa57c472012-11-21 12:06:18 -08001701 loc = GetRawSrc(cu, mir, i);
1702 DCHECK_EQ(rl_dest.wide, loc.wide);
1703 DCHECK_EQ(rl_dest.wide & rl_dest.high_word, loc.wide & loc.high_word);
1704 DCHECK_EQ(rl_dest.fp, loc.fp);
1705 DCHECK_EQ(rl_dest.core, loc.core);
1706 DCHECK_EQ(rl_dest.ref, loc.ref);
buzbeed1643e42012-09-05 14:06:51 -07001707 SafeMap<unsigned int, unsigned int>::iterator it;
buzbeefa57c472012-11-21 12:06:18 -08001708 it = cu->block_id_map.find(incoming[i]);
1709 DCHECK(it != cu->block_id_map.end());
1710 phi->addIncoming(GetLLVMValue(cu, loc.orig_sreg),
1711 GetLLVMBlock(cu, it->second));
buzbee2cfc6392012-05-07 14:51:40 -07001712 }
buzbeefa57c472012-11-21 12:06:18 -08001713 DefineValue(cu, phi, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -07001714 break;
1715 }
1716 case kMirOpCopy: {
1717 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1718 break;
1719 }
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001720 case kMirOpNop:
buzbeefa57c472012-11-21 12:06:18 -08001721 if ((mir == bb->last_mir_insn) && (bb->taken == NULL) &&
1722 (bb->fall_through == NULL)) {
1723 cu->irb->CreateUnreachable();
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001724 }
1725 break;
1726
buzbeeb046e162012-10-30 15:48:42 -07001727 // TODO: need GBC intrinsic to take advantage of fused operations
buzbee2cfc6392012-05-07 14:51:40 -07001728 case kMirOpFusedCmplFloat:
buzbeeb046e162012-10-30 15:48:42 -07001729 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpFloat unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001730 break;
1731 case kMirOpFusedCmpgFloat:
buzbeeb046e162012-10-30 15:48:42 -07001732 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmgFloat unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001733 break;
1734 case kMirOpFusedCmplDouble:
buzbeeb046e162012-10-30 15:48:42 -07001735 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmplDouble unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001736 break;
1737 case kMirOpFusedCmpgDouble:
buzbeeb046e162012-10-30 15:48:42 -07001738 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpgDouble unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001739 break;
1740 case kMirOpFusedCmpLong:
buzbeeb046e162012-10-30 15:48:42 -07001741 UNIMPLEMENTED(FATAL) << "kMirOpLongCmpBranch unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001742 break;
buzbee2cfc6392012-05-07 14:51:40 -07001743 default:
1744 break;
1745 }
1746}
1747
buzbeefa57c472012-11-21 12:06:18 -08001748static void SetDexOffset(CompilationUnit* cu, int32_t offset)
buzbee2cfc6392012-05-07 14:51:40 -07001749{
buzbeefa57c472012-11-21 12:06:18 -08001750 cu->current_dalvik_offset = offset;
1751 llvm::SmallVector<llvm::Value*, 1> array_ref;
1752 array_ref.push_back(cu->irb->getInt32(offset));
1753 llvm::MDNode* node = llvm::MDNode::get(*cu->context, array_ref);
1754 cu->irb->SetDexOffset(node);
buzbee2cfc6392012-05-07 14:51:40 -07001755}
1756
1757// Attach method info as metadata to special intrinsic
buzbeefa57c472012-11-21 12:06:18 -08001758static void SetMethodInfo(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -07001759{
1760 // We don't want dex offset on this
buzbeefa57c472012-11-21 12:06:18 -08001761 cu->irb->SetDexOffset(NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001762 greenland::IntrinsicHelper::IntrinsicId id;
1763 id = greenland::IntrinsicHelper::MethodInfo;
buzbeefa57c472012-11-21 12:06:18 -08001764 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
1765 llvm::Instruction* inst = cu->irb->CreateCall(intr);
1766 llvm::SmallVector<llvm::Value*, 2> reg_info;
1767 reg_info.push_back(cu->irb->getInt32(cu->num_ins));
1768 reg_info.push_back(cu->irb->getInt32(cu->num_regs));
1769 reg_info.push_back(cu->irb->getInt32(cu->num_outs));
1770 reg_info.push_back(cu->irb->getInt32(cu->num_compiler_temps));
1771 reg_info.push_back(cu->irb->getInt32(cu->num_ssa_regs));
1772 llvm::MDNode* reg_info_node = llvm::MDNode::get(*cu->context, reg_info);
1773 inst->setMetadata("RegInfo", reg_info_node);
1774 int promo_size = cu->num_dalvik_registers + cu->num_compiler_temps + 1;
buzbee2cfc6392012-05-07 14:51:40 -07001775 llvm::SmallVector<llvm::Value*, 50> pmap;
buzbeefa57c472012-11-21 12:06:18 -08001776 for (int i = 0; i < promo_size; i++) {
1777 PromotionMap* p = &cu->promotion_map[i];
1778 int32_t map_data = ((p->first_in_pair & 0xff) << 24) |
buzbee52a77fc2012-11-20 19:50:46 -08001779 ((p->FpReg & 0xff) << 16) |
buzbeefa57c472012-11-21 12:06:18 -08001780 ((p->core_reg & 0xff) << 8) |
1781 ((p->fp_location & 0xf) << 4) |
1782 (p->core_location & 0xf);
1783 pmap.push_back(cu->irb->getInt32(map_data));
buzbee2cfc6392012-05-07 14:51:40 -07001784 }
buzbeefa57c472012-11-21 12:06:18 -08001785 llvm::MDNode* map_node = llvm::MDNode::get(*cu->context, pmap);
1786 inst->setMetadata("PromotionMap", map_node);
1787 SetDexOffset(cu, cu->current_dalvik_offset);
buzbee2cfc6392012-05-07 14:51:40 -07001788}
1789
1790/* Handle the content in each basic block */
buzbeefa57c472012-11-21 12:06:18 -08001791static bool BlockBitcodeConversion(CompilationUnit* cu, BasicBlock* bb)
buzbee2cfc6392012-05-07 14:51:40 -07001792{
buzbeefa57c472012-11-21 12:06:18 -08001793 if (bb->block_type == kDead) return false;
1794 llvm::BasicBlock* llvm_bb = GetLLVMBlock(cu, bb->id);
1795 if (llvm_bb == NULL) {
1796 CHECK(bb->block_type == kExitBlock);
buzbeef5f5a122012-09-21 13:57:36 -07001797 } else {
buzbeefa57c472012-11-21 12:06:18 -08001798 cu->irb->SetInsertPoint(llvm_bb);
1799 SetDexOffset(cu, bb->start_offset);
buzbeef5f5a122012-09-21 13:57:36 -07001800 }
buzbee2cfc6392012-05-07 14:51:40 -07001801
buzbeefa57c472012-11-21 12:06:18 -08001802 if (cu->verbose) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001803 LOG(INFO) << "................................";
1804 LOG(INFO) << "Block id " << bb->id;
buzbeefa57c472012-11-21 12:06:18 -08001805 if (llvm_bb != NULL) {
1806 LOG(INFO) << "label " << llvm_bb->getName().str().c_str();
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001807 } else {
buzbeefa57c472012-11-21 12:06:18 -08001808 LOG(INFO) << "llvm_bb is NULL";
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001809 }
1810 }
1811
buzbeefa57c472012-11-21 12:06:18 -08001812 if (bb->block_type == kEntryBlock) {
1813 SetMethodInfo(cu);
1814 bool *can_be_ref = static_cast<bool*>(NewMem(cu, sizeof(bool) * cu->num_dalvik_registers,
buzbeecbd6d442012-11-17 14:11:25 -08001815 true, kAllocMisc));
buzbeefa57c472012-11-21 12:06:18 -08001816 for (int i = 0; i < cu->num_ssa_regs; i++) {
1817 int v_reg = SRegToVReg(cu, i);
1818 if (v_reg > SSA_METHOD_BASEREG) {
1819 can_be_ref[SRegToVReg(cu, i)] |= cu->reg_location[i].ref;
buzbee6ec5e232012-09-20 15:50:03 -07001820 }
buzbeeb03f4872012-06-11 15:22:11 -07001821 }
buzbeefa57c472012-11-21 12:06:18 -08001822 for (int i = 0; i < cu->num_dalvik_registers; i++) {
1823 if (can_be_ref[i]) {
1824 cu->num_shadow_frame_entries++;
buzbeeb03f4872012-06-11 15:22:11 -07001825 }
1826 }
buzbeefa57c472012-11-21 12:06:18 -08001827 if (cu->num_shadow_frame_entries > 0) {
1828 cu->shadow_map = static_cast<int*>(NewMem(cu, sizeof(int) * cu->num_shadow_frame_entries,
buzbeecbd6d442012-11-17 14:11:25 -08001829 true, kAllocMisc));
buzbeefa57c472012-11-21 12:06:18 -08001830 for (int i = 0, j = 0; i < cu->num_dalvik_registers; i++) {
1831 if (can_be_ref[i]) {
1832 cu->shadow_map[j++] = i;
buzbeeb03f4872012-06-11 15:22:11 -07001833 }
1834 }
buzbeeb03f4872012-06-11 15:22:11 -07001835 }
Shih-wei Liao569daf12012-08-10 23:22:33 -07001836 greenland::IntrinsicHelper::IntrinsicId id =
1837 greenland::IntrinsicHelper::AllocaShadowFrame;
buzbeefa57c472012-11-21 12:06:18 -08001838 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id);
1839 llvm::Value* entries = cu->irb->getInt32(cu->num_shadow_frame_entries);
1840 llvm::Value* dalvik_regs = cu->irb->getInt32(cu->num_dalvik_registers);
1841 llvm::Value* args[] = { entries, dalvik_regs };
1842 cu->irb->CreateCall(func, args);
1843 } else if (bb->block_type == kExitBlock) {
buzbee2cfc6392012-05-07 14:51:40 -07001844 /*
1845 * Because of the differences between how MIR/LIR and llvm handle exit
1846 * blocks, we won't explicitly covert them. On the llvm-to-lir
1847 * path, it will need to be regenereated.
1848 */
1849 return false;
buzbeefa57c472012-11-21 12:06:18 -08001850 } else if (bb->block_type == kExceptionHandling) {
buzbee6969d502012-06-15 16:40:31 -07001851 /*
1852 * Because we're deferring null checking, delete the associated empty
1853 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001854 */
buzbeefa57c472012-11-21 12:06:18 -08001855 llvm_bb->eraseFromParent();
buzbee6969d502012-06-15 16:40:31 -07001856 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001857 }
1858
buzbeefa57c472012-11-21 12:06:18 -08001859 for (MIR* mir = bb->first_mir_insn; mir; mir = mir->next) {
buzbee2cfc6392012-05-07 14:51:40 -07001860
buzbeefa57c472012-11-21 12:06:18 -08001861 SetDexOffset(cu, mir->offset);
buzbee2cfc6392012-05-07 14:51:40 -07001862
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001863 int opcode = mir->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -08001864 Instruction::Format dalvik_format =
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001865 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001866
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001867 if (opcode == kMirOpCheck) {
1868 // Combine check and work halves of throwing instruction.
buzbeefa57c472012-11-21 12:06:18 -08001869 MIR* work_half = mir->meta.throw_insn;
1870 mir->dalvikInsn.opcode = work_half->dalvikInsn.opcode;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001871 opcode = mir->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -08001872 SSARepresentation* ssa_rep = work_half->ssa_rep;
1873 work_half->ssa_rep = mir->ssa_rep;
1874 mir->ssa_rep = ssa_rep;
1875 work_half->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1876 if (bb->successor_block_list.block_list_type == kCatch) {
1877 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001878 greenland::IntrinsicHelper::CatchTargets);
buzbeefa57c472012-11-21 12:06:18 -08001879 llvm::Value* switch_key =
1880 cu->irb->CreateCall(intr, cu->irb->getInt32(mir->offset));
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001881 GrowableListIterator iter;
buzbeefa57c472012-11-21 12:06:18 -08001882 GrowableListIteratorInit(&bb->successor_block_list.blocks, &iter);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001883 // New basic block to use for work half
buzbeefa57c472012-11-21 12:06:18 -08001884 llvm::BasicBlock* work_bb =
1885 llvm::BasicBlock::Create(*cu->context, "", cu->func);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001886 llvm::SwitchInst* sw =
buzbeefa57c472012-11-21 12:06:18 -08001887 cu->irb->CreateSwitch(switch_key, work_bb,
1888 bb->successor_block_list.blocks.num_used);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001889 while (true) {
buzbeefa57c472012-11-21 12:06:18 -08001890 SuccessorBlockInfo *successor_block_info =
buzbee52a77fc2012-11-20 19:50:46 -08001891 reinterpret_cast<SuccessorBlockInfo*>(GrowableListIteratorNext(&iter));
buzbeefa57c472012-11-21 12:06:18 -08001892 if (successor_block_info == NULL) break;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001893 llvm::BasicBlock *target =
buzbeefa57c472012-11-21 12:06:18 -08001894 GetLLVMBlock(cu, successor_block_info->block->id);
1895 int type_index = successor_block_info->key;
1896 sw->addCase(cu->irb->getInt32(type_index), target);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001897 }
buzbeefa57c472012-11-21 12:06:18 -08001898 llvm_bb = work_bb;
1899 cu->irb->SetInsertPoint(llvm_bb);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001900 }
1901 }
1902
1903 if (opcode >= kMirOpFirst) {
buzbeefa57c472012-11-21 12:06:18 -08001904 ConvertExtendedMIR(cu, bb, mir, llvm_bb);
buzbee2cfc6392012-05-07 14:51:40 -07001905 continue;
1906 }
1907
buzbeefa57c472012-11-21 12:06:18 -08001908 bool not_handled = ConvertMIRNode(cu, mir, bb, llvm_bb,
1909 NULL /* label_list */);
1910 if (not_handled) {
1911 Instruction::Code dalvik_opcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001912 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001913 mir->offset, opcode,
buzbeefa57c472012-11-21 12:06:18 -08001914 Instruction::Name(dalvik_opcode),
1915 dalvik_format);
buzbee2cfc6392012-05-07 14:51:40 -07001916 }
1917 }
1918
buzbeefa57c472012-11-21 12:06:18 -08001919 if (bb->block_type == kEntryBlock) {
1920 cu->entryTarget_bb = GetLLVMBlock(cu, bb->fall_through->id);
1921 } else if ((bb->fall_through != NULL) && !bb->has_return) {
1922 cu->irb->CreateBr(GetLLVMBlock(cu, bb->fall_through->id));
buzbee2cfc6392012-05-07 14:51:40 -07001923 }
1924
1925 return false;
1926}
1927
buzbeefa57c472012-11-21 12:06:18 -08001928char RemapShorty(char shorty_type) {
buzbee4f4dfc72012-07-02 14:54:44 -07001929 /*
1930 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1931 * and longs/doubles are represented as a pair of registers. When sub-word
1932 * arguments (and method results) are passed, they are extended to Dalvik
1933 * virtual register containers. Because llvm is picky about type consistency,
1934 * we must either cast the "real" type to 32-bit container multiple Dalvik
1935 * register types, or always use the expanded values.
1936 * Here, we're doing the latter. We map the shorty signature to container
1937 * types (which is valid so long as we always do a real expansion of passed
1938 * arguments and field loads).
1939 */
buzbeefa57c472012-11-21 12:06:18 -08001940 switch(shorty_type) {
1941 case 'Z' : shorty_type = 'I'; break;
1942 case 'B' : shorty_type = 'I'; break;
1943 case 'S' : shorty_type = 'I'; break;
1944 case 'C' : shorty_type = 'I'; break;
buzbee4f4dfc72012-07-02 14:54:44 -07001945 default: break;
1946 }
buzbeefa57c472012-11-21 12:06:18 -08001947 return shorty_type;
buzbee4f4dfc72012-07-02 14:54:44 -07001948}
1949
buzbeefa57c472012-11-21 12:06:18 -08001950static llvm::FunctionType* GetFunctionType(CompilationUnit* cu) {
buzbee2cfc6392012-05-07 14:51:40 -07001951
1952 // Get return type
buzbeefa57c472012-11-21 12:06:18 -08001953 llvm::Type* ret_type = cu->irb->GetJType(RemapShorty(cu->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001954 greenland::kAccurate);
1955
1956 // Get argument type
1957 std::vector<llvm::Type*> args_type;
1958
1959 // method object
buzbeefa57c472012-11-21 12:06:18 -08001960 args_type.push_back(cu->irb->GetJMethodTy());
buzbee2cfc6392012-05-07 14:51:40 -07001961
1962 // Do we have a "this"?
buzbeefa57c472012-11-21 12:06:18 -08001963 if ((cu->access_flags & kAccStatic) == 0) {
1964 args_type.push_back(cu->irb->GetJObjectTy());
buzbee2cfc6392012-05-07 14:51:40 -07001965 }
1966
buzbeefa57c472012-11-21 12:06:18 -08001967 for (uint32_t i = 1; i < strlen(cu->shorty); ++i) {
1968 args_type.push_back(cu->irb->GetJType(RemapShorty(cu->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001969 greenland::kAccurate));
1970 }
1971
1972 return llvm::FunctionType::get(ret_type, args_type, false);
1973}
1974
buzbeefa57c472012-11-21 12:06:18 -08001975static bool CreateFunction(CompilationUnit* cu) {
1976 std::string func_name(PrettyMethod(cu->method_idx, *cu->dex_file,
buzbee2cfc6392012-05-07 14:51:40 -07001977 /* with_signature */ false));
buzbeefa57c472012-11-21 12:06:18 -08001978 llvm::FunctionType* func_type = GetFunctionType(cu);
buzbee2cfc6392012-05-07 14:51:40 -07001979
1980 if (func_type == NULL) {
1981 return false;
1982 }
1983
buzbeefa57c472012-11-21 12:06:18 -08001984 cu->func = llvm::Function::Create(func_type,
buzbee2cfc6392012-05-07 14:51:40 -07001985 llvm::Function::ExternalLinkage,
buzbeefa57c472012-11-21 12:06:18 -08001986 func_name, cu->module);
buzbee2cfc6392012-05-07 14:51:40 -07001987
buzbeefa57c472012-11-21 12:06:18 -08001988 llvm::Function::arg_iterator arg_iter(cu->func->arg_begin());
1989 llvm::Function::arg_iterator arg_end(cu->func->arg_end());
buzbee2cfc6392012-05-07 14:51:40 -07001990
1991 arg_iter->setName("method");
1992 ++arg_iter;
1993
buzbeefa57c472012-11-21 12:06:18 -08001994 int start_sreg = cu->num_regs;
buzbee2cfc6392012-05-07 14:51:40 -07001995
1996 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
buzbeefa57c472012-11-21 12:06:18 -08001997 arg_iter->setName(StringPrintf("v%i_0", start_sreg));
1998 start_sreg += cu->reg_location[start_sreg].wide ? 2 : 1;
buzbee2cfc6392012-05-07 14:51:40 -07001999 }
2000
2001 return true;
2002}
2003
buzbeefa57c472012-11-21 12:06:18 -08002004static bool CreateLLVMBasicBlock(CompilationUnit* cu, BasicBlock* bb)
buzbee2cfc6392012-05-07 14:51:40 -07002005{
2006 // Skip the exit block
buzbeefa57c472012-11-21 12:06:18 -08002007 if ((bb->block_type == kDead) ||(bb->block_type == kExitBlock)) {
2008 cu->id_to_block_map.Put(bb->id, NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002009 } else {
buzbeefa57c472012-11-21 12:06:18 -08002010 int offset = bb->start_offset;
2011 bool entry_block = (bb->block_type == kEntryBlock);
2012 llvm::BasicBlock* llvm_bb =
2013 llvm::BasicBlock::Create(*cu->context, entry_block ? "entry" :
2014 StringPrintf(kLabelFormat, bb->catch_entry ? kCatchBlock :
2015 kNormalBlock, offset, bb->id), cu->func);
2016 if (entry_block) {
2017 cu->entry_bb = llvm_bb;
2018 cu->placeholder_bb =
2019 llvm::BasicBlock::Create(*cu->context, "placeholder",
2020 cu->func);
buzbee2cfc6392012-05-07 14:51:40 -07002021 }
buzbeefa57c472012-11-21 12:06:18 -08002022 cu->id_to_block_map.Put(bb->id, llvm_bb);
buzbee2cfc6392012-05-07 14:51:40 -07002023 }
2024 return false;
2025}
2026
2027
2028/*
2029 * Convert MIR to LLVM_IR
2030 * o For each ssa name, create LLVM named value. Type these
2031 * appropriately, and ignore high half of wide and double operands.
2032 * o For each MIR basic block, create an LLVM basic block.
2033 * o Iterate through the MIR a basic block at a time, setting arguments
2034 * to recovered ssa name.
2035 */
buzbeefa57c472012-11-21 12:06:18 -08002036void MethodMIR2Bitcode(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -07002037{
buzbeefa57c472012-11-21 12:06:18 -08002038 InitIR(cu);
2039 CompilerInitGrowableList(cu, &cu->llvm_values, cu->num_ssa_regs);
buzbee2cfc6392012-05-07 14:51:40 -07002040
2041 // Create the function
buzbeefa57c472012-11-21 12:06:18 -08002042 CreateFunction(cu);
buzbee2cfc6392012-05-07 14:51:40 -07002043
2044 // Create an LLVM basic block for each MIR block in dfs preorder
buzbeefa57c472012-11-21 12:06:18 -08002045 DataFlowAnalysisDispatcher(cu, CreateLLVMBasicBlock,
2046 kPreOrderDFSTraversal, false /* is_iterative */);
buzbee2cfc6392012-05-07 14:51:40 -07002047 /*
2048 * Create an llvm named value for each MIR SSA name. Note: we'll use
2049 * placeholders for all non-argument values (because we haven't seen
2050 * the definition yet).
2051 */
buzbeefa57c472012-11-21 12:06:18 -08002052 cu->irb->SetInsertPoint(cu->placeholder_bb);
2053 llvm::Function::arg_iterator arg_iter(cu->func->arg_begin());
buzbee2cfc6392012-05-07 14:51:40 -07002054 arg_iter++; /* Skip path method */
buzbeefa57c472012-11-21 12:06:18 -08002055 for (int i = 0; i < cu->num_ssa_regs; i++) {
buzbee2cfc6392012-05-07 14:51:40 -07002056 llvm::Value* val;
buzbeefa57c472012-11-21 12:06:18 -08002057 RegLocation rl_temp = cu->reg_location[i];
2058 if ((SRegToVReg(cu, i) < 0) || rl_temp.high_word) {
2059 InsertGrowableList(cu, &cu->llvm_values, 0);
2060 } else if ((i < cu->num_regs) ||
2061 (i >= (cu->num_regs + cu->num_ins))) {
2062 llvm::Constant* imm_value = cu->reg_location[i].wide ?
2063 cu->irb->GetJLong(0) : cu->irb->GetJInt(0);
2064 val = EmitConst(cu, imm_value, cu->reg_location[i]);
2065 val->setName(LlvmSSAName(cu, i));
2066 InsertGrowableList(cu, &cu->llvm_values, reinterpret_cast<uintptr_t>(val));
buzbee2cfc6392012-05-07 14:51:40 -07002067 } else {
2068 // Recover previously-created argument values
buzbeefa57c472012-11-21 12:06:18 -08002069 llvm::Value* arg_val = arg_iter++;
2070 InsertGrowableList(cu, &cu->llvm_values, reinterpret_cast<uintptr_t>(arg_val));
buzbee2cfc6392012-05-07 14:51:40 -07002071 }
2072 }
buzbee2cfc6392012-05-07 14:51:40 -07002073
buzbeefa57c472012-11-21 12:06:18 -08002074 DataFlowAnalysisDispatcher(cu, BlockBitcodeConversion,
buzbee2cfc6392012-05-07 14:51:40 -07002075 kPreOrderDFSTraversal, false /* Iterative */);
2076
buzbee4be777b2012-07-12 14:38:18 -07002077 /*
2078 * In a few rare cases of verification failure, the verifier will
2079 * replace one or more Dalvik opcodes with the special
2080 * throw-verification-failure opcode. This can leave the SSA graph
2081 * in an invalid state, as definitions may be lost, while uses retained.
2082 * To work around this problem, we insert placeholder definitions for
2083 * all Dalvik SSA regs in the "placeholder" block. Here, after
2084 * bitcode conversion is complete, we examine those placeholder definitions
2085 * and delete any with no references (which normally is all of them).
2086 *
2087 * If any definitions remain, we link the placeholder block into the
2088 * CFG. Otherwise, it is deleted.
2089 */
buzbeefa57c472012-11-21 12:06:18 -08002090 for (llvm::BasicBlock::iterator it = cu->placeholder_bb->begin(),
2091 it_end = cu->placeholder_bb->end(); it != it_end;) {
buzbee4be777b2012-07-12 14:38:18 -07002092 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2093 DCHECK(inst != NULL);
2094 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2095 DCHECK(val != NULL);
2096 if (val->getNumUses() == 0) {
2097 inst->eraseFromParent();
2098 }
2099 }
buzbeefa57c472012-11-21 12:06:18 -08002100 SetDexOffset(cu, 0);
2101 if (cu->placeholder_bb->empty()) {
2102 cu->placeholder_bb->eraseFromParent();
buzbee4be777b2012-07-12 14:38:18 -07002103 } else {
buzbeefa57c472012-11-21 12:06:18 -08002104 cu->irb->SetInsertPoint(cu->placeholder_bb);
2105 cu->irb->CreateBr(cu->entryTarget_bb);
2106 cu->entryTarget_bb = cu->placeholder_bb;
buzbee4be777b2012-07-12 14:38:18 -07002107 }
buzbeefa57c472012-11-21 12:06:18 -08002108 cu->irb->SetInsertPoint(cu->entry_bb);
2109 cu->irb->CreateBr(cu->entryTarget_bb);
buzbee2cfc6392012-05-07 14:51:40 -07002110
buzbeefa57c472012-11-21 12:06:18 -08002111 if (cu->enable_debug & (1 << kDebugVerifyBitcode)) {
2112 if (llvm::verifyFunction(*cu->func, llvm::PrintMessageAction)) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002113 LOG(INFO) << "Bitcode verification FAILED for "
buzbeefa57c472012-11-21 12:06:18 -08002114 << PrettyMethod(cu->method_idx, *cu->dex_file)
2115 << " of size " << cu->insns_size;
2116 cu->enable_debug |= (1 << kDebugDumpBitcodeFile);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002117 }
2118 }
buzbee2cfc6392012-05-07 14:51:40 -07002119
buzbeefa57c472012-11-21 12:06:18 -08002120 if (cu->enable_debug & (1 << kDebugDumpBitcodeFile)) {
buzbeead8f15e2012-06-18 14:49:45 -07002121 // Write bitcode to file
2122 std::string errmsg;
buzbeefa57c472012-11-21 12:06:18 -08002123 std::string fname(PrettyMethod(cu->method_idx, *cu->dex_file));
buzbee52a77fc2012-11-20 19:50:46 -08002124 ReplaceSpecialChars(fname);
buzbee6459e7c2012-10-02 14:42:41 -07002125 // TODO: make configurable change naming mechanism to avoid fname length issues.
buzbee4f1181f2012-06-22 13:52:12 -07002126 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002127
buzbee6459e7c2012-10-02 14:42:41 -07002128 if (fname.size() > 240) {
2129 LOG(INFO) << "Warning: bitcode filename too long. Truncated.";
2130 fname.resize(240);
2131 }
2132
buzbeead8f15e2012-06-18 14:49:45 -07002133 llvm::OwningPtr<llvm::tool_output_file> out_file(
2134 new llvm::tool_output_file(fname.c_str(), errmsg,
2135 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002136
buzbeead8f15e2012-06-18 14:49:45 -07002137 if (!errmsg.empty()) {
2138 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2139 }
2140
buzbeefa57c472012-11-21 12:06:18 -08002141 llvm::WriteBitcodeToFile(cu->module, out_file->os());
buzbeead8f15e2012-06-18 14:49:45 -07002142 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002143 }
buzbee2cfc6392012-05-07 14:51:40 -07002144}
2145
buzbeefa57c472012-11-21 12:06:18 -08002146static RegLocation GetLoc(CompilationUnit* cu, llvm::Value* val) {
buzbee2cfc6392012-05-07 14:51:40 -07002147 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002148 DCHECK(val != NULL);
buzbeefa57c472012-11-21 12:06:18 -08002149 SafeMap<llvm::Value*, RegLocation>::iterator it = cu->loc_map.find(val);
2150 if (it == cu->loc_map.end()) {
2151 std::string val_name = val->getName().str();
2152 if (val_name.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002153 // FIXME: need to be more robust, handle FP and be in a position to
2154 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002155 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2156 memset(&res, 0, sizeof(res));
2157 res.location = kLocPhysReg;
buzbeefa57c472012-11-21 12:06:18 -08002158 res.low_reg = AllocTemp(cu);
buzbee4f1181f2012-06-22 13:52:12 -07002159 res.home = true;
buzbeefa57c472012-11-21 12:06:18 -08002160 res.s_reg_low = INVALID_SREG;
2161 res.orig_sreg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002162 llvm::Type* ty = val->getType();
buzbeefa57c472012-11-21 12:06:18 -08002163 res.wide = ((ty == cu->irb->getInt64Ty()) ||
2164 (ty == cu->irb->getDoubleTy()));
buzbee101305f2012-06-28 18:00:56 -07002165 if (res.wide) {
buzbeefa57c472012-11-21 12:06:18 -08002166 res.high_reg = AllocTemp(cu);
buzbee101305f2012-06-28 18:00:56 -07002167 }
buzbeefa57c472012-11-21 12:06:18 -08002168 cu->loc_map.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002169 } else {
buzbeefa57c472012-11-21 12:06:18 -08002170 DCHECK_EQ(val_name[0], 'v');
2171 int base_sreg = INVALID_SREG;
2172 sscanf(val_name.c_str(), "v%d_", &base_sreg);
2173 res = cu->reg_location[base_sreg];
2174 cu->loc_map.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002175 }
2176 } else {
2177 res = it->second;
2178 }
2179 return res;
2180}
2181
buzbeefa57c472012-11-21 12:06:18 -08002182static Instruction::Code GetDalvikOpcode(OpKind op, bool is_const, bool is_wide)
buzbee2cfc6392012-05-07 14:51:40 -07002183{
2184 Instruction::Code res = Instruction::NOP;
buzbeefa57c472012-11-21 12:06:18 -08002185 if (is_wide) {
buzbee2cfc6392012-05-07 14:51:40 -07002186 switch(op) {
2187 case kOpAdd: res = Instruction::ADD_LONG; break;
2188 case kOpSub: res = Instruction::SUB_LONG; break;
2189 case kOpMul: res = Instruction::MUL_LONG; break;
2190 case kOpDiv: res = Instruction::DIV_LONG; break;
2191 case kOpRem: res = Instruction::REM_LONG; break;
2192 case kOpAnd: res = Instruction::AND_LONG; break;
2193 case kOpOr: res = Instruction::OR_LONG; break;
2194 case kOpXor: res = Instruction::XOR_LONG; break;
2195 case kOpLsl: res = Instruction::SHL_LONG; break;
2196 case kOpLsr: res = Instruction::USHR_LONG; break;
2197 case kOpAsr: res = Instruction::SHR_LONG; break;
2198 default: LOG(FATAL) << "Unexpected OpKind " << op;
2199 }
buzbeefa57c472012-11-21 12:06:18 -08002200 } else if (is_const){
buzbee2cfc6392012-05-07 14:51:40 -07002201 switch(op) {
2202 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2203 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2204 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2205 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2206 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2207 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2208 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2209 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2210 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2211 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2212 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2213 default: LOG(FATAL) << "Unexpected OpKind " << op;
2214 }
2215 } else {
2216 switch(op) {
2217 case kOpAdd: res = Instruction::ADD_INT; break;
2218 case kOpSub: res = Instruction::SUB_INT; break;
2219 case kOpMul: res = Instruction::MUL_INT; break;
2220 case kOpDiv: res = Instruction::DIV_INT; break;
2221 case kOpRem: res = Instruction::REM_INT; break;
2222 case kOpAnd: res = Instruction::AND_INT; break;
2223 case kOpOr: res = Instruction::OR_INT; break;
2224 case kOpXor: res = Instruction::XOR_INT; break;
2225 case kOpLsl: res = Instruction::SHL_INT; break;
2226 case kOpLsr: res = Instruction::USHR_INT; break;
2227 case kOpAsr: res = Instruction::SHR_INT; break;
2228 default: LOG(FATAL) << "Unexpected OpKind " << op;
2229 }
2230 }
2231 return res;
2232}
2233
buzbeefa57c472012-11-21 12:06:18 -08002234static Instruction::Code GetDalvikFPOpcode(OpKind op, bool is_const, bool is_wide)
buzbee4f1181f2012-06-22 13:52:12 -07002235{
2236 Instruction::Code res = Instruction::NOP;
buzbeefa57c472012-11-21 12:06:18 -08002237 if (is_wide) {
buzbee4f1181f2012-06-22 13:52:12 -07002238 switch(op) {
2239 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2240 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2241 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2242 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2243 case kOpRem: res = Instruction::REM_DOUBLE; break;
2244 default: LOG(FATAL) << "Unexpected OpKind " << op;
2245 }
2246 } else {
2247 switch(op) {
2248 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2249 case kOpSub: res = Instruction::SUB_FLOAT; break;
2250 case kOpMul: res = Instruction::MUL_FLOAT; break;
2251 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2252 case kOpRem: res = Instruction::REM_FLOAT; break;
2253 default: LOG(FATAL) << "Unexpected OpKind " << op;
2254 }
2255 }
2256 return res;
2257}
2258
buzbeefa57c472012-11-21 12:06:18 -08002259static void CvtBinFPOp(CompilationUnit* cu, OpKind op, llvm::Instruction* inst)
buzbee4f1181f2012-06-22 13:52:12 -07002260{
buzbeefa57c472012-11-21 12:06:18 -08002261 RegLocation rl_dest = GetLoc(cu, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002262 /*
2263 * Normally, we won't ever generate an FP operation with an immediate
2264 * operand (not supported in Dex instruction set). However, the IR builder
buzbeefa57c472012-11-21 12:06:18 -08002265 * may insert them - in particular for create_neg_fp. Recognize this case
buzbee4f4dfc72012-07-02 14:54:44 -07002266 * and deal with it.
2267 */
2268 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2269 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2270 DCHECK(op2C == NULL);
2271 if ((op1C != NULL) && (op == kOpSub)) {
buzbeefa57c472012-11-21 12:06:18 -08002272 RegLocation rl_src = GetLoc(cu, inst->getOperand(1));
2273 if (rl_dest.wide) {
2274 GenArithOpDouble(cu, Instruction::NEG_DOUBLE, rl_dest, rl_src, rl_src);
buzbee4f4dfc72012-07-02 14:54:44 -07002275 } else {
buzbeefa57c472012-11-21 12:06:18 -08002276 GenArithOpFloat(cu, Instruction::NEG_FLOAT, rl_dest, rl_src, rl_src);
buzbee4f4dfc72012-07-02 14:54:44 -07002277 }
buzbee4f1181f2012-06-22 13:52:12 -07002278 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002279 DCHECK(op1C == NULL);
buzbeefa57c472012-11-21 12:06:18 -08002280 RegLocation rl_src1 = GetLoc(cu, inst->getOperand(0));
2281 RegLocation rl_src2 = GetLoc(cu, inst->getOperand(1));
2282 Instruction::Code dalvik_op = GetDalvikFPOpcode(op, false, rl_dest.wide);
2283 if (rl_dest.wide) {
2284 GenArithOpDouble(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
buzbee4f4dfc72012-07-02 14:54:44 -07002285 } else {
buzbeefa57c472012-11-21 12:06:18 -08002286 GenArithOpFloat(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
buzbee4f4dfc72012-07-02 14:54:44 -07002287 }
buzbee4f1181f2012-06-22 13:52:12 -07002288 }
2289}
2290
buzbeefa57c472012-11-21 12:06:18 -08002291static void CvtIntNarrowing(CompilationUnit* cu, llvm::Instruction* inst,
buzbee101305f2012-06-28 18:00:56 -07002292 Instruction::Code opcode)
2293{
buzbeefa57c472012-11-21 12:06:18 -08002294 RegLocation rl_dest = GetLoc(cu, inst);
2295 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
2296 GenIntNarrowing(cu, opcode, rl_dest, rl_src);
buzbee101305f2012-06-28 18:00:56 -07002297}
2298
buzbeefa57c472012-11-21 12:06:18 -08002299static void CvtIntToFP(CompilationUnit* cu, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002300{
buzbeefa57c472012-11-21 12:06:18 -08002301 RegLocation rl_dest = GetLoc(cu, inst);
2302 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002303 Instruction::Code opcode;
buzbeefa57c472012-11-21 12:06:18 -08002304 if (rl_dest.wide) {
2305 if (rl_src.wide) {
buzbee76592632012-06-29 15:18:35 -07002306 opcode = Instruction::LONG_TO_DOUBLE;
2307 } else {
2308 opcode = Instruction::INT_TO_DOUBLE;
2309 }
2310 } else {
buzbeefa57c472012-11-21 12:06:18 -08002311 if (rl_src.wide) {
buzbee76592632012-06-29 15:18:35 -07002312 opcode = Instruction::LONG_TO_FLOAT;
2313 } else {
2314 opcode = Instruction::INT_TO_FLOAT;
2315 }
2316 }
buzbeefa57c472012-11-21 12:06:18 -08002317 GenConversion(cu, opcode, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002318}
2319
buzbeefa57c472012-11-21 12:06:18 -08002320static void CvtFPToInt(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002321{
buzbeefa57c472012-11-21 12:06:18 -08002322 RegLocation rl_dest = GetLoc(cu, call_inst);
2323 RegLocation rl_src = GetLoc(cu, call_inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002324 Instruction::Code opcode;
buzbeefa57c472012-11-21 12:06:18 -08002325 if (rl_dest.wide) {
2326 if (rl_src.wide) {
buzbee76592632012-06-29 15:18:35 -07002327 opcode = Instruction::DOUBLE_TO_LONG;
2328 } else {
2329 opcode = Instruction::FLOAT_TO_LONG;
2330 }
2331 } else {
buzbeefa57c472012-11-21 12:06:18 -08002332 if (rl_src.wide) {
buzbee76592632012-06-29 15:18:35 -07002333 opcode = Instruction::DOUBLE_TO_INT;
2334 } else {
2335 opcode = Instruction::FLOAT_TO_INT;
2336 }
2337 }
buzbeefa57c472012-11-21 12:06:18 -08002338 GenConversion(cu, opcode, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002339}
2340
buzbeefa57c472012-11-21 12:06:18 -08002341static void CvtFloatToDouble(CompilationUnit* cu, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002342{
buzbeefa57c472012-11-21 12:06:18 -08002343 RegLocation rl_dest = GetLoc(cu, inst);
2344 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
2345 GenConversion(cu, Instruction::FLOAT_TO_DOUBLE, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002346}
2347
buzbeefa57c472012-11-21 12:06:18 -08002348static void CvtTrunc(CompilationUnit* cu, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002349{
buzbeefa57c472012-11-21 12:06:18 -08002350 RegLocation rl_dest = GetLoc(cu, inst);
2351 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
2352 rl_src = UpdateLocWide(cu, rl_src);
2353 rl_src = WideToNarrow(cu, rl_src);
2354 StoreValue(cu, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002355}
2356
buzbeefa57c472012-11-21 12:06:18 -08002357static void CvtDoubleToFloat(CompilationUnit* cu, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002358{
buzbeefa57c472012-11-21 12:06:18 -08002359 RegLocation rl_dest = GetLoc(cu, inst);
2360 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
2361 GenConversion(cu, Instruction::DOUBLE_TO_FLOAT, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002362}
2363
2364
buzbeefa57c472012-11-21 12:06:18 -08002365static void CvtIntExt(CompilationUnit* cu, llvm::Instruction* inst, bool is_signed)
buzbee101305f2012-06-28 18:00:56 -07002366{
2367 // TODO: evaluate src/tgt types and add general support for more than int to long
buzbeefa57c472012-11-21 12:06:18 -08002368 RegLocation rl_dest = GetLoc(cu, inst);
2369 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
2370 DCHECK(rl_dest.wide);
2371 DCHECK(!rl_src.wide);
2372 DCHECK(!rl_dest.fp);
2373 DCHECK(!rl_src.fp);
2374 RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
2375 if (rl_src.location == kLocPhysReg) {
2376 OpRegCopy(cu, rl_result.low_reg, rl_src.low_reg);
buzbee101305f2012-06-28 18:00:56 -07002377 } else {
buzbeefa57c472012-11-21 12:06:18 -08002378 LoadValueDirect(cu, rl_src, rl_result.low_reg);
buzbee101305f2012-06-28 18:00:56 -07002379 }
buzbeefa57c472012-11-21 12:06:18 -08002380 if (is_signed) {
2381 OpRegRegImm(cu, kOpAsr, rl_result.high_reg, rl_result.low_reg, 31);
buzbee101305f2012-06-28 18:00:56 -07002382 } else {
buzbeefa57c472012-11-21 12:06:18 -08002383 LoadConstant(cu, rl_result.high_reg, 0);
buzbee101305f2012-06-28 18:00:56 -07002384 }
buzbeefa57c472012-11-21 12:06:18 -08002385 StoreValueWide(cu, rl_dest, rl_result);
buzbee101305f2012-06-28 18:00:56 -07002386}
2387
buzbeefa57c472012-11-21 12:06:18 -08002388static void CvtBinOp(CompilationUnit* cu, OpKind op, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002389{
buzbeefa57c472012-11-21 12:06:18 -08002390 RegLocation rl_dest = GetLoc(cu, inst);
buzbee2cfc6392012-05-07 14:51:40 -07002391 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002392 // Special-case RSUB/NEG
buzbeefa57c472012-11-21 12:06:18 -08002393 llvm::ConstantInt* lhs_imm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2394 if ((op == kOpSub) && (lhs_imm != NULL)) {
2395 RegLocation rl_src1 = GetLoc(cu, inst->getOperand(1));
2396 if (rl_src1.wide) {
2397 DCHECK_EQ(lhs_imm->getSExtValue(), 0);
2398 GenArithOpLong(cu, Instruction::NEG_LONG, rl_dest, rl_src1, rl_src1);
buzbeef58c12c2012-07-03 15:06:29 -07002399 } else {
buzbeefa57c472012-11-21 12:06:18 -08002400 GenArithOpIntLit(cu, Instruction::RSUB_INT, rl_dest, rl_src1,
2401 lhs_imm->getSExtValue());
buzbeef58c12c2012-07-03 15:06:29 -07002402 }
buzbee4f1181f2012-06-22 13:52:12 -07002403 return;
2404 }
buzbeefa57c472012-11-21 12:06:18 -08002405 DCHECK(lhs_imm == NULL);
2406 RegLocation rl_src1 = GetLoc(cu, inst->getOperand(0));
buzbee2cfc6392012-05-07 14:51:40 -07002407 llvm::Value* rhs = inst->getOperand(1);
buzbeefa57c472012-11-21 12:06:18 -08002408 llvm::ConstantInt* const_rhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2409 if (!rl_dest.wide && (const_rhs != NULL)) {
2410 Instruction::Code dalvik_op = GetDalvikOpcode(op, true, false);
2411 GenArithOpIntLit(cu, dalvik_op, rl_dest, rl_src1, const_rhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002412 } else {
buzbeefa57c472012-11-21 12:06:18 -08002413 Instruction::Code dalvik_op = GetDalvikOpcode(op, false, rl_dest.wide);
2414 RegLocation rl_src2;
2415 if (const_rhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002416 // ir_builder converts NOT_LONG to xor src, -1. Restore
buzbeefa57c472012-11-21 12:06:18 -08002417 DCHECK_EQ(dalvik_op, Instruction::XOR_LONG);
2418 DCHECK_EQ(-1L, const_rhs->getSExtValue());
2419 dalvik_op = Instruction::NOT_LONG;
2420 rl_src2 = rl_src1;
buzbee9a2487f2012-07-26 14:01:13 -07002421 } else {
buzbeefa57c472012-11-21 12:06:18 -08002422 rl_src2 = GetLoc(cu, rhs);
buzbee9a2487f2012-07-26 14:01:13 -07002423 }
buzbeefa57c472012-11-21 12:06:18 -08002424 if (rl_dest.wide) {
2425 GenArithOpLong(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
buzbee2cfc6392012-05-07 14:51:40 -07002426 } else {
buzbeefa57c472012-11-21 12:06:18 -08002427 GenArithOpInt(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
buzbee2cfc6392012-05-07 14:51:40 -07002428 }
2429 }
2430}
2431
buzbeefa57c472012-11-21 12:06:18 -08002432static void CvtShiftOp(CompilationUnit* cu, Instruction::Code opcode, llvm::CallInst* call_inst)
buzbee101305f2012-06-28 18:00:56 -07002433{
buzbeefa57c472012-11-21 12:06:18 -08002434 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2435 RegLocation rl_dest = GetLoc(cu, call_inst);
2436 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(0));
2437 llvm::Value* rhs = call_inst->getArgOperand(1);
buzbee2a83e8f2012-07-13 16:42:30 -07002438 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
buzbeefa57c472012-11-21 12:06:18 -08002439 DCHECK(!rl_dest.wide);
2440 GenArithOpIntLit(cu, opcode, rl_dest, rl_src, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002441 } else {
buzbeefa57c472012-11-21 12:06:18 -08002442 RegLocation rl_shift = GetLoc(cu, rhs);
2443 if (call_inst->getType() == cu->irb->getInt64Ty()) {
2444 GenShiftOpLong(cu, opcode, rl_dest, rl_src, rl_shift);
buzbee2a83e8f2012-07-13 16:42:30 -07002445 } else {
buzbeefa57c472012-11-21 12:06:18 -08002446 GenArithOpInt(cu, opcode, rl_dest, rl_src, rl_shift);
buzbee2a83e8f2012-07-13 16:42:30 -07002447 }
buzbee101305f2012-06-28 18:00:56 -07002448 }
2449}
2450
buzbeefa57c472012-11-21 12:06:18 -08002451static void CvtBr(CompilationUnit* cu, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002452{
buzbeefa57c472012-11-21 12:06:18 -08002453 llvm::BranchInst* br_inst = llvm::dyn_cast<llvm::BranchInst>(inst);
2454 DCHECK(br_inst != NULL);
2455 DCHECK(br_inst->isUnconditional()); // May change - but this is all we use now
2456 llvm::BasicBlock* target_bb = br_inst->getSuccessor(0);
2457 OpUnconditionalBranch(cu, cu->block_to_label_map.Get(target_bb));
buzbee2cfc6392012-05-07 14:51:40 -07002458}
2459
buzbeefa57c472012-11-21 12:06:18 -08002460static void CvtPhi(CompilationUnit* cu, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002461{
2462 // Nop - these have already been processed
2463}
2464
buzbeefa57c472012-11-21 12:06:18 -08002465static void CvtRet(CompilationUnit* cu, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002466{
buzbeefa57c472012-11-21 12:06:18 -08002467 llvm::ReturnInst* ret_inst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2468 llvm::Value* ret_val = ret_inst->getReturnValue();
2469 if (ret_val != NULL) {
2470 RegLocation rl_src = GetLoc(cu, ret_val);
2471 if (rl_src.wide) {
2472 StoreValueWide(cu, GetReturnWide(cu, rl_src.fp), rl_src);
buzbee2cfc6392012-05-07 14:51:40 -07002473 } else {
buzbeefa57c472012-11-21 12:06:18 -08002474 StoreValue(cu, GetReturn(cu, rl_src.fp), rl_src);
buzbee2cfc6392012-05-07 14:51:40 -07002475 }
2476 }
buzbeefa57c472012-11-21 12:06:18 -08002477 GenExitSequence(cu);
buzbee2cfc6392012-05-07 14:51:40 -07002478}
2479
buzbeefa57c472012-11-21 12:06:18 -08002480static ConditionCode GetCond(llvm::ICmpInst::Predicate llvm_cond)
buzbee2cfc6392012-05-07 14:51:40 -07002481{
2482 ConditionCode res = kCondAl;
buzbeefa57c472012-11-21 12:06:18 -08002483 switch(llvm_cond) {
buzbee6969d502012-06-15 16:40:31 -07002484 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002485 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2486 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2487 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002488 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002489 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002490 default: LOG(FATAL) << "Unexpected llvm condition";
2491 }
2492 return res;
2493}
2494
buzbeefa57c472012-11-21 12:06:18 -08002495static void CvtICmp(CompilationUnit* cu, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002496{
buzbeefa57c472012-11-21 12:06:18 -08002497 // GenCmpLong(cu, rl_dest, rl_src1, rl_src2)
buzbee2cfc6392012-05-07 14:51:40 -07002498 UNIMPLEMENTED(FATAL);
2499}
2500
buzbeefa57c472012-11-21 12:06:18 -08002501static void CvtICmpBr(CompilationUnit* cu, llvm::Instruction* inst,
2502 llvm::BranchInst* br_inst)
buzbee2cfc6392012-05-07 14:51:40 -07002503{
2504 // Get targets
buzbeefa57c472012-11-21 12:06:18 -08002505 llvm::BasicBlock* taken_bb = br_inst->getSuccessor(0);
2506 LIR* taken = cu->block_to_label_map.Get(taken_bb);
2507 llvm::BasicBlock* fallthrough_bb = br_inst->getSuccessor(1);
2508 LIR* fall_through = cu->block_to_label_map.Get(fallthrough_bb);
buzbee2cfc6392012-05-07 14:51:40 -07002509 // Get comparison operands
buzbeefa57c472012-11-21 12:06:18 -08002510 llvm::ICmpInst* i_cmp_inst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2511 ConditionCode cond = GetCond(i_cmp_inst->getPredicate());
2512 llvm::Value* lhs = i_cmp_inst->getOperand(0);
buzbee2cfc6392012-05-07 14:51:40 -07002513 // Not expecting a constant as 1st operand
2514 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
buzbeefa57c472012-11-21 12:06:18 -08002515 RegLocation rl_src1 = GetLoc(cu, inst->getOperand(0));
2516 rl_src1 = LoadValue(cu, rl_src1, kCoreReg);
buzbee2cfc6392012-05-07 14:51:40 -07002517 llvm::Value* rhs = inst->getOperand(1);
buzbeefa57c472012-11-21 12:06:18 -08002518 if (cu->instruction_set == kMips) {
buzbeeb046e162012-10-30 15:48:42 -07002519 // Compare and branch in one shot
2520 UNIMPLEMENTED(FATAL);
2521 }
buzbee2cfc6392012-05-07 14:51:40 -07002522 //Compare, then branch
2523 // TODO: handle fused CMP_LONG/IF_xxZ case
2524 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
buzbeefa57c472012-11-21 12:06:18 -08002525 OpRegImm(cu, kOpCmp, rl_src1.low_reg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002526 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
buzbeefa57c472012-11-21 12:06:18 -08002527 OpRegImm(cu, kOpCmp, rl_src1.low_reg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002528 } else {
buzbeefa57c472012-11-21 12:06:18 -08002529 RegLocation rl_src2 = GetLoc(cu, rhs);
2530 rl_src2 = LoadValue(cu, rl_src2, kCoreReg);
2531 OpRegReg(cu, kOpCmp, rl_src1.low_reg, rl_src2.low_reg);
buzbee2cfc6392012-05-07 14:51:40 -07002532 }
buzbeefa57c472012-11-21 12:06:18 -08002533 OpCondBranch(cu, cond, taken);
buzbee2cfc6392012-05-07 14:51:40 -07002534 // Fallthrough
buzbeefa57c472012-11-21 12:06:18 -08002535 OpUnconditionalBranch(cu, fall_through);
buzbee2cfc6392012-05-07 14:51:40 -07002536}
2537
buzbeefa57c472012-11-21 12:06:18 -08002538static void CvtCopy(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee2cfc6392012-05-07 14:51:40 -07002539{
buzbeefa57c472012-11-21 12:06:18 -08002540 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2541 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(0));
2542 RegLocation rl_dest = GetLoc(cu, call_inst);
2543 DCHECK_EQ(rl_src.wide, rl_dest.wide);
2544 DCHECK_EQ(rl_src.fp, rl_dest.fp);
2545 if (rl_src.wide) {
2546 StoreValueWide(cu, rl_dest, rl_src);
buzbee2cfc6392012-05-07 14:51:40 -07002547 } else {
buzbeefa57c472012-11-21 12:06:18 -08002548 StoreValue(cu, rl_dest, rl_src);
buzbee2cfc6392012-05-07 14:51:40 -07002549 }
2550}
2551
2552// Note: Immediate arg is a ConstantInt regardless of result type
buzbeefa57c472012-11-21 12:06:18 -08002553static void CvtConst(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee2cfc6392012-05-07 14:51:40 -07002554{
buzbeefa57c472012-11-21 12:06:18 -08002555 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002556 llvm::ConstantInt* src =
buzbeefa57c472012-11-21 12:06:18 -08002557 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
buzbee2cfc6392012-05-07 14:51:40 -07002558 uint64_t immval = src->getZExtValue();
buzbeefa57c472012-11-21 12:06:18 -08002559 RegLocation rl_dest = GetLoc(cu, call_inst);
2560 RegLocation rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
2561 if (rl_dest.wide) {
2562 LoadConstantValueWide(cu, rl_result.low_reg, rl_result.high_reg,
buzbee2cfc6392012-05-07 14:51:40 -07002563 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
buzbeefa57c472012-11-21 12:06:18 -08002564 StoreValueWide(cu, rl_dest, rl_result);
buzbee2cfc6392012-05-07 14:51:40 -07002565 } else {
buzbeefa57c472012-11-21 12:06:18 -08002566 LoadConstantNoClobber(cu, rl_result.low_reg, immval & 0xffffffff);
2567 StoreValue(cu, rl_dest, rl_result);
buzbee2cfc6392012-05-07 14:51:40 -07002568 }
2569}
2570
buzbeefa57c472012-11-21 12:06:18 -08002571static void CvtConstObject(CompilationUnit* cu, llvm::CallInst* call_inst, bool is_string)
buzbee6969d502012-06-15 16:40:31 -07002572{
buzbeefa57c472012-11-21 12:06:18 -08002573 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2574 llvm::ConstantInt* idx_val =
2575 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2576 uint32_t index = idx_val->getZExtValue();
2577 RegLocation rl_dest = GetLoc(cu, call_inst);
2578 if (is_string) {
2579 GenConstString(cu, index, rl_dest);
buzbee101305f2012-06-28 18:00:56 -07002580 } else {
buzbeefa57c472012-11-21 12:06:18 -08002581 GenConstClass(cu, index, rl_dest);
buzbee101305f2012-06-28 18:00:56 -07002582 }
2583}
2584
buzbeefa57c472012-11-21 12:06:18 -08002585static void CvtFillArrayData(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee101305f2012-06-28 18:00:56 -07002586{
buzbeefa57c472012-11-21 12:06:18 -08002587 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2588 llvm::ConstantInt* offset_val =
2589 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2590 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
2591 GenFillArrayData(cu, offset_val->getSExtValue(), rl_src);
buzbee6969d502012-06-15 16:40:31 -07002592}
2593
buzbeefa57c472012-11-21 12:06:18 -08002594static void CvtNewInstance(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee4f1181f2012-06-22 13:52:12 -07002595{
buzbeefa57c472012-11-21 12:06:18 -08002596 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2597 llvm::ConstantInt* type_idx_val =
2598 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2599 uint32_t type_idx = type_idx_val->getZExtValue();
2600 RegLocation rl_dest = GetLoc(cu, call_inst);
2601 GenNewInstance(cu, type_idx, rl_dest);
buzbee4f1181f2012-06-22 13:52:12 -07002602}
2603
buzbeefa57c472012-11-21 12:06:18 -08002604static void CvtNewArray(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee8fa0fda2012-06-27 15:44:52 -07002605{
buzbeefa57c472012-11-21 12:06:18 -08002606 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2607 llvm::ConstantInt* type_idx_val =
2608 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2609 uint32_t type_idx = type_idx_val->getZExtValue();
2610 llvm::Value* len = call_inst->getArgOperand(1);
2611 RegLocation rl_len = GetLoc(cu, len);
2612 RegLocation rl_dest = GetLoc(cu, call_inst);
2613 GenNewArray(cu, type_idx, rl_dest, rl_len);
buzbee8fa0fda2012-06-27 15:44:52 -07002614}
2615
buzbeefa57c472012-11-21 12:06:18 -08002616static void CvtInstanceOf(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee8fa0fda2012-06-27 15:44:52 -07002617{
buzbeefa57c472012-11-21 12:06:18 -08002618 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2619 llvm::ConstantInt* type_idx_val =
2620 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2621 uint32_t type_idx = type_idx_val->getZExtValue();
2622 llvm::Value* src = call_inst->getArgOperand(1);
2623 RegLocation rl_src = GetLoc(cu, src);
2624 RegLocation rl_dest = GetLoc(cu, call_inst);
2625 GenInstanceof(cu, type_idx, rl_dest, rl_src);
buzbee8fa0fda2012-06-27 15:44:52 -07002626}
2627
buzbeefa57c472012-11-21 12:06:18 -08002628static void CvtThrow(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee32412962012-06-26 16:27:56 -07002629{
buzbeefa57c472012-11-21 12:06:18 -08002630 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2631 llvm::Value* src = call_inst->getArgOperand(0);
2632 RegLocation rl_src = GetLoc(cu, src);
2633 GenThrow(cu, rl_src);
buzbee32412962012-06-26 16:27:56 -07002634}
2635
buzbeefa57c472012-11-21 12:06:18 -08002636static void CvtMonitorEnterExit(CompilationUnit* cu, bool is_enter,
2637 llvm::CallInst* call_inst)
buzbee8fa0fda2012-06-27 15:44:52 -07002638{
buzbeefa57c472012-11-21 12:06:18 -08002639 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2640 llvm::ConstantInt* opt_flags =
2641 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2642 llvm::Value* src = call_inst->getArgOperand(1);
2643 RegLocation rl_src = GetLoc(cu, src);
2644 if (is_enter) {
2645 GenMonitorEnter(cu, opt_flags->getZExtValue(), rl_src);
buzbee8fa0fda2012-06-27 15:44:52 -07002646 } else {
buzbeefa57c472012-11-21 12:06:18 -08002647 GenMonitorExit(cu, opt_flags->getZExtValue(), rl_src);
buzbee8fa0fda2012-06-27 15:44:52 -07002648 }
2649}
2650
buzbeefa57c472012-11-21 12:06:18 -08002651static void CvtArrayLength(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee8fa0fda2012-06-27 15:44:52 -07002652{
buzbeefa57c472012-11-21 12:06:18 -08002653 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2654 llvm::ConstantInt* opt_flags =
2655 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2656 llvm::Value* src = call_inst->getArgOperand(1);
2657 RegLocation rl_src = GetLoc(cu, src);
2658 rl_src = LoadValue(cu, rl_src, kCoreReg);
2659 GenNullCheck(cu, rl_src.s_reg_low, rl_src.low_reg, opt_flags->getZExtValue());
2660 RegLocation rl_dest = GetLoc(cu, call_inst);
2661 RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
2662 int len_offset = Array::LengthOffset().Int32Value();
2663 LoadWordDisp(cu, rl_src.low_reg, len_offset, rl_result.low_reg);
2664 StoreValue(cu, rl_dest, rl_result);
buzbee8fa0fda2012-06-27 15:44:52 -07002665}
2666
buzbeefa57c472012-11-21 12:06:18 -08002667static void CvtMoveException(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee32412962012-06-26 16:27:56 -07002668{
buzbeefa57c472012-11-21 12:06:18 -08002669 RegLocation rl_dest = GetLoc(cu, call_inst);
2670 GenMoveException(cu, rl_dest);
buzbee32412962012-06-26 16:27:56 -07002671}
2672
buzbeefa57c472012-11-21 12:06:18 -08002673static void CvtSget(CompilationUnit* cu, llvm::CallInst* call_inst, bool is_wide, bool is_object)
buzbee4f1181f2012-06-22 13:52:12 -07002674{
buzbeefa57c472012-11-21 12:06:18 -08002675 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2676 llvm::ConstantInt* type_idx_val =
2677 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2678 uint32_t type_idx = type_idx_val->getZExtValue();
2679 RegLocation rl_dest = GetLoc(cu, call_inst);
2680 GenSget(cu, type_idx, rl_dest, is_wide, is_object);
buzbee4f1181f2012-06-22 13:52:12 -07002681}
2682
buzbeefa57c472012-11-21 12:06:18 -08002683static void CvtSput(CompilationUnit* cu, llvm::CallInst* call_inst, bool is_wide, bool is_object)
buzbee8fa0fda2012-06-27 15:44:52 -07002684{
buzbeefa57c472012-11-21 12:06:18 -08002685 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2686 llvm::ConstantInt* type_idx_val =
2687 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2688 uint32_t type_idx = type_idx_val->getZExtValue();
2689 llvm::Value* src = call_inst->getArgOperand(1);
2690 RegLocation rl_src = GetLoc(cu, src);
2691 GenSput(cu, type_idx, rl_src, is_wide, is_object);
buzbee8fa0fda2012-06-27 15:44:52 -07002692}
2693
buzbeefa57c472012-11-21 12:06:18 -08002694static void CvtAget(CompilationUnit* cu, llvm::CallInst* call_inst, OpSize size, int scale)
buzbee8fa0fda2012-06-27 15:44:52 -07002695{
buzbeefa57c472012-11-21 12:06:18 -08002696 DCHECK_EQ(call_inst->getNumArgOperands(), 3U);
2697 llvm::ConstantInt* opt_flags =
2698 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2699 RegLocation rl_array = GetLoc(cu, call_inst->getArgOperand(1));
2700 RegLocation rl_index = GetLoc(cu, call_inst->getArgOperand(2));
2701 RegLocation rl_dest = GetLoc(cu, call_inst);
2702 GenArrayGet(cu, opt_flags->getZExtValue(), size, rl_array, rl_index,
2703 rl_dest, scale);
buzbee8fa0fda2012-06-27 15:44:52 -07002704}
2705
buzbeefa57c472012-11-21 12:06:18 -08002706static void CvtAput(CompilationUnit* cu, llvm::CallInst* call_inst, OpSize size,
2707 int scale, bool is_object)
buzbee8fa0fda2012-06-27 15:44:52 -07002708{
buzbeefa57c472012-11-21 12:06:18 -08002709 DCHECK_EQ(call_inst->getNumArgOperands(), 4U);
2710 llvm::ConstantInt* opt_flags =
2711 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2712 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
2713 RegLocation rl_array = GetLoc(cu, call_inst->getArgOperand(2));
2714 RegLocation rl_index = GetLoc(cu, call_inst->getArgOperand(3));
2715 if (is_object) {
2716 GenArrayObjPut(cu, opt_flags->getZExtValue(), rl_array, rl_index,
2717 rl_src, scale);
buzbeef1f86362012-07-10 15:18:31 -07002718 } else {
buzbeefa57c472012-11-21 12:06:18 -08002719 GenArrayPut(cu, opt_flags->getZExtValue(), size, rl_array, rl_index,
2720 rl_src, scale);
buzbeef1f86362012-07-10 15:18:31 -07002721 }
2722}
2723
buzbeefa57c472012-11-21 12:06:18 -08002724static void CvtAputObj(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbeef1f86362012-07-10 15:18:31 -07002725{
buzbeefa57c472012-11-21 12:06:18 -08002726 CvtAput(cu, call_inst, kWord, 2, true /* is_object */);
buzbeef1f86362012-07-10 15:18:31 -07002727}
2728
buzbeefa57c472012-11-21 12:06:18 -08002729static void CvtAputPrimitive(CompilationUnit* cu, llvm::CallInst* call_inst,
buzbeef1f86362012-07-10 15:18:31 -07002730 OpSize size, int scale)
2731{
buzbeefa57c472012-11-21 12:06:18 -08002732 CvtAput(cu, call_inst, size, scale, false /* is_object */);
buzbee8fa0fda2012-06-27 15:44:52 -07002733}
2734
buzbeefa57c472012-11-21 12:06:18 -08002735static void CvtIget(CompilationUnit* cu, llvm::CallInst* call_inst, OpSize size,
2736 bool is_wide, bool is_obj)
buzbee101305f2012-06-28 18:00:56 -07002737{
buzbeefa57c472012-11-21 12:06:18 -08002738 DCHECK_EQ(call_inst->getNumArgOperands(), 3U);
2739 llvm::ConstantInt* opt_flags =
2740 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2741 RegLocation rl_obj = GetLoc(cu, call_inst->getArgOperand(1));
2742 llvm::ConstantInt* field_idx =
2743 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(2));
2744 RegLocation rl_dest = GetLoc(cu, call_inst);
2745 GenIGet(cu, field_idx->getZExtValue(), opt_flags->getZExtValue(),
2746 size, rl_dest, rl_obj, is_wide, is_obj);
buzbee101305f2012-06-28 18:00:56 -07002747}
2748
buzbeefa57c472012-11-21 12:06:18 -08002749static void CvtIput(CompilationUnit* cu, llvm::CallInst* call_inst, OpSize size,
2750 bool is_wide, bool is_obj)
buzbee101305f2012-06-28 18:00:56 -07002751{
buzbeefa57c472012-11-21 12:06:18 -08002752 DCHECK_EQ(call_inst->getNumArgOperands(), 4U);
2753 llvm::ConstantInt* opt_flags =
2754 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2755 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
2756 RegLocation rl_obj = GetLoc(cu, call_inst->getArgOperand(2));
2757 llvm::ConstantInt* field_idx =
2758 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(3));
2759 GenIPut(cu, field_idx->getZExtValue(), opt_flags->getZExtValue(),
2760 size, rl_src, rl_obj, is_wide, is_obj);
buzbee101305f2012-06-28 18:00:56 -07002761}
2762
buzbeefa57c472012-11-21 12:06:18 -08002763static void CvtCheckCast(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee101305f2012-06-28 18:00:56 -07002764{
buzbeefa57c472012-11-21 12:06:18 -08002765 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2766 llvm::ConstantInt* type_idx =
2767 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2768 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
2769 GenCheckCast(cu, type_idx->getZExtValue(), rl_src);
buzbee101305f2012-06-28 18:00:56 -07002770}
2771
buzbeefa57c472012-11-21 12:06:18 -08002772static void CvtFPCompare(CompilationUnit* cu, llvm::CallInst* call_inst,
buzbeeaad94382012-11-21 07:40:50 -08002773 Instruction::Code opcode)
buzbee76592632012-06-29 15:18:35 -07002774{
buzbeefa57c472012-11-21 12:06:18 -08002775 RegLocation rl_src1 = GetLoc(cu, call_inst->getArgOperand(0));
2776 RegLocation rl_src2 = GetLoc(cu, call_inst->getArgOperand(1));
2777 RegLocation rl_dest = GetLoc(cu, call_inst);
2778 GenCmpFP(cu, opcode, rl_dest, rl_src1, rl_src2);
buzbee76592632012-06-29 15:18:35 -07002779}
2780
buzbeefa57c472012-11-21 12:06:18 -08002781static void CvtLongCompare(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002782{
buzbeefa57c472012-11-21 12:06:18 -08002783 RegLocation rl_src1 = GetLoc(cu, call_inst->getArgOperand(0));
2784 RegLocation rl_src2 = GetLoc(cu, call_inst->getArgOperand(1));
2785 RegLocation rl_dest = GetLoc(cu, call_inst);
2786 GenCmpLong(cu, rl_dest, rl_src1, rl_src2);
buzbee76592632012-06-29 15:18:35 -07002787}
2788
buzbeefa57c472012-11-21 12:06:18 -08002789static void CvtSwitch(CompilationUnit* cu, llvm::Instruction* inst)
buzbeef58c12c2012-07-03 15:06:29 -07002790{
buzbeefa57c472012-11-21 12:06:18 -08002791 llvm::SwitchInst* sw_inst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2792 DCHECK(sw_inst != NULL);
2793 llvm::Value* test_val = sw_inst->getCondition();
2794 llvm::MDNode* table_offset_node = sw_inst->getMetadata("SwitchTable");
2795 DCHECK(table_offset_node != NULL);
2796 llvm::ConstantInt* table_offset_value =
2797 static_cast<llvm::ConstantInt*>(table_offset_node->getOperand(0));
2798 int32_t table_offset = table_offset_value->getSExtValue();
2799 RegLocation rl_src = GetLoc(cu, test_val);
2800 const uint16_t* table = cu->insns + cu->current_dalvik_offset + table_offset;
2801 uint16_t table_magic = *table;
2802 if (table_magic == 0x100) {
2803 GenPackedSwitch(cu, table_offset, rl_src);
buzbeea1da8a52012-07-09 14:00:21 -07002804 } else {
buzbeefa57c472012-11-21 12:06:18 -08002805 DCHECK_EQ(table_magic, 0x200);
2806 GenSparseSwitch(cu, table_offset, rl_src);
buzbeea1da8a52012-07-09 14:00:21 -07002807 }
buzbeef58c12c2012-07-03 15:06:29 -07002808}
2809
buzbeefa57c472012-11-21 12:06:18 -08002810static void CvtInvoke(CompilationUnit* cu, llvm::CallInst* call_inst, bool is_void,
2811 bool is_filled_new_array)
buzbee6969d502012-06-15 16:40:31 -07002812{
buzbeefa57c472012-11-21 12:06:18 -08002813 CallInfo* info = static_cast<CallInfo*>(NewMem(cu, sizeof(CallInfo), true, kAllocMisc));
2814 if (is_void) {
buzbee6969d502012-06-15 16:40:31 -07002815 info->result.location = kLocInvalid;
2816 } else {
buzbeefa57c472012-11-21 12:06:18 -08002817 info->result = GetLoc(cu, call_inst);
buzbee6969d502012-06-15 16:40:31 -07002818 }
buzbeefa57c472012-11-21 12:06:18 -08002819 llvm::ConstantInt* invoke_type_val =
2820 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2821 llvm::ConstantInt* method_index_val =
2822 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(1));
2823 llvm::ConstantInt* opt_flags_val =
2824 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(2));
2825 info->type = static_cast<InvokeType>(invoke_type_val->getZExtValue());
2826 info->index = method_index_val->getZExtValue();
2827 info->opt_flags = opt_flags_val->getZExtValue();
2828 info->offset = cu->current_dalvik_offset;
buzbee6969d502012-06-15 16:40:31 -07002829
buzbee6969d502012-06-15 16:40:31 -07002830 // Count the argument words, and then build argument array.
buzbeefa57c472012-11-21 12:06:18 -08002831 info->num_arg_words = 0;
2832 for (unsigned int i = 3; i < call_inst->getNumArgOperands(); i++) {
2833 RegLocation t_loc = GetLoc(cu, call_inst->getArgOperand(i));
2834 info->num_arg_words += t_loc.wide ? 2 : 1;
buzbee6969d502012-06-15 16:40:31 -07002835 }
buzbeefa57c472012-11-21 12:06:18 -08002836 info->args = (info->num_arg_words == 0) ? NULL : static_cast<RegLocation*>
2837 (NewMem(cu, sizeof(RegLocation) * info->num_arg_words, false, kAllocMisc));
buzbee6969d502012-06-15 16:40:31 -07002838 // Now, fill in the location records, synthesizing high loc of wide vals
buzbeefa57c472012-11-21 12:06:18 -08002839 for (int i = 3, next = 0; next < info->num_arg_words;) {
2840 info->args[next] = GetLoc(cu, call_inst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002841 if (info->args[next].wide) {
2842 next++;
2843 // TODO: Might make sense to mark this as an invalid loc
buzbeefa57c472012-11-21 12:06:18 -08002844 info->args[next].orig_sreg = info->args[next-1].orig_sreg+1;
2845 info->args[next].s_reg_low = info->args[next-1].s_reg_low+1;
buzbee6969d502012-06-15 16:40:31 -07002846 }
2847 next++;
2848 }
buzbeefa57c472012-11-21 12:06:18 -08002849 // TODO - rework such that we no longer need is_range
2850 info->is_range = (info->num_arg_words > 5);
buzbee4f4dfc72012-07-02 14:54:44 -07002851
buzbeefa57c472012-11-21 12:06:18 -08002852 if (is_filled_new_array) {
2853 GenFilledNewArray(cu, info);
buzbee101305f2012-06-28 18:00:56 -07002854 } else {
buzbeefa57c472012-11-21 12:06:18 -08002855 GenInvoke(cu, info);
buzbee101305f2012-06-28 18:00:56 -07002856 }
buzbee6969d502012-06-15 16:40:31 -07002857}
2858
buzbeead8f15e2012-06-18 14:49:45 -07002859/* Look up the RegLocation associated with a Value. Must already be defined */
buzbeefa57c472012-11-21 12:06:18 -08002860static RegLocation ValToLoc(CompilationUnit* cu, llvm::Value* val)
buzbeead8f15e2012-06-18 14:49:45 -07002861{
buzbeefa57c472012-11-21 12:06:18 -08002862 SafeMap<llvm::Value*, RegLocation>::iterator it = cu->loc_map.find(val);
2863 DCHECK(it != cu->loc_map.end()) << "Missing definition";
buzbeead8f15e2012-06-18 14:49:45 -07002864 return it->second;
2865}
2866
buzbeefa57c472012-11-21 12:06:18 -08002867static bool BitcodeBlockCodeGen(CompilationUnit* cu, llvm::BasicBlock* bb)
buzbee2cfc6392012-05-07 14:51:40 -07002868{
buzbeefa57c472012-11-21 12:06:18 -08002869 while (cu->llvm_blocks.find(bb) == cu->llvm_blocks.end()) {
2870 llvm::BasicBlock* next_bb = NULL;
2871 cu->llvm_blocks.insert(bb);
2872 bool is_entry = (bb == &cu->func->getEntryBlock());
buzbee0967a252012-09-14 10:43:54 -07002873 // Define the starting label
buzbeefa57c472012-11-21 12:06:18 -08002874 LIR* block_label = cu->block_to_label_map.Get(bb);
buzbee0967a252012-09-14 10:43:54 -07002875 // Extract the type and starting offset from the block's name
buzbeefa57c472012-11-21 12:06:18 -08002876 char block_type = kInvalidBlock;
2877 if (is_entry) {
2878 block_type = kNormalBlock;
2879 block_label->operands[0] = 0;
buzbee951c0a12012-10-03 16:31:39 -07002880 } else if (!bb->hasName()) {
buzbeefa57c472012-11-21 12:06:18 -08002881 block_type = kNormalBlock;
2882 block_label->operands[0] = DexFile::kDexNoIndex;
buzbee0967a252012-09-14 10:43:54 -07002883 } else {
buzbeefa57c472012-11-21 12:06:18 -08002884 std::string block_name = bb->getName().str();
buzbee951c0a12012-10-03 16:31:39 -07002885 int dummy;
buzbeefa57c472012-11-21 12:06:18 -08002886 sscanf(block_name.c_str(), kLabelFormat, &block_type, &block_label->operands[0], &dummy);
2887 cu->current_dalvik_offset = block_label->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002888 }
buzbeefa57c472012-11-21 12:06:18 -08002889 DCHECK((block_type == kNormalBlock) || (block_type == kCatchBlock));
2890 cu->current_dalvik_offset = block_label->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002891 // Set the label kind
buzbeefa57c472012-11-21 12:06:18 -08002892 block_label->opcode = kPseudoNormalBlockLabel;
buzbee0967a252012-09-14 10:43:54 -07002893 // Insert the label
buzbeefa57c472012-11-21 12:06:18 -08002894 AppendLIR(cu, block_label);
buzbee2cfc6392012-05-07 14:51:40 -07002895
buzbeefa57c472012-11-21 12:06:18 -08002896 LIR* head_lir = NULL;
buzbee8320f382012-09-11 16:29:42 -07002897
buzbeefa57c472012-11-21 12:06:18 -08002898 if (block_type == kCatchBlock) {
2899 head_lir = NewLIR0(cu, kPseudoExportedPC);
buzbee0967a252012-09-14 10:43:54 -07002900 }
buzbee8320f382012-09-11 16:29:42 -07002901
buzbee0967a252012-09-14 10:43:54 -07002902 // Free temp registers and reset redundant store tracking */
buzbeefa57c472012-11-21 12:06:18 -08002903 ResetRegPool(cu);
2904 ResetDefTracking(cu);
buzbee2cfc6392012-05-07 14:51:40 -07002905
buzbee0967a252012-09-14 10:43:54 -07002906 //TODO: restore oat incoming liveness optimization
buzbeefa57c472012-11-21 12:06:18 -08002907 ClobberAllRegs(cu);
buzbee2cfc6392012-05-07 14:51:40 -07002908
buzbeefa57c472012-11-21 12:06:18 -08002909 if (is_entry) {
buzbee52a77fc2012-11-20 19:50:46 -08002910 RegLocation* ArgLocs = static_cast<RegLocation*>
buzbeefa57c472012-11-21 12:06:18 -08002911 (NewMem(cu, sizeof(RegLocation) * cu->num_ins, true, kAllocMisc));
2912 llvm::Function::arg_iterator it(cu->func->arg_begin());
2913 llvm::Function::arg_iterator it_end(cu->func->arg_end());
buzbee0967a252012-09-14 10:43:54 -07002914 // Skip past Method*
2915 it++;
2916 for (unsigned i = 0; it != it_end; ++it) {
2917 llvm::Value* val = it;
buzbeefa57c472012-11-21 12:06:18 -08002918 ArgLocs[i++] = ValToLoc(cu, val);
buzbee0967a252012-09-14 10:43:54 -07002919 llvm::Type* ty = val->getType();
buzbeefa57c472012-11-21 12:06:18 -08002920 if ((ty == cu->irb->getInt64Ty()) || (ty == cu->irb->getDoubleTy())) {
buzbee52a77fc2012-11-20 19:50:46 -08002921 ArgLocs[i] = ArgLocs[i-1];
buzbeefa57c472012-11-21 12:06:18 -08002922 ArgLocs[i].low_reg = ArgLocs[i].high_reg;
2923 ArgLocs[i].orig_sreg++;
2924 ArgLocs[i].s_reg_low = INVALID_SREG;
2925 ArgLocs[i].high_word = true;
buzbee0967a252012-09-14 10:43:54 -07002926 i++;
2927 }
2928 }
buzbeefa57c472012-11-21 12:06:18 -08002929 GenEntrySequence(cu, ArgLocs, cu->method_loc);
buzbee0967a252012-09-14 10:43:54 -07002930 }
2931
2932 // Visit all of the instructions in the block
2933 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2934 llvm::Instruction* inst = it;
buzbeefa57c472012-11-21 12:06:18 -08002935 llvm::BasicBlock::iterator next_it = ++it;
buzbee0967a252012-09-14 10:43:54 -07002936 // Extract the Dalvik offset from the instruction
2937 uint32_t opcode = inst->getOpcode();
buzbeefa57c472012-11-21 12:06:18 -08002938 llvm::MDNode* dex_offset_node = inst->getMetadata("DexOff");
2939 if (dex_offset_node != NULL) {
2940 llvm::ConstantInt* dex_offset_value =
2941 static_cast<llvm::ConstantInt*>(dex_offset_node->getOperand(0));
2942 cu->current_dalvik_offset = dex_offset_value->getZExtValue();
buzbee0967a252012-09-14 10:43:54 -07002943 }
2944
buzbeefa57c472012-11-21 12:06:18 -08002945 ResetRegPool(cu);
2946 if (cu->disable_opt & (1 << kTrackLiveTemps)) {
2947 ClobberAllRegs(cu);
buzbee0967a252012-09-14 10:43:54 -07002948 }
2949
buzbeefa57c472012-11-21 12:06:18 -08002950 if (cu->disable_opt & (1 << kSuppressLoads)) {
2951 ResetDefTracking(cu);
buzbee0967a252012-09-14 10:43:54 -07002952 }
2953
2954 #ifndef NDEBUG
2955 /* Reset temp tracking sanity check */
buzbeefa57c472012-11-21 12:06:18 -08002956 cu->live_sreg = INVALID_SREG;
buzbee0967a252012-09-14 10:43:54 -07002957 #endif
2958
2959 // TODO: use llvm opcode name here instead of "boundary" if verbose
buzbeefa57c472012-11-21 12:06:18 -08002960 LIR* boundary_lir = MarkBoundary(cu, cu->current_dalvik_offset, "boundary");
buzbee0967a252012-09-14 10:43:54 -07002961
2962 /* Remember the first LIR for thisl block*/
buzbeefa57c472012-11-21 12:06:18 -08002963 if (head_lir == NULL) {
2964 head_lir = boundary_lir;
2965 head_lir->def_mask = ENCODE_ALL;
buzbee0967a252012-09-14 10:43:54 -07002966 }
2967
2968 switch(opcode) {
2969
2970 case llvm::Instruction::ICmp: {
buzbeefa57c472012-11-21 12:06:18 -08002971 llvm::Instruction* next_inst = next_it;
2972 llvm::BranchInst* br_inst = llvm::dyn_cast<llvm::BranchInst>(next_inst);
2973 if (br_inst != NULL /* and... */) {
2974 CvtICmpBr(cu, inst, br_inst);
buzbee0967a252012-09-14 10:43:54 -07002975 ++it;
2976 } else {
buzbeefa57c472012-11-21 12:06:18 -08002977 CvtICmp(cu, inst);
buzbee0967a252012-09-14 10:43:54 -07002978 }
2979 }
2980 break;
2981
2982 case llvm::Instruction::Call: {
buzbeefa57c472012-11-21 12:06:18 -08002983 llvm::CallInst* call_inst = llvm::dyn_cast<llvm::CallInst>(inst);
2984 llvm::Function* callee = call_inst->getCalledFunction();
buzbee0967a252012-09-14 10:43:54 -07002985 greenland::IntrinsicHelper::IntrinsicId id =
buzbeefa57c472012-11-21 12:06:18 -08002986 cu->intrinsic_helper->GetIntrinsicId(callee);
buzbee0967a252012-09-14 10:43:54 -07002987 switch (id) {
2988 case greenland::IntrinsicHelper::AllocaShadowFrame:
2989 case greenland::IntrinsicHelper::SetShadowFrameEntry:
2990 case greenland::IntrinsicHelper::PopShadowFrame:
TDYa1278e950c12012-11-02 09:58:19 -07002991 case greenland::IntrinsicHelper::SetVReg:
buzbee0967a252012-09-14 10:43:54 -07002992 // Ignore shadow frame stuff for quick compiler
2993 break;
2994 case greenland::IntrinsicHelper::CopyInt:
2995 case greenland::IntrinsicHelper::CopyObj:
2996 case greenland::IntrinsicHelper::CopyFloat:
2997 case greenland::IntrinsicHelper::CopyLong:
2998 case greenland::IntrinsicHelper::CopyDouble:
buzbeefa57c472012-11-21 12:06:18 -08002999 CvtCopy(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003000 break;
3001 case greenland::IntrinsicHelper::ConstInt:
3002 case greenland::IntrinsicHelper::ConstObj:
3003 case greenland::IntrinsicHelper::ConstLong:
3004 case greenland::IntrinsicHelper::ConstFloat:
3005 case greenland::IntrinsicHelper::ConstDouble:
buzbeefa57c472012-11-21 12:06:18 -08003006 CvtConst(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003007 break;
3008 case greenland::IntrinsicHelper::DivInt:
3009 case greenland::IntrinsicHelper::DivLong:
buzbeefa57c472012-11-21 12:06:18 -08003010 CvtBinOp(cu, kOpDiv, inst);
buzbee0967a252012-09-14 10:43:54 -07003011 break;
3012 case greenland::IntrinsicHelper::RemInt:
3013 case greenland::IntrinsicHelper::RemLong:
buzbeefa57c472012-11-21 12:06:18 -08003014 CvtBinOp(cu, kOpRem, inst);
buzbee0967a252012-09-14 10:43:54 -07003015 break;
3016 case greenland::IntrinsicHelper::MethodInfo:
3017 // Already dealt with - just ignore it here.
3018 break;
3019 case greenland::IntrinsicHelper::CheckSuspend:
buzbeefa57c472012-11-21 12:06:18 -08003020 GenSuspendTest(cu, 0 /* opt_flags already applied */);
buzbee0967a252012-09-14 10:43:54 -07003021 break;
3022 case greenland::IntrinsicHelper::HLInvokeObj:
3023 case greenland::IntrinsicHelper::HLInvokeFloat:
3024 case greenland::IntrinsicHelper::HLInvokeDouble:
3025 case greenland::IntrinsicHelper::HLInvokeLong:
3026 case greenland::IntrinsicHelper::HLInvokeInt:
buzbeefa57c472012-11-21 12:06:18 -08003027 CvtInvoke(cu, call_inst, false /* is_void */, false /* new_array */);
buzbee0967a252012-09-14 10:43:54 -07003028 break;
3029 case greenland::IntrinsicHelper::HLInvokeVoid:
buzbeefa57c472012-11-21 12:06:18 -08003030 CvtInvoke(cu, call_inst, true /* is_void */, false /* new_array */);
buzbee0967a252012-09-14 10:43:54 -07003031 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003032 case greenland::IntrinsicHelper::HLFilledNewArray:
buzbeefa57c472012-11-21 12:06:18 -08003033 CvtInvoke(cu, call_inst, false /* is_void */, true /* new_array */);
buzbee0967a252012-09-14 10:43:54 -07003034 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003035 case greenland::IntrinsicHelper::HLFillArrayData:
buzbeefa57c472012-11-21 12:06:18 -08003036 CvtFillArrayData(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003037 break;
3038 case greenland::IntrinsicHelper::ConstString:
buzbeefa57c472012-11-21 12:06:18 -08003039 CvtConstObject(cu, call_inst, true /* is_string */);
buzbee0967a252012-09-14 10:43:54 -07003040 break;
3041 case greenland::IntrinsicHelper::ConstClass:
buzbeefa57c472012-11-21 12:06:18 -08003042 CvtConstObject(cu, call_inst, false /* is_string */);
buzbee0967a252012-09-14 10:43:54 -07003043 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003044 case greenland::IntrinsicHelper::HLCheckCast:
buzbeefa57c472012-11-21 12:06:18 -08003045 CvtCheckCast(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003046 break;
3047 case greenland::IntrinsicHelper::NewInstance:
buzbeefa57c472012-11-21 12:06:18 -08003048 CvtNewInstance(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003049 break;
3050 case greenland::IntrinsicHelper::HLSgetObject:
buzbeefa57c472012-11-21 12:06:18 -08003051 CvtSget(cu, call_inst, false /* wide */, true /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003052 break;
3053 case greenland::IntrinsicHelper::HLSget:
3054 case greenland::IntrinsicHelper::HLSgetFloat:
3055 case greenland::IntrinsicHelper::HLSgetBoolean:
3056 case greenland::IntrinsicHelper::HLSgetByte:
3057 case greenland::IntrinsicHelper::HLSgetChar:
3058 case greenland::IntrinsicHelper::HLSgetShort:
buzbeefa57c472012-11-21 12:06:18 -08003059 CvtSget(cu, call_inst, false /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003060 break;
3061 case greenland::IntrinsicHelper::HLSgetWide:
3062 case greenland::IntrinsicHelper::HLSgetDouble:
buzbeefa57c472012-11-21 12:06:18 -08003063 CvtSget(cu, call_inst, true /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003064 break;
3065 case greenland::IntrinsicHelper::HLSput:
3066 case greenland::IntrinsicHelper::HLSputFloat:
3067 case greenland::IntrinsicHelper::HLSputBoolean:
3068 case greenland::IntrinsicHelper::HLSputByte:
3069 case greenland::IntrinsicHelper::HLSputChar:
3070 case greenland::IntrinsicHelper::HLSputShort:
buzbeefa57c472012-11-21 12:06:18 -08003071 CvtSput(cu, call_inst, false /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003072 break;
3073 case greenland::IntrinsicHelper::HLSputWide:
3074 case greenland::IntrinsicHelper::HLSputDouble:
buzbeefa57c472012-11-21 12:06:18 -08003075 CvtSput(cu, call_inst, true /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003076 break;
3077 case greenland::IntrinsicHelper::HLSputObject:
buzbeefa57c472012-11-21 12:06:18 -08003078 CvtSput(cu, call_inst, false /* wide */, true /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003079 break;
3080 case greenland::IntrinsicHelper::GetException:
buzbeefa57c472012-11-21 12:06:18 -08003081 CvtMoveException(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003082 break;
TDYa127f71bf5a2012-07-29 20:09:52 -07003083 case greenland::IntrinsicHelper::HLThrowException:
buzbeefa57c472012-11-21 12:06:18 -08003084 CvtThrow(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003085 break;
3086 case greenland::IntrinsicHelper::MonitorEnter:
buzbeefa57c472012-11-21 12:06:18 -08003087 CvtMonitorEnterExit(cu, true /* is_enter */, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003088 break;
3089 case greenland::IntrinsicHelper::MonitorExit:
buzbeefa57c472012-11-21 12:06:18 -08003090 CvtMonitorEnterExit(cu, false /* is_enter */, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003091 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003092 case greenland::IntrinsicHelper::OptArrayLength:
buzbeefa57c472012-11-21 12:06:18 -08003093 CvtArrayLength(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003094 break;
3095 case greenland::IntrinsicHelper::NewArray:
buzbeefa57c472012-11-21 12:06:18 -08003096 CvtNewArray(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003097 break;
3098 case greenland::IntrinsicHelper::InstanceOf:
buzbeefa57c472012-11-21 12:06:18 -08003099 CvtInstanceOf(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003100 break;
3101
3102 case greenland::IntrinsicHelper::HLArrayGet:
3103 case greenland::IntrinsicHelper::HLArrayGetObject:
3104 case greenland::IntrinsicHelper::HLArrayGetFloat:
buzbeefa57c472012-11-21 12:06:18 -08003105 CvtAget(cu, call_inst, kWord, 2);
buzbee0967a252012-09-14 10:43:54 -07003106 break;
3107 case greenland::IntrinsicHelper::HLArrayGetWide:
3108 case greenland::IntrinsicHelper::HLArrayGetDouble:
buzbeefa57c472012-11-21 12:06:18 -08003109 CvtAget(cu, call_inst, kLong, 3);
buzbee0967a252012-09-14 10:43:54 -07003110 break;
3111 case greenland::IntrinsicHelper::HLArrayGetBoolean:
buzbeefa57c472012-11-21 12:06:18 -08003112 CvtAget(cu, call_inst, kUnsignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003113 break;
3114 case greenland::IntrinsicHelper::HLArrayGetByte:
buzbeefa57c472012-11-21 12:06:18 -08003115 CvtAget(cu, call_inst, kSignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003116 break;
3117 case greenland::IntrinsicHelper::HLArrayGetChar:
buzbeefa57c472012-11-21 12:06:18 -08003118 CvtAget(cu, call_inst, kUnsignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003119 break;
3120 case greenland::IntrinsicHelper::HLArrayGetShort:
buzbeefa57c472012-11-21 12:06:18 -08003121 CvtAget(cu, call_inst, kSignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003122 break;
3123
3124 case greenland::IntrinsicHelper::HLArrayPut:
3125 case greenland::IntrinsicHelper::HLArrayPutFloat:
buzbeefa57c472012-11-21 12:06:18 -08003126 CvtAputPrimitive(cu, call_inst, kWord, 2);
buzbee0967a252012-09-14 10:43:54 -07003127 break;
3128 case greenland::IntrinsicHelper::HLArrayPutObject:
buzbeefa57c472012-11-21 12:06:18 -08003129 CvtAputObj(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003130 break;
3131 case greenland::IntrinsicHelper::HLArrayPutWide:
3132 case greenland::IntrinsicHelper::HLArrayPutDouble:
buzbeefa57c472012-11-21 12:06:18 -08003133 CvtAputPrimitive(cu, call_inst, kLong, 3);
buzbee0967a252012-09-14 10:43:54 -07003134 break;
3135 case greenland::IntrinsicHelper::HLArrayPutBoolean:
buzbeefa57c472012-11-21 12:06:18 -08003136 CvtAputPrimitive(cu, call_inst, kUnsignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003137 break;
3138 case greenland::IntrinsicHelper::HLArrayPutByte:
buzbeefa57c472012-11-21 12:06:18 -08003139 CvtAputPrimitive(cu, call_inst, kSignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003140 break;
3141 case greenland::IntrinsicHelper::HLArrayPutChar:
buzbeefa57c472012-11-21 12:06:18 -08003142 CvtAputPrimitive(cu, call_inst, kUnsignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003143 break;
3144 case greenland::IntrinsicHelper::HLArrayPutShort:
buzbeefa57c472012-11-21 12:06:18 -08003145 CvtAputPrimitive(cu, call_inst, kSignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003146 break;
3147
3148 case greenland::IntrinsicHelper::HLIGet:
3149 case greenland::IntrinsicHelper::HLIGetFloat:
buzbeefa57c472012-11-21 12:06:18 -08003150 CvtIget(cu, call_inst, kWord, false /* is_wide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003151 break;
3152 case greenland::IntrinsicHelper::HLIGetObject:
buzbeefa57c472012-11-21 12:06:18 -08003153 CvtIget(cu, call_inst, kWord, false /* is_wide */, true /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003154 break;
3155 case greenland::IntrinsicHelper::HLIGetWide:
3156 case greenland::IntrinsicHelper::HLIGetDouble:
buzbeefa57c472012-11-21 12:06:18 -08003157 CvtIget(cu, call_inst, kLong, true /* is_wide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003158 break;
3159 case greenland::IntrinsicHelper::HLIGetBoolean:
buzbeefa57c472012-11-21 12:06:18 -08003160 CvtIget(cu, call_inst, kUnsignedByte, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003161 false /* obj */);
3162 break;
3163 case greenland::IntrinsicHelper::HLIGetByte:
buzbeefa57c472012-11-21 12:06:18 -08003164 CvtIget(cu, call_inst, kSignedByte, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003165 false /* obj */);
3166 break;
3167 case greenland::IntrinsicHelper::HLIGetChar:
buzbeefa57c472012-11-21 12:06:18 -08003168 CvtIget(cu, call_inst, kUnsignedHalf, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003169 false /* obj */);
3170 break;
3171 case greenland::IntrinsicHelper::HLIGetShort:
buzbeefa57c472012-11-21 12:06:18 -08003172 CvtIget(cu, call_inst, kSignedHalf, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003173 false /* obj */);
3174 break;
3175
3176 case greenland::IntrinsicHelper::HLIPut:
3177 case greenland::IntrinsicHelper::HLIPutFloat:
buzbeefa57c472012-11-21 12:06:18 -08003178 CvtIput(cu, call_inst, kWord, false /* is_wide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003179 break;
3180 case greenland::IntrinsicHelper::HLIPutObject:
buzbeefa57c472012-11-21 12:06:18 -08003181 CvtIput(cu, call_inst, kWord, false /* is_wide */, true /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003182 break;
3183 case greenland::IntrinsicHelper::HLIPutWide:
3184 case greenland::IntrinsicHelper::HLIPutDouble:
buzbeefa57c472012-11-21 12:06:18 -08003185 CvtIput(cu, call_inst, kLong, true /* is_wide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003186 break;
3187 case greenland::IntrinsicHelper::HLIPutBoolean:
buzbeefa57c472012-11-21 12:06:18 -08003188 CvtIput(cu, call_inst, kUnsignedByte, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003189 false /* obj */);
3190 break;
3191 case greenland::IntrinsicHelper::HLIPutByte:
buzbeefa57c472012-11-21 12:06:18 -08003192 CvtIput(cu, call_inst, kSignedByte, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003193 false /* obj */);
3194 break;
3195 case greenland::IntrinsicHelper::HLIPutChar:
buzbeefa57c472012-11-21 12:06:18 -08003196 CvtIput(cu, call_inst, kUnsignedHalf, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003197 false /* obj */);
3198 break;
3199 case greenland::IntrinsicHelper::HLIPutShort:
buzbeefa57c472012-11-21 12:06:18 -08003200 CvtIput(cu, call_inst, kSignedHalf, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003201 false /* obj */);
3202 break;
3203
3204 case greenland::IntrinsicHelper::IntToChar:
buzbeefa57c472012-11-21 12:06:18 -08003205 CvtIntNarrowing(cu, call_inst, Instruction::INT_TO_CHAR);
buzbee0967a252012-09-14 10:43:54 -07003206 break;
3207 case greenland::IntrinsicHelper::IntToShort:
buzbeefa57c472012-11-21 12:06:18 -08003208 CvtIntNarrowing(cu, call_inst, Instruction::INT_TO_SHORT);
buzbee0967a252012-09-14 10:43:54 -07003209 break;
3210 case greenland::IntrinsicHelper::IntToByte:
buzbeefa57c472012-11-21 12:06:18 -08003211 CvtIntNarrowing(cu, call_inst, Instruction::INT_TO_BYTE);
buzbee0967a252012-09-14 10:43:54 -07003212 break;
3213
TDYa1274ec8ccd2012-08-11 07:04:57 -07003214 case greenland::IntrinsicHelper::F2I:
3215 case greenland::IntrinsicHelper::D2I:
3216 case greenland::IntrinsicHelper::F2L:
3217 case greenland::IntrinsicHelper::D2L:
buzbeefa57c472012-11-21 12:06:18 -08003218 CvtFPToInt(cu, call_inst);
TDYa1274ec8ccd2012-08-11 07:04:57 -07003219 break;
3220
buzbee0967a252012-09-14 10:43:54 -07003221 case greenland::IntrinsicHelper::CmplFloat:
buzbeefa57c472012-11-21 12:06:18 -08003222 CvtFPCompare(cu, call_inst, Instruction::CMPL_FLOAT);
buzbee0967a252012-09-14 10:43:54 -07003223 break;
3224 case greenland::IntrinsicHelper::CmpgFloat:
buzbeefa57c472012-11-21 12:06:18 -08003225 CvtFPCompare(cu, call_inst, Instruction::CMPG_FLOAT);
buzbee0967a252012-09-14 10:43:54 -07003226 break;
3227 case greenland::IntrinsicHelper::CmplDouble:
buzbeefa57c472012-11-21 12:06:18 -08003228 CvtFPCompare(cu, call_inst, Instruction::CMPL_DOUBLE);
buzbee0967a252012-09-14 10:43:54 -07003229 break;
3230 case greenland::IntrinsicHelper::CmpgDouble:
buzbeefa57c472012-11-21 12:06:18 -08003231 CvtFPCompare(cu, call_inst, Instruction::CMPG_DOUBLE);
buzbee0967a252012-09-14 10:43:54 -07003232 break;
3233
3234 case greenland::IntrinsicHelper::CmpLong:
buzbeefa57c472012-11-21 12:06:18 -08003235 CvtLongCompare(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003236 break;
3237
3238 case greenland::IntrinsicHelper::SHLLong:
buzbeefa57c472012-11-21 12:06:18 -08003239 CvtShiftOp(cu, Instruction::SHL_LONG, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003240 break;
3241 case greenland::IntrinsicHelper::SHRLong:
buzbeefa57c472012-11-21 12:06:18 -08003242 CvtShiftOp(cu, Instruction::SHR_LONG, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003243 break;
3244 case greenland::IntrinsicHelper::USHRLong:
buzbeefa57c472012-11-21 12:06:18 -08003245 CvtShiftOp(cu, Instruction::USHR_LONG, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003246 break;
3247 case greenland::IntrinsicHelper::SHLInt:
buzbeefa57c472012-11-21 12:06:18 -08003248 CvtShiftOp(cu, Instruction::SHL_INT, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003249 break;
3250 case greenland::IntrinsicHelper::SHRInt:
buzbeefa57c472012-11-21 12:06:18 -08003251 CvtShiftOp(cu, Instruction::SHR_INT, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003252 break;
3253 case greenland::IntrinsicHelper::USHRInt:
buzbeefa57c472012-11-21 12:06:18 -08003254 CvtShiftOp(cu, Instruction::USHR_INT, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003255 break;
3256
3257 case greenland::IntrinsicHelper::CatchTargets: {
buzbeefa57c472012-11-21 12:06:18 -08003258 llvm::SwitchInst* sw_inst =
3259 llvm::dyn_cast<llvm::SwitchInst>(next_it);
3260 DCHECK(sw_inst != NULL);
buzbee0967a252012-09-14 10:43:54 -07003261 /*
3262 * Discard the edges and the following conditional branch.
3263 * Do a direct branch to the default target (which is the
3264 * "work" portion of the pair.
3265 * TODO: awful code layout - rework
3266 */
buzbeefa57c472012-11-21 12:06:18 -08003267 llvm::BasicBlock* target_bb = sw_inst->getDefaultDest();
3268 DCHECK(target_bb != NULL);
3269 OpUnconditionalBranch(cu,
3270 cu->block_to_label_map.Get(target_bb));
buzbee0967a252012-09-14 10:43:54 -07003271 ++it;
3272 // Set next bb to default target - improves code layout
buzbeefa57c472012-11-21 12:06:18 -08003273 next_bb = target_bb;
buzbee0967a252012-09-14 10:43:54 -07003274 }
3275 break;
3276
3277 default:
buzbeefa57c472012-11-21 12:06:18 -08003278 LOG(FATAL) << "Unexpected intrinsic " << cu->intrinsic_helper->GetName(id);
buzbee0967a252012-09-14 10:43:54 -07003279 }
3280 }
3281 break;
3282
buzbeefa57c472012-11-21 12:06:18 -08003283 case llvm::Instruction::Br: CvtBr(cu, inst); break;
3284 case llvm::Instruction::Add: CvtBinOp(cu, kOpAdd, inst); break;
3285 case llvm::Instruction::Sub: CvtBinOp(cu, kOpSub, inst); break;
3286 case llvm::Instruction::Mul: CvtBinOp(cu, kOpMul, inst); break;
3287 case llvm::Instruction::SDiv: CvtBinOp(cu, kOpDiv, inst); break;
3288 case llvm::Instruction::SRem: CvtBinOp(cu, kOpRem, inst); break;
3289 case llvm::Instruction::And: CvtBinOp(cu, kOpAnd, inst); break;
3290 case llvm::Instruction::Or: CvtBinOp(cu, kOpOr, inst); break;
3291 case llvm::Instruction::Xor: CvtBinOp(cu, kOpXor, inst); break;
3292 case llvm::Instruction::PHI: CvtPhi(cu, inst); break;
3293 case llvm::Instruction::Ret: CvtRet(cu, inst); break;
3294 case llvm::Instruction::FAdd: CvtBinFPOp(cu, kOpAdd, inst); break;
3295 case llvm::Instruction::FSub: CvtBinFPOp(cu, kOpSub, inst); break;
3296 case llvm::Instruction::FMul: CvtBinFPOp(cu, kOpMul, inst); break;
3297 case llvm::Instruction::FDiv: CvtBinFPOp(cu, kOpDiv, inst); break;
3298 case llvm::Instruction::FRem: CvtBinFPOp(cu, kOpRem, inst); break;
3299 case llvm::Instruction::SIToFP: CvtIntToFP(cu, inst); break;
3300 case llvm::Instruction::FPTrunc: CvtDoubleToFloat(cu, inst); break;
3301 case llvm::Instruction::FPExt: CvtFloatToDouble(cu, inst); break;
3302 case llvm::Instruction::Trunc: CvtTrunc(cu, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003303
buzbeefa57c472012-11-21 12:06:18 -08003304 case llvm::Instruction::ZExt: CvtIntExt(cu, inst, false /* signed */);
buzbee0967a252012-09-14 10:43:54 -07003305 break;
buzbeefa57c472012-11-21 12:06:18 -08003306 case llvm::Instruction::SExt: CvtIntExt(cu, inst, true /* signed */);
buzbee0967a252012-09-14 10:43:54 -07003307 break;
3308
buzbeefa57c472012-11-21 12:06:18 -08003309 case llvm::Instruction::Switch: CvtSwitch(cu, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003310
3311 case llvm::Instruction::Unreachable:
3312 break; // FIXME: can we really ignore these?
3313
3314 case llvm::Instruction::Shl:
3315 case llvm::Instruction::LShr:
3316 case llvm::Instruction::AShr:
3317 case llvm::Instruction::Invoke:
3318 case llvm::Instruction::FPToUI:
TDYa1274ec8ccd2012-08-11 07:04:57 -07003319 case llvm::Instruction::FPToSI:
buzbee0967a252012-09-14 10:43:54 -07003320 case llvm::Instruction::UIToFP:
3321 case llvm::Instruction::PtrToInt:
3322 case llvm::Instruction::IntToPtr:
3323 case llvm::Instruction::FCmp:
3324 case llvm::Instruction::URem:
3325 case llvm::Instruction::UDiv:
3326 case llvm::Instruction::Resume:
3327 case llvm::Instruction::Alloca:
3328 case llvm::Instruction::GetElementPtr:
3329 case llvm::Instruction::Fence:
3330 case llvm::Instruction::AtomicCmpXchg:
3331 case llvm::Instruction::AtomicRMW:
3332 case llvm::Instruction::BitCast:
3333 case llvm::Instruction::VAArg:
3334 case llvm::Instruction::Select:
3335 case llvm::Instruction::UserOp1:
3336 case llvm::Instruction::UserOp2:
3337 case llvm::Instruction::ExtractElement:
3338 case llvm::Instruction::InsertElement:
3339 case llvm::Instruction::ShuffleVector:
3340 case llvm::Instruction::ExtractValue:
3341 case llvm::Instruction::InsertValue:
3342 case llvm::Instruction::LandingPad:
3343 case llvm::Instruction::IndirectBr:
3344 case llvm::Instruction::Load:
3345 case llvm::Instruction::Store:
3346 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3347
3348 default:
3349 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3350 break;
buzbeead8f15e2012-06-18 14:49:45 -07003351 }
3352 }
buzbee2cfc6392012-05-07 14:51:40 -07003353
buzbeefa57c472012-11-21 12:06:18 -08003354 if (head_lir != NULL) {
3355 ApplyLocalOptimizations(cu, head_lir, cu->last_lir_insn);
buzbee2cfc6392012-05-07 14:51:40 -07003356 }
buzbeefa57c472012-11-21 12:06:18 -08003357 if (next_bb != NULL) {
3358 bb = next_bb;
3359 next_bb = NULL;
buzbee6969d502012-06-15 16:40:31 -07003360 }
buzbee6969d502012-06-15 16:40:31 -07003361 }
buzbee2cfc6392012-05-07 14:51:40 -07003362 return false;
3363}
3364
3365/*
3366 * Convert LLVM_IR to MIR:
3367 * o Iterate through the LLVM_IR and construct a graph using
3368 * standard MIR building blocks.
3369 * o Perform a basic-block optimization pass to remove unnecessary
3370 * store/load sequences.
3371 * o Convert the LLVM Value operands into RegLocations where applicable.
buzbeefa57c472012-11-21 12:06:18 -08003372 * o Create ssa_rep def/use operand arrays for each converted LLVM opcode
buzbee2cfc6392012-05-07 14:51:40 -07003373 * o Perform register promotion
3374 * o Iterate through the graph a basic block at a time, generating
3375 * LIR.
3376 * o Assemble LIR as usual.
3377 * o Profit.
3378 */
buzbeefa57c472012-11-21 12:06:18 -08003379void MethodBitcode2LIR(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -07003380{
buzbeefa57c472012-11-21 12:06:18 -08003381 llvm::Function* func = cu->func;
3382 int num_basic_blocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003383 // Allocate a list for LIR basic block labels
buzbeefa57c472012-11-21 12:06:18 -08003384 cu->block_label_list =
3385 static_cast<LIR*>(NewMem(cu, sizeof(LIR) * num_basic_blocks, true, kAllocLIR));
3386 LIR* label_list = cu->block_label_list;
3387 int next_label = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003388 for (llvm::Function::iterator i = func->begin(),
3389 e = func->end(); i != e; ++i) {
buzbeefa57c472012-11-21 12:06:18 -08003390 cu->block_to_label_map.Put(static_cast<llvm::BasicBlock*>(i),
3391 &label_list[next_label++]);
buzbee2cfc6392012-05-07 14:51:40 -07003392 }
buzbeead8f15e2012-06-18 14:49:45 -07003393
3394 /*
buzbeefa57c472012-11-21 12:06:18 -08003395 * Keep honest - clear reg_locations, Value => RegLocation,
buzbeead8f15e2012-06-18 14:49:45 -07003396 * promotion map and VmapTables.
3397 */
buzbeefa57c472012-11-21 12:06:18 -08003398 cu->loc_map.clear(); // Start fresh
3399 cu->reg_location = NULL;
3400 for (int i = 0; i < cu->num_dalvik_registers + cu->num_compiler_temps + 1;
buzbeead8f15e2012-06-18 14:49:45 -07003401 i++) {
buzbeefa57c472012-11-21 12:06:18 -08003402 cu->promotion_map[i].core_location = kLocDalvikFrame;
3403 cu->promotion_map[i].fp_location = kLocDalvikFrame;
buzbeead8f15e2012-06-18 14:49:45 -07003404 }
buzbeefa57c472012-11-21 12:06:18 -08003405 cu->core_spill_mask = 0;
3406 cu->num_core_spills = 0;
3407 cu->fp_spill_mask = 0;
3408 cu->num_fp_spills = 0;
3409 cu->core_vmap_table.clear();
3410 cu->fp_vmap_table.clear();
buzbeead8f15e2012-06-18 14:49:45 -07003411
3412 /*
3413 * At this point, we've lost all knowledge of register promotion.
3414 * Rebuild that info from the MethodInfo intrinsic (if it
buzbeeca7a5e42012-08-20 11:12:18 -07003415 * exists - not required for correctness). Normally, this will
3416 * be the first instruction we encounter, so we won't have to iterate
3417 * through everything.
buzbeead8f15e2012-06-18 14:49:45 -07003418 */
buzbeeca7a5e42012-08-20 11:12:18 -07003419 for (llvm::inst_iterator i = llvm::inst_begin(func),
3420 e = llvm::inst_end(func); i != e; ++i) {
buzbeefa57c472012-11-21 12:06:18 -08003421 llvm::CallInst* call_inst = llvm::dyn_cast<llvm::CallInst>(&*i);
3422 if (call_inst != NULL) {
3423 llvm::Function* callee = call_inst->getCalledFunction();
buzbeeca7a5e42012-08-20 11:12:18 -07003424 greenland::IntrinsicHelper::IntrinsicId id =
buzbeefa57c472012-11-21 12:06:18 -08003425 cu->intrinsic_helper->GetIntrinsicId(callee);
buzbeeca7a5e42012-08-20 11:12:18 -07003426 if (id == greenland::IntrinsicHelper::MethodInfo) {
buzbeefa57c472012-11-21 12:06:18 -08003427 if (cu->verbose) {
buzbeeca7a5e42012-08-20 11:12:18 -07003428 LOG(INFO) << "Found MethodInfo";
3429 }
buzbeefa57c472012-11-21 12:06:18 -08003430 llvm::MDNode* reg_info_node = call_inst->getMetadata("RegInfo");
3431 if (reg_info_node != NULL) {
3432 llvm::ConstantInt* num_ins_value =
3433 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(0));
3434 llvm::ConstantInt* num_regs_value =
3435 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(1));
3436 llvm::ConstantInt* num_outs_value =
3437 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(2));
3438 llvm::ConstantInt* num_compiler_temps_value =
3439 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(3));
3440 llvm::ConstantInt* num_ssa_regs_value =
3441 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(4));
3442 if (cu->verbose) {
3443 LOG(INFO) << "RegInfo - Ins:" << num_ins_value->getZExtValue()
3444 << ", Regs:" << num_regs_value->getZExtValue()
3445 << ", Outs:" << num_outs_value->getZExtValue()
3446 << ", CTemps:" << num_compiler_temps_value->getZExtValue()
3447 << ", SSARegs:" << num_ssa_regs_value->getZExtValue();
buzbeeca7a5e42012-08-20 11:12:18 -07003448 }
3449 }
buzbeefa57c472012-11-21 12:06:18 -08003450 llvm::MDNode* pmap_info_node = call_inst->getMetadata("PromotionMap");
3451 if (pmap_info_node != NULL) {
3452 int elems = pmap_info_node->getNumOperands();
3453 if (cu->verbose) {
buzbeeca7a5e42012-08-20 11:12:18 -07003454 LOG(INFO) << "PMap size: " << elems;
3455 }
3456 for (int i = 0; i < elems; i++) {
buzbeefa57c472012-11-21 12:06:18 -08003457 llvm::ConstantInt* raw_map_data =
3458 static_cast<llvm::ConstantInt*>(pmap_info_node->getOperand(i));
3459 uint32_t map_data = raw_map_data->getZExtValue();
3460 PromotionMap* p = &cu->promotion_map[i];
3461 p->first_in_pair = (map_data >> 24) & 0xff;
3462 p->FpReg = (map_data >> 16) & 0xff;
3463 p->core_reg = (map_data >> 8) & 0xff;
3464 p->fp_location = static_cast<RegLocationType>((map_data >> 4) & 0xf);
3465 if (p->fp_location == kLocPhysReg) {
3466 RecordFpPromotion(cu, p->FpReg, i);
buzbeeca7a5e42012-08-20 11:12:18 -07003467 }
buzbeefa57c472012-11-21 12:06:18 -08003468 p->core_location = static_cast<RegLocationType>(map_data & 0xf);
3469 if (p->core_location == kLocPhysReg) {
3470 RecordCorePromotion(cu, p->core_reg, i);
buzbeeca7a5e42012-08-20 11:12:18 -07003471 }
3472 }
buzbeefa57c472012-11-21 12:06:18 -08003473 if (cu->verbose) {
3474 DumpPromotionMap(cu);
buzbeeca7a5e42012-08-20 11:12:18 -07003475 }
3476 }
3477 break;
3478 }
3479 }
3480 }
buzbeefa57c472012-11-21 12:06:18 -08003481 AdjustSpillMask(cu);
3482 cu->frame_size = ComputeFrameSize(cu);
buzbeead8f15e2012-06-18 14:49:45 -07003483
3484 // Create RegLocations for arguments
buzbeefa57c472012-11-21 12:06:18 -08003485 llvm::Function::arg_iterator it(cu->func->arg_begin());
3486 llvm::Function::arg_iterator it_end(cu->func->arg_end());
buzbeead8f15e2012-06-18 14:49:45 -07003487 for (; it != it_end; ++it) {
3488 llvm::Value* val = it;
buzbeefa57c472012-11-21 12:06:18 -08003489 CreateLocFromValue(cu, val);
buzbeead8f15e2012-06-18 14:49:45 -07003490 }
3491 // Create RegLocations for all non-argument defintions
3492 for (llvm::inst_iterator i = llvm::inst_begin(func),
3493 e = llvm::inst_end(func); i != e; ++i) {
3494 llvm::Value* val = &*i;
3495 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
buzbeefa57c472012-11-21 12:06:18 -08003496 CreateLocFromValue(cu, val);
buzbeead8f15e2012-06-18 14:49:45 -07003497 }
3498 }
3499
buzbee2cfc6392012-05-07 14:51:40 -07003500 // Walk the blocks, generating code.
buzbeefa57c472012-11-21 12:06:18 -08003501 for (llvm::Function::iterator i = cu->func->begin(),
3502 e = cu->func->end(); i != e; ++i) {
3503 BitcodeBlockCodeGen(cu, static_cast<llvm::BasicBlock*>(i));
buzbee2cfc6392012-05-07 14:51:40 -07003504 }
3505
buzbeefa57c472012-11-21 12:06:18 -08003506 HandleSuspendLaunchPads(cu);
buzbee2cfc6392012-05-07 14:51:40 -07003507
buzbeefa57c472012-11-21 12:06:18 -08003508 HandleThrowLaunchPads(cu);
buzbee2cfc6392012-05-07 14:51:40 -07003509
buzbeefa57c472012-11-21 12:06:18 -08003510 HandleIntrinsicLaunchPads(cu);
buzbee2cfc6392012-05-07 14:51:40 -07003511
buzbeefa57c472012-11-21 12:06:18 -08003512 cu->func->eraseFromParent();
3513 cu->func = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07003514}
3515
3516
3517} // namespace art