blob: 766a630a0cf7f4974eaca0822ea46393beff68df [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 "local_optimizations.h"
buzbee1bc37c62012-11-20 13:35:41 -080032#include "codegen_util.h"
33#include "ralloc_util.h"
buzbeeeaf09bc2012-11-15 14:51:41 -080034
buzbee8320f382012-09-11 16:29:42 -070035static const char* kLabelFormat = "%c0x%x_%d";
buzbee951c0a12012-10-03 16:31:39 -070036static const char kInvalidBlock = 0xff;
buzbee8320f382012-09-11 16:29:42 -070037static const char kNormalBlock = 'L';
38static const char kCatchBlock = 'C';
buzbee2cfc6392012-05-07 14:51:40 -070039
40namespace art {
buzbeefa57c472012-11-21 12:06:18 -080041static RegLocation GetLoc(CompilationUnit* cu, llvm::Value* val);
buzbee2cfc6392012-05-07 14:51:40 -070042
buzbeefa57c472012-11-21 12:06:18 -080043static llvm::BasicBlock* GetLLVMBlock(CompilationUnit* cu, int id)
buzbee2cfc6392012-05-07 14:51:40 -070044{
buzbeefa57c472012-11-21 12:06:18 -080045 return cu->id_to_block_map.Get(id);
buzbee2cfc6392012-05-07 14:51:40 -070046}
47
buzbeefa57c472012-11-21 12:06:18 -080048static llvm::Value* GetLLVMValue(CompilationUnit* cu, int s_reg)
buzbee2cfc6392012-05-07 14:51:40 -070049{
buzbeefa57c472012-11-21 12:06:18 -080050 return reinterpret_cast<llvm::Value*>(GrowableListGetElement(&cu->llvm_values, s_reg));
buzbee2cfc6392012-05-07 14:51:40 -070051}
52
buzbee26f10ee2012-12-21 11:16:29 -080053static void SetVregOnValue(CompilationUnit* cu, llvm::Value* val, int s_reg)
54{
55 // Set vreg for debugging
56 if (cu->compiler->IsDebuggingSupported()) {
57 greenland::IntrinsicHelper::IntrinsicId id =
58 greenland::IntrinsicHelper::SetVReg;
59 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id);
60 int v_reg = SRegToVReg(cu, s_reg);
61 llvm::Value* table_slot = cu->irb->getInt32(v_reg);
62 llvm::Value* args[] = { table_slot, val };
63 cu->irb->CreateCall(func, args);
64 }
65}
66
buzbee2cfc6392012-05-07 14:51:40 -070067// Replace the placeholder value with the real definition
buzbee26f10ee2012-12-21 11:16:29 -080068static void DefineValueOnly(CompilationUnit* cu, llvm::Value* val, int s_reg)
buzbee2cfc6392012-05-07 14:51:40 -070069{
buzbeefa57c472012-11-21 12:06:18 -080070 llvm::Value* placeholder = GetLLVMValue(cu, s_reg);
buzbee9a2487f2012-07-26 14:01:13 -070071 if (placeholder == NULL) {
72 // This can happen on instruction rewrite on verification failure
Bill Buzbeec9f40dd2012-08-15 11:35:25 -070073 LOG(WARNING) << "Null placeholder";
buzbee9a2487f2012-07-26 14:01:13 -070074 return;
75 }
buzbee2cfc6392012-05-07 14:51:40 -070076 placeholder->replaceAllUsesWith(val);
77 val->takeName(placeholder);
buzbeefa57c472012-11-21 12:06:18 -080078 cu->llvm_values.elem_list[s_reg] = reinterpret_cast<uintptr_t>(val);
buzbee4be777b2012-07-12 14:38:18 -070079 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(placeholder);
80 DCHECK(inst != NULL);
81 inst->eraseFromParent();
TDYa1278e950c12012-11-02 09:58:19 -070082
buzbee26f10ee2012-12-21 11:16:29 -080083}
84
85static void DefineValue(CompilationUnit* cu, llvm::Value* val, int s_reg)
86{
87 DefineValueOnly(cu, val, s_reg);
88 SetVregOnValue(cu, val, s_reg);
buzbee2cfc6392012-05-07 14:51:40 -070089}
90
buzbeefa57c472012-11-21 12:06:18 -080091static llvm::Type* LlvmTypeFromLocRec(CompilationUnit* cu, RegLocation loc)
buzbee2cfc6392012-05-07 14:51:40 -070092{
93 llvm::Type* res = NULL;
94 if (loc.wide) {
95 if (loc.fp)
buzbeefa57c472012-11-21 12:06:18 -080096 res = cu->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070097 else
buzbeefa57c472012-11-21 12:06:18 -080098 res = cu->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070099 } else {
100 if (loc.fp) {
buzbeefa57c472012-11-21 12:06:18 -0800101 res = cu->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -0700102 } else {
103 if (loc.ref)
buzbeefa57c472012-11-21 12:06:18 -0800104 res = cu->irb->GetJObjectTy();
buzbee2cfc6392012-05-07 14:51:40 -0700105 else
buzbeefa57c472012-11-21 12:06:18 -0800106 res = cu->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -0700107 }
108 }
109 return res;
110}
111
buzbeead8f15e2012-06-18 14:49:45 -0700112/* Create an in-memory RegLocation from an llvm Value. */
buzbeefa57c472012-11-21 12:06:18 -0800113static void CreateLocFromValue(CompilationUnit* cu, llvm::Value* val)
buzbeead8f15e2012-06-18 14:49:45 -0700114{
115 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
116 std::string s(val->getName().str());
buzbeefa57c472012-11-21 12:06:18 -0800117 const char* val_name = s.c_str();
118 SafeMap<llvm::Value*, RegLocation>::iterator it = cu->loc_map.find(val);
119 DCHECK(it == cu->loc_map.end()) << " - already defined: " << val_name;
120 int base_sreg = INVALID_SREG;
buzbeead8f15e2012-06-18 14:49:45 -0700121 int subscript = -1;
buzbeefa57c472012-11-21 12:06:18 -0800122 sscanf(val_name, "v%d_%d", &base_sreg, &subscript);
123 if ((base_sreg == INVALID_SREG) && (!strcmp(val_name, "method"))) {
124 base_sreg = SSA_METHOD_BASEREG;
buzbeead8f15e2012-06-18 14:49:45 -0700125 subscript = 0;
126 }
buzbeefa57c472012-11-21 12:06:18 -0800127 DCHECK_NE(base_sreg, INVALID_SREG);
buzbeead8f15e2012-06-18 14:49:45 -0700128 DCHECK_NE(subscript, -1);
129 // TODO: redo during C++'ification
130 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
131 INVALID_REG, INVALID_SREG, INVALID_SREG};
132 llvm::Type* ty = val->getType();
buzbeefa57c472012-11-21 12:06:18 -0800133 loc.wide = ((ty == cu->irb->getInt64Ty()) ||
134 (ty == cu->irb->getDoubleTy()));
buzbeead8f15e2012-06-18 14:49:45 -0700135 loc.defined = true;
buzbeeca7a5e42012-08-20 11:12:18 -0700136 loc.home = false; // May change during promotion
buzbeefa57c472012-11-21 12:06:18 -0800137 loc.s_reg_low = base_sreg;
138 loc.orig_sreg = cu->loc_map.size();
139 PromotionMap p_map = cu->promotion_map[base_sreg];
140 if (ty == cu->irb->getFloatTy()) {
buzbeeca7a5e42012-08-20 11:12:18 -0700141 loc.fp = true;
buzbeefa57c472012-11-21 12:06:18 -0800142 if (p_map.fp_location == kLocPhysReg) {
143 loc.low_reg = p_map.FpReg;
buzbeeca7a5e42012-08-20 11:12:18 -0700144 loc.location = kLocPhysReg;
145 loc.home = true;
146 }
buzbeefa57c472012-11-21 12:06:18 -0800147 } else if (ty == cu->irb->getDoubleTy()) {
buzbeeca7a5e42012-08-20 11:12:18 -0700148 loc.fp = true;
buzbeefa57c472012-11-21 12:06:18 -0800149 PromotionMap p_map_high = cu->promotion_map[base_sreg + 1];
150 if ((p_map.fp_location == kLocPhysReg) &&
151 (p_map_high.fp_location == kLocPhysReg) &&
152 ((p_map.FpReg & 0x1) == 0) &&
153 (p_map.FpReg + 1 == p_map_high.FpReg)) {
154 loc.low_reg = p_map.FpReg;
155 loc.high_reg = p_map_high.FpReg;
buzbeeca7a5e42012-08-20 11:12:18 -0700156 loc.location = kLocPhysReg;
157 loc.home = true;
158 }
buzbeefa57c472012-11-21 12:06:18 -0800159 } else if (ty == cu->irb->GetJObjectTy()) {
buzbeeca7a5e42012-08-20 11:12:18 -0700160 loc.ref = true;
buzbeefa57c472012-11-21 12:06:18 -0800161 if (p_map.core_location == kLocPhysReg) {
162 loc.low_reg = p_map.core_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700163 loc.location = kLocPhysReg;
164 loc.home = true;
165 }
buzbeefa57c472012-11-21 12:06:18 -0800166 } else if (ty == cu->irb->getInt64Ty()) {
buzbeeca7a5e42012-08-20 11:12:18 -0700167 loc.core = true;
buzbeefa57c472012-11-21 12:06:18 -0800168 PromotionMap p_map_high = cu->promotion_map[base_sreg + 1];
169 if ((p_map.core_location == kLocPhysReg) &&
170 (p_map_high.core_location == kLocPhysReg)) {
171 loc.low_reg = p_map.core_reg;
172 loc.high_reg = p_map_high.core_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700173 loc.location = kLocPhysReg;
174 loc.home = true;
175 }
176 } else {
177 loc.core = true;
buzbeefa57c472012-11-21 12:06:18 -0800178 if (p_map.core_location == kLocPhysReg) {
179 loc.low_reg = p_map.core_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700180 loc.location = kLocPhysReg;
181 loc.home = true;
182 }
183 }
184
buzbeefa57c472012-11-21 12:06:18 -0800185 if (cu->verbose && loc.home) {
buzbeeca7a5e42012-08-20 11:12:18 -0700186 if (loc.wide) {
buzbeefa57c472012-11-21 12:06:18 -0800187 LOG(INFO) << "Promoted wide " << s << " to regs " << loc.low_reg << "/" << loc.high_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700188 } else {
buzbeefa57c472012-11-21 12:06:18 -0800189 LOG(INFO) << "Promoted " << s << " to reg " << loc.low_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700190 }
191 }
buzbeefa57c472012-11-21 12:06:18 -0800192 cu->loc_map.Put(val, loc);
buzbeead8f15e2012-06-18 14:49:45 -0700193}
buzbeeaad94382012-11-21 07:40:50 -0800194
buzbeefa57c472012-11-21 12:06:18 -0800195static void InitIR(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -0700196{
buzbeefa57c472012-11-21 12:06:18 -0800197 LLVMInfo* llvm_info = cu->llvm_info;
198 if (llvm_info == NULL) {
199 CompilerTls* tls = cu->compiler->GetTls();
buzbee4df2bbd2012-10-11 14:46:06 -0700200 CHECK(tls != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800201 llvm_info = static_cast<LLVMInfo*>(tls->GetLLVMInfo());
202 if (llvm_info == NULL) {
203 llvm_info = new LLVMInfo();
204 tls->SetLLVMInfo(llvm_info);
buzbee4df2bbd2012-10-11 14:46:06 -0700205 }
206 }
buzbeefa57c472012-11-21 12:06:18 -0800207 cu->context = llvm_info->GetLLVMContext();
208 cu->module = llvm_info->GetLLVMModule();
209 cu->intrinsic_helper = llvm_info->GetIntrinsicHelper();
210 cu->irb = llvm_info->GetIRBuilder();
buzbee2cfc6392012-05-07 14:51:40 -0700211}
212
buzbeefa57c472012-11-21 12:06:18 -0800213static const char* LlvmSSAName(CompilationUnit* cu, int ssa_reg) {
214 return GET_ELEM_N(cu->ssa_strings, char*, ssa_reg);
buzbee2cfc6392012-05-07 14:51:40 -0700215}
216
buzbeefa57c472012-11-21 12:06:18 -0800217llvm::BasicBlock* FindCaseTarget(CompilationUnit* cu, uint32_t vaddr)
buzbeef58c12c2012-07-03 15:06:29 -0700218{
buzbeefa57c472012-11-21 12:06:18 -0800219 BasicBlock* bb = FindBlock(cu, vaddr);
buzbeef58c12c2012-07-03 15:06:29 -0700220 DCHECK(bb != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800221 return GetLLVMBlock(cu, bb->id);
buzbeef58c12c2012-07-03 15:06:29 -0700222}
223
buzbeefa57c472012-11-21 12:06:18 -0800224static void ConvertPackedSwitch(CompilationUnit* cu, BasicBlock* bb,
225 int32_t table_offset, RegLocation rl_src)
buzbeef58c12c2012-07-03 15:06:29 -0700226{
227 const Instruction::PackedSwitchPayload* payload =
228 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
buzbeefa57c472012-11-21 12:06:18 -0800229 cu->insns + cu->current_dalvik_offset + table_offset);
buzbeef58c12c2012-07-03 15:06:29 -0700230
buzbeefa57c472012-11-21 12:06:18 -0800231 llvm::Value* value = GetLLVMValue(cu, rl_src.orig_sreg);
buzbeef58c12c2012-07-03 15:06:29 -0700232
233 llvm::SwitchInst* sw =
buzbeefa57c472012-11-21 12:06:18 -0800234 cu->irb->CreateSwitch(value, GetLLVMBlock(cu, bb->fall_through->id),
buzbeef58c12c2012-07-03 15:06:29 -0700235 payload->case_count);
236
237 for (uint16_t i = 0; i < payload->case_count; ++i) {
buzbeefa57c472012-11-21 12:06:18 -0800238 llvm::BasicBlock* llvm_bb =
239 FindCaseTarget(cu, cu->current_dalvik_offset + payload->targets[i]);
240 sw->addCase(cu->irb->getInt32(payload->first_key + i), llvm_bb);
buzbeef58c12c2012-07-03 15:06:29 -0700241 }
buzbeefa57c472012-11-21 12:06:18 -0800242 llvm::MDNode* switch_node =
243 llvm::MDNode::get(*cu->context, cu->irb->getInt32(table_offset));
244 sw->setMetadata("SwitchTable", switch_node);
buzbeef58c12c2012-07-03 15:06:29 -0700245 bb->taken = NULL;
buzbeefa57c472012-11-21 12:06:18 -0800246 bb->fall_through = NULL;
buzbeef58c12c2012-07-03 15:06:29 -0700247}
248
buzbeefa57c472012-11-21 12:06:18 -0800249static void ConvertSparseSwitch(CompilationUnit* cu, BasicBlock* bb,
250 int32_t table_offset, RegLocation rl_src)
buzbeea1da8a52012-07-09 14:00:21 -0700251{
252 const Instruction::SparseSwitchPayload* payload =
253 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
buzbeefa57c472012-11-21 12:06:18 -0800254 cu->insns + cu->current_dalvik_offset + table_offset);
buzbeea1da8a52012-07-09 14:00:21 -0700255
256 const int32_t* keys = payload->GetKeys();
257 const int32_t* targets = payload->GetTargets();
258
buzbeefa57c472012-11-21 12:06:18 -0800259 llvm::Value* value = GetLLVMValue(cu, rl_src.orig_sreg);
buzbeea1da8a52012-07-09 14:00:21 -0700260
261 llvm::SwitchInst* sw =
buzbeefa57c472012-11-21 12:06:18 -0800262 cu->irb->CreateSwitch(value, GetLLVMBlock(cu, bb->fall_through->id),
buzbeea1da8a52012-07-09 14:00:21 -0700263 payload->case_count);
264
265 for (size_t i = 0; i < payload->case_count; ++i) {
buzbeefa57c472012-11-21 12:06:18 -0800266 llvm::BasicBlock* llvm_bb =
267 FindCaseTarget(cu, cu->current_dalvik_offset + targets[i]);
268 sw->addCase(cu->irb->getInt32(keys[i]), llvm_bb);
buzbeea1da8a52012-07-09 14:00:21 -0700269 }
buzbeefa57c472012-11-21 12:06:18 -0800270 llvm::MDNode* switch_node =
271 llvm::MDNode::get(*cu->context, cu->irb->getInt32(table_offset));
272 sw->setMetadata("SwitchTable", switch_node);
buzbeea1da8a52012-07-09 14:00:21 -0700273 bb->taken = NULL;
buzbeefa57c472012-11-21 12:06:18 -0800274 bb->fall_through = NULL;
buzbeea1da8a52012-07-09 14:00:21 -0700275}
276
buzbeefa57c472012-11-21 12:06:18 -0800277static void ConvertSget(CompilationUnit* cu, int32_t field_index,
278 greenland::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest)
buzbee4f1181f2012-06-22 13:52:12 -0700279{
buzbeefa57c472012-11-21 12:06:18 -0800280 llvm::Constant* field_idx = cu->irb->getInt32(field_index);
281 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
282 llvm::Value* res = cu->irb->CreateCall(intr, field_idx);
283 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700284}
285
buzbeefa57c472012-11-21 12:06:18 -0800286static void ConvertSput(CompilationUnit* cu, int32_t field_index,
287 greenland::IntrinsicHelper::IntrinsicId id, RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700288{
289 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800290 args.push_back(cu->irb->getInt32(field_index));
291 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
292 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
293 cu->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700294}
295
buzbeefa57c472012-11-21 12:06:18 -0800296static void ConvertFillArrayData(CompilationUnit* cu, int32_t offset, RegLocation rl_array)
buzbee101305f2012-06-28 18:00:56 -0700297{
298 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700299 id = greenland::IntrinsicHelper::HLFillArrayData;
buzbee101305f2012-06-28 18:00:56 -0700300 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800301 args.push_back(cu->irb->getInt32(offset));
302 args.push_back(GetLLVMValue(cu, rl_array.orig_sreg));
303 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
304 cu->irb->CreateCall(intr, args);
buzbee101305f2012-06-28 18:00:56 -0700305}
306
buzbeefa57c472012-11-21 12:06:18 -0800307static llvm::Value* EmitConst(CompilationUnit* cu, llvm::ArrayRef<llvm::Value*> src,
buzbeeaad94382012-11-21 07:40:50 -0800308 RegLocation loc)
buzbee2cfc6392012-05-07 14:51:40 -0700309{
310 greenland::IntrinsicHelper::IntrinsicId id;
311 if (loc.wide) {
312 if (loc.fp) {
313 id = greenland::IntrinsicHelper::ConstDouble;
314 } else {
315 id = greenland::IntrinsicHelper::ConstLong;
316 }
317 } else {
318 if (loc.fp) {
319 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700320 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700321 id = greenland::IntrinsicHelper::ConstObj;
322 } else {
323 id = greenland::IntrinsicHelper::ConstInt;
324 }
325 }
buzbeefa57c472012-11-21 12:06:18 -0800326 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
327 return cu->irb->CreateCall(intr, src);
buzbee2cfc6392012-05-07 14:51:40 -0700328}
buzbeeb03f4872012-06-11 15:22:11 -0700329
buzbeefa57c472012-11-21 12:06:18 -0800330static void EmitPopShadowFrame(CompilationUnit* cu)
buzbeeb03f4872012-06-11 15:22:11 -0700331{
buzbeefa57c472012-11-21 12:06:18 -0800332 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(
buzbeeb03f4872012-06-11 15:22:11 -0700333 greenland::IntrinsicHelper::PopShadowFrame);
buzbeefa57c472012-11-21 12:06:18 -0800334 cu->irb->CreateCall(intr);
buzbeeb03f4872012-06-11 15:22:11 -0700335}
336
buzbeefa57c472012-11-21 12:06:18 -0800337static llvm::Value* EmitCopy(CompilationUnit* cu, llvm::ArrayRef<llvm::Value*> src,
buzbeeaad94382012-11-21 07:40:50 -0800338 RegLocation loc)
buzbee2cfc6392012-05-07 14:51:40 -0700339{
340 greenland::IntrinsicHelper::IntrinsicId id;
341 if (loc.wide) {
342 if (loc.fp) {
343 id = greenland::IntrinsicHelper::CopyDouble;
344 } else {
345 id = greenland::IntrinsicHelper::CopyLong;
346 }
347 } else {
348 if (loc.fp) {
349 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700350 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700351 id = greenland::IntrinsicHelper::CopyObj;
352 } else {
353 id = greenland::IntrinsicHelper::CopyInt;
354 }
355 }
buzbeefa57c472012-11-21 12:06:18 -0800356 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
357 return cu->irb->CreateCall(intr, src);
buzbee2cfc6392012-05-07 14:51:40 -0700358}
359
buzbeefa57c472012-11-21 12:06:18 -0800360static void ConvertMoveException(CompilationUnit* cu, RegLocation rl_dest)
buzbee32412962012-06-26 16:27:56 -0700361{
buzbeefa57c472012-11-21 12:06:18 -0800362 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(
buzbee32412962012-06-26 16:27:56 -0700363 greenland::IntrinsicHelper::GetException);
buzbeefa57c472012-11-21 12:06:18 -0800364 llvm::Value* res = cu->irb->CreateCall(func);
365 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee32412962012-06-26 16:27:56 -0700366}
367
buzbeefa57c472012-11-21 12:06:18 -0800368static void ConvertThrow(CompilationUnit* cu, RegLocation rl_src)
buzbee32412962012-06-26 16:27:56 -0700369{
buzbeefa57c472012-11-21 12:06:18 -0800370 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
371 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(
TDYa127f71bf5a2012-07-29 20:09:52 -0700372 greenland::IntrinsicHelper::HLThrowException);
buzbeefa57c472012-11-21 12:06:18 -0800373 cu->irb->CreateCall(func, src);
buzbee32412962012-06-26 16:27:56 -0700374}
375
buzbeefa57c472012-11-21 12:06:18 -0800376static void ConvertMonitorEnterExit(CompilationUnit* cu, int opt_flags,
buzbeeaad94382012-11-21 07:40:50 -0800377 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800378 RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700379{
380 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800381 args.push_back(cu->irb->getInt32(opt_flags));
382 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
383 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id);
384 cu->irb->CreateCall(func, args);
buzbee8fa0fda2012-06-27 15:44:52 -0700385}
386
buzbeefa57c472012-11-21 12:06:18 -0800387static void ConvertArrayLength(CompilationUnit* cu, int opt_flags,
388 RegLocation rl_dest, RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700389{
390 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800391 args.push_back(cu->irb->getInt32(opt_flags));
392 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
393 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700394 greenland::IntrinsicHelper::OptArrayLength);
buzbeefa57c472012-11-21 12:06:18 -0800395 llvm::Value* res = cu->irb->CreateCall(func, args);
396 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700397}
398
buzbeefa57c472012-11-21 12:06:18 -0800399static void EmitSuspendCheck(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -0700400{
401 greenland::IntrinsicHelper::IntrinsicId id =
402 greenland::IntrinsicHelper::CheckSuspend;
buzbeefa57c472012-11-21 12:06:18 -0800403 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
404 cu->irb->CreateCall(intr);
buzbee2cfc6392012-05-07 14:51:40 -0700405}
406
buzbeefa57c472012-11-21 12:06:18 -0800407static llvm::Value* ConvertCompare(CompilationUnit* cu, ConditionCode cc,
buzbeeaad94382012-11-21 07:40:50 -0800408 llvm::Value* src1, llvm::Value* src2)
buzbee2cfc6392012-05-07 14:51:40 -0700409{
410 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700411 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700412 switch(cc) {
buzbeefa57c472012-11-21 12:06:18 -0800413 case kCondEq: res = cu->irb->CreateICmpEQ(src1, src2); break;
414 case kCondNe: res = cu->irb->CreateICmpNE(src1, src2); break;
415 case kCondLt: res = cu->irb->CreateICmpSLT(src1, src2); break;
416 case kCondGe: res = cu->irb->CreateICmpSGE(src1, src2); break;
417 case kCondGt: res = cu->irb->CreateICmpSGT(src1, src2); break;
418 case kCondLe: res = cu->irb->CreateICmpSLE(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700419 default: LOG(FATAL) << "Unexpected cc value " << cc;
420 }
421 return res;
422}
423
buzbeefa57c472012-11-21 12:06:18 -0800424static void ConvertCompareAndBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
425 ConditionCode cc, RegLocation rl_src1, RegLocation rl_src2)
buzbee2cfc6392012-05-07 14:51:40 -0700426{
buzbeefa57c472012-11-21 12:06:18 -0800427 if (bb->taken->start_offset <= mir->offset) {
428 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -0700429 }
buzbeefa57c472012-11-21 12:06:18 -0800430 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
431 llvm::Value* src2 = GetLLVMValue(cu, rl_src2.orig_sreg);
432 llvm::Value* cond_value = ConvertCompare(cu, cc, src1, src2);
433 cond_value->setName(StringPrintf("t%d", cu->temp_name++));
434 cu->irb->CreateCondBr(cond_value, GetLLVMBlock(cu, bb->taken->id),
435 GetLLVMBlock(cu, bb->fall_through->id));
buzbee6969d502012-06-15 16:40:31 -0700436 // Don't redo the fallthrough branch in the BB driver
buzbeefa57c472012-11-21 12:06:18 -0800437 bb->fall_through = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700438}
439
buzbeefa57c472012-11-21 12:06:18 -0800440static void ConvertCompareZeroAndBranch(CompilationUnit* cu, BasicBlock* bb,
441 MIR* mir, ConditionCode cc, RegLocation rl_src1)
buzbee2cfc6392012-05-07 14:51:40 -0700442{
buzbeefa57c472012-11-21 12:06:18 -0800443 if (bb->taken->start_offset <= mir->offset) {
444 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -0700445 }
buzbeefa57c472012-11-21 12:06:18 -0800446 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700447 llvm::Value* src2;
buzbeefa57c472012-11-21 12:06:18 -0800448 if (rl_src1.ref) {
449 src2 = cu->irb->GetJNull();
buzbee2cfc6392012-05-07 14:51:40 -0700450 } else {
buzbeefa57c472012-11-21 12:06:18 -0800451 src2 = cu->irb->getInt32(0);
buzbee2cfc6392012-05-07 14:51:40 -0700452 }
buzbeefa57c472012-11-21 12:06:18 -0800453 llvm::Value* cond_value = ConvertCompare(cu, cc, src1, src2);
454 cu->irb->CreateCondBr(cond_value, GetLLVMBlock(cu, bb->taken->id),
455 GetLLVMBlock(cu, bb->fall_through->id));
buzbee6969d502012-06-15 16:40:31 -0700456 // Don't redo the fallthrough branch in the BB driver
buzbeefa57c472012-11-21 12:06:18 -0800457 bb->fall_through = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700458}
459
buzbeefa57c472012-11-21 12:06:18 -0800460static llvm::Value* GenDivModOp(CompilationUnit* cu, bool is_div, bool is_long,
buzbeeaad94382012-11-21 07:40:50 -0800461 llvm::Value* src1, llvm::Value* src2)
buzbee2cfc6392012-05-07 14:51:40 -0700462{
463 greenland::IntrinsicHelper::IntrinsicId id;
buzbeefa57c472012-11-21 12:06:18 -0800464 if (is_long) {
465 if (is_div) {
buzbee2cfc6392012-05-07 14:51:40 -0700466 id = greenland::IntrinsicHelper::DivLong;
467 } else {
468 id = greenland::IntrinsicHelper::RemLong;
469 }
Logan Chien554e6072012-07-23 20:00:01 -0700470 } else {
buzbeefa57c472012-11-21 12:06:18 -0800471 if (is_div) {
buzbee2cfc6392012-05-07 14:51:40 -0700472 id = greenland::IntrinsicHelper::DivInt;
473 } else {
474 id = greenland::IntrinsicHelper::RemInt;
Logan Chien554e6072012-07-23 20:00:01 -0700475 }
buzbee2cfc6392012-05-07 14:51:40 -0700476 }
buzbeefa57c472012-11-21 12:06:18 -0800477 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee2cfc6392012-05-07 14:51:40 -0700478 llvm::SmallVector<llvm::Value*, 2>args;
479 args.push_back(src1);
480 args.push_back(src2);
buzbeefa57c472012-11-21 12:06:18 -0800481 return cu->irb->CreateCall(intr, args);
buzbee2cfc6392012-05-07 14:51:40 -0700482}
483
buzbeefa57c472012-11-21 12:06:18 -0800484static llvm::Value* GenArithOp(CompilationUnit* cu, OpKind op, bool is_long,
buzbeeaad94382012-11-21 07:40:50 -0800485 llvm::Value* src1, llvm::Value* src2)
buzbee2cfc6392012-05-07 14:51:40 -0700486{
487 llvm::Value* res = NULL;
488 switch(op) {
buzbeefa57c472012-11-21 12:06:18 -0800489 case kOpAdd: res = cu->irb->CreateAdd(src1, src2); break;
490 case kOpSub: res = cu->irb->CreateSub(src1, src2); break;
491 case kOpRsub: res = cu->irb->CreateSub(src2, src1); break;
492 case kOpMul: res = cu->irb->CreateMul(src1, src2); break;
493 case kOpOr: res = cu->irb->CreateOr(src1, src2); break;
494 case kOpAnd: res = cu->irb->CreateAnd(src1, src2); break;
495 case kOpXor: res = cu->irb->CreateXor(src1, src2); break;
496 case kOpDiv: res = GenDivModOp(cu, true, is_long, src1, src2); break;
497 case kOpRem: res = GenDivModOp(cu, false, is_long, src1, src2); break;
498 case kOpLsl: res = cu->irb->CreateShl(src1, src2); break;
499 case kOpLsr: res = cu->irb->CreateLShr(src1, src2); break;
500 case kOpAsr: res = cu->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700501 default:
502 LOG(FATAL) << "Invalid op " << op;
503 }
504 return res;
505}
506
buzbeefa57c472012-11-21 12:06:18 -0800507static void ConvertFPArithOp(CompilationUnit* cu, OpKind op, RegLocation rl_dest,
508 RegLocation rl_src1, RegLocation rl_src2)
buzbee2cfc6392012-05-07 14:51:40 -0700509{
buzbeefa57c472012-11-21 12:06:18 -0800510 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
511 llvm::Value* src2 = GetLLVMValue(cu, rl_src2.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700512 llvm::Value* res = NULL;
513 switch(op) {
buzbeefa57c472012-11-21 12:06:18 -0800514 case kOpAdd: res = cu->irb->CreateFAdd(src1, src2); break;
515 case kOpSub: res = cu->irb->CreateFSub(src1, src2); break;
516 case kOpMul: res = cu->irb->CreateFMul(src1, src2); break;
517 case kOpDiv: res = cu->irb->CreateFDiv(src1, src2); break;
518 case kOpRem: res = cu->irb->CreateFRem(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700519 default:
520 LOG(FATAL) << "Invalid op " << op;
521 }
buzbeefa57c472012-11-21 12:06:18 -0800522 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700523}
524
buzbeefa57c472012-11-21 12:06:18 -0800525static void ConvertShift(CompilationUnit* cu, greenland::IntrinsicHelper::IntrinsicId id,
526 RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2)
buzbee4f1181f2012-06-22 13:52:12 -0700527{
buzbeefa57c472012-11-21 12:06:18 -0800528 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee2a83e8f2012-07-13 16:42:30 -0700529 llvm::SmallVector<llvm::Value*, 2>args;
buzbeefa57c472012-11-21 12:06:18 -0800530 args.push_back(GetLLVMValue(cu, rl_src1.orig_sreg));
531 args.push_back(GetLLVMValue(cu, rl_src2.orig_sreg));
532 llvm::Value* res = cu->irb->CreateCall(intr, args);
533 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2a83e8f2012-07-13 16:42:30 -0700534}
535
buzbeefa57c472012-11-21 12:06:18 -0800536static void ConvertShiftLit(CompilationUnit* cu, greenland::IntrinsicHelper::IntrinsicId id,
537 RegLocation rl_dest, RegLocation rl_src, int shift_amount)
buzbee2a83e8f2012-07-13 16:42:30 -0700538{
buzbeefa57c472012-11-21 12:06:18 -0800539 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee2a83e8f2012-07-13 16:42:30 -0700540 llvm::SmallVector<llvm::Value*, 2>args;
buzbeefa57c472012-11-21 12:06:18 -0800541 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
542 args.push_back(cu->irb->getInt32(shift_amount));
543 llvm::Value* res = cu->irb->CreateCall(intr, args);
544 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee4f1181f2012-06-22 13:52:12 -0700545}
546
buzbeefa57c472012-11-21 12:06:18 -0800547static void ConvertArithOp(CompilationUnit* cu, OpKind op, RegLocation rl_dest,
548 RegLocation rl_src1, RegLocation rl_src2)
buzbee2cfc6392012-05-07 14:51:40 -0700549{
buzbeefa57c472012-11-21 12:06:18 -0800550 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
551 llvm::Value* src2 = GetLLVMValue(cu, rl_src2.orig_sreg);
buzbee4f4dfc72012-07-02 14:54:44 -0700552 DCHECK_EQ(src1->getType(), src2->getType());
buzbeefa57c472012-11-21 12:06:18 -0800553 llvm::Value* res = GenArithOp(cu, op, rl_dest.wide, src1, src2);
554 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700555}
556
buzbeefa57c472012-11-21 12:06:18 -0800557static void ConvertArithOpLit(CompilationUnit* cu, OpKind op, RegLocation rl_dest,
558 RegLocation rl_src1, int32_t imm)
buzbee2cfc6392012-05-07 14:51:40 -0700559{
buzbeefa57c472012-11-21 12:06:18 -0800560 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
561 llvm::Value* src2 = cu->irb->getInt32(imm);
562 llvm::Value* res = GenArithOp(cu, op, rl_dest.wide, src1, src2);
563 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700564}
565
buzbee101305f2012-06-28 18:00:56 -0700566/*
567 * Process arguments for invoke. Note: this code is also used to
568 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
569 * The requirements are similar.
570 */
buzbeefa57c472012-11-21 12:06:18 -0800571static void ConvertInvoke(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
572 InvokeType invoke_type, bool is_range, bool is_filled_new_array)
buzbee6969d502012-06-15 16:40:31 -0700573{
buzbee02031b12012-11-23 09:41:35 -0800574 Codegen* cg = cu->cg.get();
575 CallInfo* info = cg->NewMemCallInfo(cu, bb, mir, invoke_type, is_range);
buzbee6969d502012-06-15 16:40:31 -0700576 llvm::SmallVector<llvm::Value*, 10> args;
buzbeefa57c472012-11-21 12:06:18 -0800577 // Insert the invoke_type
578 args.push_back(cu->irb->getInt32(static_cast<int>(invoke_type)));
buzbee6969d502012-06-15 16:40:31 -0700579 // Insert the method_idx
buzbeefa57c472012-11-21 12:06:18 -0800580 args.push_back(cu->irb->getInt32(info->index));
buzbee6969d502012-06-15 16:40:31 -0700581 // Insert the optimization flags
buzbeefa57c472012-11-21 12:06:18 -0800582 args.push_back(cu->irb->getInt32(info->opt_flags));
buzbee6969d502012-06-15 16:40:31 -0700583 // Now, insert the actual arguments
buzbeefa57c472012-11-21 12:06:18 -0800584 for (int i = 0; i < info->num_arg_words;) {
585 llvm::Value* val = GetLLVMValue(cu, info->args[i].orig_sreg);
buzbee6969d502012-06-15 16:40:31 -0700586 args.push_back(val);
587 i += info->args[i].wide ? 2 : 1;
588 }
589 /*
590 * Choose the invoke return type based on actual usage. Note: may
591 * be different than shorty. For example, if a function return value
592 * is not used, we'll treat this as a void invoke.
593 */
594 greenland::IntrinsicHelper::IntrinsicId id;
buzbeefa57c472012-11-21 12:06:18 -0800595 if (is_filled_new_array) {
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700596 id = greenland::IntrinsicHelper::HLFilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700597 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700598 id = greenland::IntrinsicHelper::HLInvokeVoid;
599 } else {
600 if (info->result.wide) {
601 if (info->result.fp) {
602 id = greenland::IntrinsicHelper::HLInvokeDouble;
603 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700604 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700605 }
606 } else if (info->result.ref) {
607 id = greenland::IntrinsicHelper::HLInvokeObj;
608 } else if (info->result.fp) {
609 id = greenland::IntrinsicHelper::HLInvokeFloat;
610 } else {
611 id = greenland::IntrinsicHelper::HLInvokeInt;
612 }
613 }
buzbeefa57c472012-11-21 12:06:18 -0800614 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
615 llvm::Value* res = cu->irb->CreateCall(intr, args);
buzbee6969d502012-06-15 16:40:31 -0700616 if (info->result.location != kLocInvalid) {
buzbeefa57c472012-11-21 12:06:18 -0800617 DefineValue(cu, res, info->result.orig_sreg);
buzbee6969d502012-06-15 16:40:31 -0700618 }
619}
620
buzbeefa57c472012-11-21 12:06:18 -0800621static void ConvertConstObject(CompilationUnit* cu, uint32_t idx,
622 greenland::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest)
buzbee6969d502012-06-15 16:40:31 -0700623{
buzbeefa57c472012-11-21 12:06:18 -0800624 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
625 llvm::Value* index = cu->irb->getInt32(idx);
626 llvm::Value* res = cu->irb->CreateCall(intr, index);
627 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee6969d502012-06-15 16:40:31 -0700628}
629
buzbeefa57c472012-11-21 12:06:18 -0800630static void ConvertCheckCast(CompilationUnit* cu, uint32_t type_idx, RegLocation rl_src)
buzbee101305f2012-06-28 18:00:56 -0700631{
632 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700633 id = greenland::IntrinsicHelper::HLCheckCast;
buzbeefa57c472012-11-21 12:06:18 -0800634 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700635 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800636 args.push_back(cu->irb->getInt32(type_idx));
637 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
638 cu->irb->CreateCall(intr, args);
buzbee101305f2012-06-28 18:00:56 -0700639}
640
buzbeefa57c472012-11-21 12:06:18 -0800641static void ConvertNewInstance(CompilationUnit* cu, uint32_t type_idx, RegLocation rl_dest)
buzbee4f1181f2012-06-22 13:52:12 -0700642{
643 greenland::IntrinsicHelper::IntrinsicId id;
644 id = greenland::IntrinsicHelper::NewInstance;
buzbeefa57c472012-11-21 12:06:18 -0800645 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
646 llvm::Value* index = cu->irb->getInt32(type_idx);
647 llvm::Value* res = cu->irb->CreateCall(intr, index);
648 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee4f1181f2012-06-22 13:52:12 -0700649}
650
buzbeefa57c472012-11-21 12:06:18 -0800651static void ConvertNewArray(CompilationUnit* cu, uint32_t type_idx,
652 RegLocation rl_dest, RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700653{
654 greenland::IntrinsicHelper::IntrinsicId id;
655 id = greenland::IntrinsicHelper::NewArray;
buzbeefa57c472012-11-21 12:06:18 -0800656 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700657 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800658 args.push_back(cu->irb->getInt32(type_idx));
659 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
660 llvm::Value* res = cu->irb->CreateCall(intr, args);
661 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700662}
663
buzbeefa57c472012-11-21 12:06:18 -0800664static void ConvertAget(CompilationUnit* cu, int opt_flags,
buzbeeaad94382012-11-21 07:40:50 -0800665 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800666 RegLocation rl_dest, RegLocation rl_array, RegLocation rl_index)
buzbee8fa0fda2012-06-27 15:44:52 -0700667{
668 llvm::SmallVector<llvm::Value*, 3> args;
buzbeefa57c472012-11-21 12:06:18 -0800669 args.push_back(cu->irb->getInt32(opt_flags));
670 args.push_back(GetLLVMValue(cu, rl_array.orig_sreg));
671 args.push_back(GetLLVMValue(cu, rl_index.orig_sreg));
672 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
673 llvm::Value* res = cu->irb->CreateCall(intr, args);
674 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700675}
676
buzbeefa57c472012-11-21 12:06:18 -0800677static void ConvertAput(CompilationUnit* cu, int opt_flags,
buzbeeaad94382012-11-21 07:40:50 -0800678 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800679 RegLocation rl_src, RegLocation rl_array, RegLocation rl_index)
buzbee8fa0fda2012-06-27 15:44:52 -0700680{
681 llvm::SmallVector<llvm::Value*, 4> args;
buzbeefa57c472012-11-21 12:06:18 -0800682 args.push_back(cu->irb->getInt32(opt_flags));
683 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
684 args.push_back(GetLLVMValue(cu, rl_array.orig_sreg));
685 args.push_back(GetLLVMValue(cu, rl_index.orig_sreg));
686 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
687 cu->irb->CreateCall(intr, args);
buzbee8fa0fda2012-06-27 15:44:52 -0700688}
689
buzbeefa57c472012-11-21 12:06:18 -0800690static void ConvertIget(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_obj, int field_index)
buzbee101305f2012-06-28 18:00:56 -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_obj.orig_sreg));
697 args.push_back(cu->irb->getInt32(field_index));
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);
buzbee101305f2012-06-28 18:00:56 -0700701}
702
buzbeefa57c472012-11-21 12:06:18 -0800703static void ConvertIput(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_obj, int field_index)
buzbee101305f2012-06-28 18:00:56 -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_obj.orig_sreg));
711 args.push_back(cu->irb->getInt32(field_index));
712 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
713 cu->irb->CreateCall(intr, args);
buzbee101305f2012-06-28 18:00:56 -0700714}
715
buzbeefa57c472012-11-21 12:06:18 -0800716static void ConvertInstanceOf(CompilationUnit* cu, uint32_t type_idx,
717 RegLocation rl_dest, RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700718{
719 greenland::IntrinsicHelper::IntrinsicId id;
720 id = greenland::IntrinsicHelper::InstanceOf;
buzbeefa57c472012-11-21 12:06:18 -0800721 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700722 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800723 args.push_back(cu->irb->getInt32(type_idx));
724 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
725 llvm::Value* res = cu->irb->CreateCall(intr, args);
726 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700727}
728
buzbeefa57c472012-11-21 12:06:18 -0800729static void ConvertIntToLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee101305f2012-06-28 18:00:56 -0700730{
buzbeefa57c472012-11-21 12:06:18 -0800731 llvm::Value* res = cu->irb->CreateSExt(GetLLVMValue(cu, rl_src.orig_sreg),
732 cu->irb->getInt64Ty());
733 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee101305f2012-06-28 18:00:56 -0700734}
735
buzbeefa57c472012-11-21 12:06:18 -0800736static void ConvertLongToInt(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700737{
buzbeefa57c472012-11-21 12:06:18 -0800738 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
739 llvm::Value* res = cu->irb->CreateTrunc(src, cu->irb->getInt32Ty());
740 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700741}
742
buzbeefa57c472012-11-21 12:06:18 -0800743static void ConvertFloatToDouble(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700744{
buzbeefa57c472012-11-21 12:06:18 -0800745 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
746 llvm::Value* res = cu->irb->CreateFPExt(src, cu->irb->getDoubleTy());
747 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700748}
749
buzbeefa57c472012-11-21 12:06:18 -0800750static void ConvertDoubleToFloat(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700751{
buzbeefa57c472012-11-21 12:06:18 -0800752 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
753 llvm::Value* res = cu->irb->CreateFPTrunc(src, cu->irb->getFloatTy());
754 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700755}
756
buzbeefa57c472012-11-21 12:06:18 -0800757static void ConvertWideComparison(CompilationUnit* cu,
buzbeeaad94382012-11-21 07:40:50 -0800758 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800759 RegLocation rl_dest, RegLocation rl_src1,
760 RegLocation rl_src2)
buzbee76592632012-06-29 15:18:35 -0700761{
buzbeefa57c472012-11-21 12:06:18 -0800762 DCHECK_EQ(rl_src1.fp, rl_src2.fp);
763 DCHECK_EQ(rl_src1.wide, rl_src2.wide);
764 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700765 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800766 args.push_back(GetLLVMValue(cu, rl_src1.orig_sreg));
767 args.push_back(GetLLVMValue(cu, rl_src2.orig_sreg));
768 llvm::Value* res = cu->irb->CreateCall(intr, args);
769 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700770}
771
buzbeefa57c472012-11-21 12:06:18 -0800772static void ConvertIntNarrowing(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src,
buzbeeaad94382012-11-21 07:40:50 -0800773 greenland::IntrinsicHelper::IntrinsicId id)
buzbee101305f2012-06-28 18:00:56 -0700774{
buzbeefa57c472012-11-21 12:06:18 -0800775 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700776 llvm::Value* res =
buzbeefa57c472012-11-21 12:06:18 -0800777 cu->irb->CreateCall(intr, GetLLVMValue(cu, rl_src.orig_sreg));
778 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700779}
780
buzbeefa57c472012-11-21 12:06:18 -0800781static void ConvertNeg(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700782{
buzbeefa57c472012-11-21 12:06:18 -0800783 llvm::Value* res = cu->irb->CreateNeg(GetLLVMValue(cu, rl_src.orig_sreg));
784 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700785}
786
buzbeefa57c472012-11-21 12:06:18 -0800787static void ConvertIntToFP(CompilationUnit* cu, llvm::Type* ty, RegLocation rl_dest,
788 RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700789{
790 llvm::Value* res =
buzbeefa57c472012-11-21 12:06:18 -0800791 cu->irb->CreateSIToFP(GetLLVMValue(cu, rl_src.orig_sreg), ty);
792 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700793}
794
buzbeefa57c472012-11-21 12:06:18 -0800795static void ConvertFPToInt(CompilationUnit* cu, greenland::IntrinsicHelper::IntrinsicId id,
796 RegLocation rl_dest,
797 RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700798{
buzbeefa57c472012-11-21 12:06:18 -0800799 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
800 llvm::Value* res = cu->irb->CreateCall(intr, GetLLVMValue(cu, rl_src.orig_sreg));
801 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700802}
803
804
buzbeefa57c472012-11-21 12:06:18 -0800805static void ConvertNegFP(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700806{
807 llvm::Value* res =
buzbeefa57c472012-11-21 12:06:18 -0800808 cu->irb->CreateFNeg(GetLLVMValue(cu, rl_src.orig_sreg));
809 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700810}
811
buzbeefa57c472012-11-21 12:06:18 -0800812static void ConvertNot(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700813{
buzbeefa57c472012-11-21 12:06:18 -0800814 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
815 llvm::Value* res = cu->irb->CreateXor(src, static_cast<uint64_t>(-1));
816 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee101305f2012-06-28 18:00:56 -0700817}
818
buzbee2cfc6392012-05-07 14:51:40 -0700819/*
820 * Target-independent code generation. Use only high-level
821 * load/store utilities here, or target-dependent genXX() handlers
822 * when necessary.
823 */
buzbeefa57c472012-11-21 12:06:18 -0800824static bool ConvertMIRNode(CompilationUnit* cu, MIR* mir, BasicBlock* bb,
825 llvm::BasicBlock* llvm_bb, LIR* label_list)
buzbee2cfc6392012-05-07 14:51:40 -0700826{
827 bool res = false; // Assume success
buzbeefa57c472012-11-21 12:06:18 -0800828 RegLocation rl_src[3];
buzbee02031b12012-11-23 09:41:35 -0800829 RegLocation rl_dest = GetBadLoc();
buzbee2cfc6392012-05-07 14:51:40 -0700830 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -0800831 int op_val = opcode;
buzbee6969d502012-06-15 16:40:31 -0700832 uint32_t vB = mir->dalvikInsn.vB;
833 uint32_t vC = mir->dalvikInsn.vC;
buzbeefa57c472012-11-21 12:06:18 -0800834 int opt_flags = mir->optimization_flags;
buzbee6969d502012-06-15 16:40:31 -0700835
buzbeefa57c472012-11-21 12:06:18 -0800836 if (cu->verbose) {
837 if (op_val < kMirOpFirst) {
838 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x" << std::hex << op_val;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700839 } else {
buzbeefa57c472012-11-21 12:06:18 -0800840 LOG(INFO) << extended_mir_op_names[op_val - kMirOpFirst] << " 0x" << std::hex << op_val;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700841 }
842 }
843
buzbee2cfc6392012-05-07 14:51:40 -0700844 /* Prep Src and Dest locations */
buzbeefa57c472012-11-21 12:06:18 -0800845 int next_sreg = 0;
846 int next_loc = 0;
847 int attrs = oat_data_flow_attributes[opcode];
buzbee02031b12012-11-23 09:41:35 -0800848 rl_src[0] = rl_src[1] = rl_src[2] = GetBadLoc();
buzbee2cfc6392012-05-07 14:51:40 -0700849 if (attrs & DF_UA) {
850 if (attrs & DF_A_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -0800851 rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
852 next_sreg+= 2;
buzbee2cfc6392012-05-07 14:51:40 -0700853 } else {
buzbeefa57c472012-11-21 12:06:18 -0800854 rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
855 next_sreg++;
buzbee2cfc6392012-05-07 14:51:40 -0700856 }
857 }
858 if (attrs & DF_UB) {
859 if (attrs & DF_B_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -0800860 rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
861 next_sreg+= 2;
buzbee2cfc6392012-05-07 14:51:40 -0700862 } else {
buzbeefa57c472012-11-21 12:06:18 -0800863 rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
864 next_sreg++;
buzbee2cfc6392012-05-07 14:51:40 -0700865 }
866 }
867 if (attrs & DF_UC) {
868 if (attrs & DF_C_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -0800869 rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700870 } else {
buzbeefa57c472012-11-21 12:06:18 -0800871 rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700872 }
873 }
874 if (attrs & DF_DA) {
875 if (attrs & DF_A_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -0800876 rl_dest = GetDestWide(cu, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700877 } else {
buzbeefa57c472012-11-21 12:06:18 -0800878 rl_dest = GetDest(cu, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700879 }
880 }
881
882 switch (opcode) {
883 case Instruction::NOP:
884 break;
885
886 case Instruction::MOVE:
887 case Instruction::MOVE_OBJECT:
888 case Instruction::MOVE_16:
889 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700890 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700891 case Instruction::MOVE_FROM16:
892 case Instruction::MOVE_WIDE:
893 case Instruction::MOVE_WIDE_16:
894 case Instruction::MOVE_WIDE_FROM16: {
895 /*
896 * Moves/copies are meaningless in pure SSA register form,
897 * but we need to preserve them for the conversion back into
898 * MIR (at least until we stop using the Dalvik register maps).
899 * Insert a dummy intrinsic copy call, which will be recognized
900 * by the quick path and removed by the portable path.
901 */
buzbeefa57c472012-11-21 12:06:18 -0800902 llvm::Value* src = GetLLVMValue(cu, rl_src[0].orig_sreg);
903 llvm::Value* res = EmitCopy(cu, src, rl_dest);
904 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700905 }
906 break;
907
908 case Instruction::CONST:
909 case Instruction::CONST_4:
910 case Instruction::CONST_16: {
buzbeefa57c472012-11-21 12:06:18 -0800911 llvm::Constant* imm_value = cu->irb->GetJInt(vB);
912 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
913 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700914 }
915 break;
916
917 case Instruction::CONST_WIDE_16:
918 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700919 // Sign extend to 64 bits
920 int64_t imm = static_cast<int32_t>(vB);
buzbeefa57c472012-11-21 12:06:18 -0800921 llvm::Constant* imm_value = cu->irb->GetJLong(imm);
922 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
923 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700924 }
925 break;
926
927 case Instruction::CONST_HIGH16: {
buzbeefa57c472012-11-21 12:06:18 -0800928 llvm::Constant* imm_value = cu->irb->GetJInt(vB << 16);
929 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
930 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700931 }
932 break;
933
934 case Instruction::CONST_WIDE: {
buzbeefa57c472012-11-21 12:06:18 -0800935 llvm::Constant* imm_value =
936 cu->irb->GetJLong(mir->dalvikInsn.vB_wide);
937 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
938 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee4f1181f2012-06-22 13:52:12 -0700939 }
940 break;
buzbee2cfc6392012-05-07 14:51:40 -0700941 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700942 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbeefa57c472012-11-21 12:06:18 -0800943 llvm::Constant* imm_value = cu->irb->GetJLong(imm);
944 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
945 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee4f1181f2012-06-22 13:52:12 -0700946 }
947 break;
948
buzbee8fa0fda2012-06-27 15:44:52 -0700949 case Instruction::SPUT_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -0800950 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputObject,
951 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700952 break;
953 case Instruction::SPUT:
buzbeefa57c472012-11-21 12:06:18 -0800954 if (rl_src[0].fp) {
955 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputFloat,
956 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700957 } else {
buzbeefa57c472012-11-21 12:06:18 -0800958 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSput, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700959 }
960 break;
961 case Instruction::SPUT_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -0800962 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputBoolean,
963 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700964 break;
965 case Instruction::SPUT_BYTE:
buzbeefa57c472012-11-21 12:06:18 -0800966 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputByte, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700967 break;
968 case Instruction::SPUT_CHAR:
buzbeefa57c472012-11-21 12:06:18 -0800969 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputChar, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700970 break;
971 case Instruction::SPUT_SHORT:
buzbeefa57c472012-11-21 12:06:18 -0800972 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputShort, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700973 break;
974 case Instruction::SPUT_WIDE:
buzbeefa57c472012-11-21 12:06:18 -0800975 if (rl_src[0].fp) {
976 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputDouble,
977 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700978 } else {
buzbeefa57c472012-11-21 12:06:18 -0800979 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputWide,
980 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700981 }
982 break;
983
984 case Instruction::SGET_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -0800985 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetObject, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -0700986 break;
987 case Instruction::SGET:
buzbeefa57c472012-11-21 12:06:18 -0800988 if (rl_dest.fp) {
989 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetFloat, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -0700990 } else {
buzbeefa57c472012-11-21 12:06:18 -0800991 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSget, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -0700992 }
993 break;
994 case Instruction::SGET_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -0800995 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetBoolean, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -0700996 break;
997 case Instruction::SGET_BYTE:
buzbeefa57c472012-11-21 12:06:18 -0800998 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetByte, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -0700999 break;
1000 case Instruction::SGET_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001001 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetChar, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001002 break;
1003 case Instruction::SGET_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001004 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetShort, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001005 break;
1006 case Instruction::SGET_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001007 if (rl_dest.fp) {
1008 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetDouble,
1009 rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001010 } else {
buzbeefa57c472012-11-21 12:06:18 -08001011 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetWide, rl_dest);
buzbee4f1181f2012-06-22 13:52:12 -07001012 }
1013 break;
buzbee2cfc6392012-05-07 14:51:40 -07001014
1015 case Instruction::RETURN_WIDE:
1016 case Instruction::RETURN:
1017 case Instruction::RETURN_OBJECT: {
buzbeefa57c472012-11-21 12:06:18 -08001018 if (!(cu->attrs & METHOD_IS_LEAF)) {
1019 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -07001020 }
buzbeefa57c472012-11-21 12:06:18 -08001021 EmitPopShadowFrame(cu);
1022 cu->irb->CreateRet(GetLLVMValue(cu, rl_src[0].orig_sreg));
1023 bb->has_return = true;
buzbee2cfc6392012-05-07 14:51:40 -07001024 }
1025 break;
1026
1027 case Instruction::RETURN_VOID: {
buzbeefa57c472012-11-21 12:06:18 -08001028 if (!(cu->attrs & METHOD_IS_LEAF)) {
1029 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -07001030 }
buzbeefa57c472012-11-21 12:06:18 -08001031 EmitPopShadowFrame(cu);
1032 cu->irb->CreateRetVoid();
1033 bb->has_return = true;
buzbee2cfc6392012-05-07 14:51:40 -07001034 }
1035 break;
1036
1037 case Instruction::IF_EQ:
buzbeefa57c472012-11-21 12:06:18 -08001038 ConvertCompareAndBranch(cu, bb, mir, kCondEq, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001039 break;
1040 case Instruction::IF_NE:
buzbeefa57c472012-11-21 12:06:18 -08001041 ConvertCompareAndBranch(cu, bb, mir, kCondNe, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001042 break;
1043 case Instruction::IF_LT:
buzbeefa57c472012-11-21 12:06:18 -08001044 ConvertCompareAndBranch(cu, bb, mir, kCondLt, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001045 break;
1046 case Instruction::IF_GE:
buzbeefa57c472012-11-21 12:06:18 -08001047 ConvertCompareAndBranch(cu, bb, mir, kCondGe, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001048 break;
1049 case Instruction::IF_GT:
buzbeefa57c472012-11-21 12:06:18 -08001050 ConvertCompareAndBranch(cu, bb, mir, kCondGt, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001051 break;
1052 case Instruction::IF_LE:
buzbeefa57c472012-11-21 12:06:18 -08001053 ConvertCompareAndBranch(cu, bb, mir, kCondLe, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001054 break;
1055 case Instruction::IF_EQZ:
buzbeefa57c472012-11-21 12:06:18 -08001056 ConvertCompareZeroAndBranch(cu, bb, mir, kCondEq, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001057 break;
1058 case Instruction::IF_NEZ:
buzbeefa57c472012-11-21 12:06:18 -08001059 ConvertCompareZeroAndBranch(cu, bb, mir, kCondNe, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001060 break;
1061 case Instruction::IF_LTZ:
buzbeefa57c472012-11-21 12:06:18 -08001062 ConvertCompareZeroAndBranch(cu, bb, mir, kCondLt, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001063 break;
1064 case Instruction::IF_GEZ:
buzbeefa57c472012-11-21 12:06:18 -08001065 ConvertCompareZeroAndBranch(cu, bb, mir, kCondGe, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001066 break;
1067 case Instruction::IF_GTZ:
buzbeefa57c472012-11-21 12:06:18 -08001068 ConvertCompareZeroAndBranch(cu, bb, mir, kCondGt, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001069 break;
1070 case Instruction::IF_LEZ:
buzbeefa57c472012-11-21 12:06:18 -08001071 ConvertCompareZeroAndBranch(cu, bb, mir, kCondLe, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001072 break;
1073
1074 case Instruction::GOTO:
1075 case Instruction::GOTO_16:
1076 case Instruction::GOTO_32: {
buzbeefa57c472012-11-21 12:06:18 -08001077 if (bb->taken->start_offset <= bb->start_offset) {
1078 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -07001079 }
buzbeefa57c472012-11-21 12:06:18 -08001080 cu->irb->CreateBr(GetLLVMBlock(cu, bb->taken->id));
buzbee2cfc6392012-05-07 14:51:40 -07001081 }
1082 break;
1083
1084 case Instruction::ADD_LONG:
1085 case Instruction::ADD_LONG_2ADDR:
1086 case Instruction::ADD_INT:
1087 case Instruction::ADD_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001088 ConvertArithOp(cu, kOpAdd, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001089 break;
1090 case Instruction::SUB_LONG:
1091 case Instruction::SUB_LONG_2ADDR:
1092 case Instruction::SUB_INT:
1093 case Instruction::SUB_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001094 ConvertArithOp(cu, kOpSub, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001095 break;
1096 case Instruction::MUL_LONG:
1097 case Instruction::MUL_LONG_2ADDR:
1098 case Instruction::MUL_INT:
1099 case Instruction::MUL_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001100 ConvertArithOp(cu, kOpMul, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001101 break;
1102 case Instruction::DIV_LONG:
1103 case Instruction::DIV_LONG_2ADDR:
1104 case Instruction::DIV_INT:
1105 case Instruction::DIV_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001106 ConvertArithOp(cu, kOpDiv, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001107 break;
1108 case Instruction::REM_LONG:
1109 case Instruction::REM_LONG_2ADDR:
1110 case Instruction::REM_INT:
1111 case Instruction::REM_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001112 ConvertArithOp(cu, kOpRem, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001113 break;
1114 case Instruction::AND_LONG:
1115 case Instruction::AND_LONG_2ADDR:
1116 case Instruction::AND_INT:
1117 case Instruction::AND_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001118 ConvertArithOp(cu, kOpAnd, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001119 break;
1120 case Instruction::OR_LONG:
1121 case Instruction::OR_LONG_2ADDR:
1122 case Instruction::OR_INT:
1123 case Instruction::OR_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001124 ConvertArithOp(cu, kOpOr, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001125 break;
1126 case Instruction::XOR_LONG:
1127 case Instruction::XOR_LONG_2ADDR:
1128 case Instruction::XOR_INT:
1129 case Instruction::XOR_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001130 ConvertArithOp(cu, kOpXor, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001131 break;
1132 case Instruction::SHL_LONG:
1133 case Instruction::SHL_LONG_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001134 ConvertShift(cu, greenland::IntrinsicHelper::SHLLong,
1135 rl_dest, rl_src[0], rl_src[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001136 break;
buzbee2cfc6392012-05-07 14:51:40 -07001137 case Instruction::SHL_INT:
1138 case Instruction::SHL_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001139 ConvertShift(cu, greenland::IntrinsicHelper::SHLInt,
1140 rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001141 break;
1142 case Instruction::SHR_LONG:
1143 case Instruction::SHR_LONG_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001144 ConvertShift(cu, greenland::IntrinsicHelper::SHRLong,
1145 rl_dest, rl_src[0], rl_src[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001146 break;
buzbee2cfc6392012-05-07 14:51:40 -07001147 case Instruction::SHR_INT:
1148 case Instruction::SHR_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001149 ConvertShift(cu, greenland::IntrinsicHelper::SHRInt,
1150 rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001151 break;
1152 case Instruction::USHR_LONG:
1153 case Instruction::USHR_LONG_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001154 ConvertShift(cu, greenland::IntrinsicHelper::USHRLong,
1155 rl_dest, rl_src[0], rl_src[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001156 break;
buzbee2cfc6392012-05-07 14:51:40 -07001157 case Instruction::USHR_INT:
1158 case Instruction::USHR_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001159 ConvertShift(cu, greenland::IntrinsicHelper::USHRInt,
1160 rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001161 break;
1162
1163 case Instruction::ADD_INT_LIT16:
1164 case Instruction::ADD_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001165 ConvertArithOpLit(cu, kOpAdd, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001166 break;
1167 case Instruction::RSUB_INT:
1168 case Instruction::RSUB_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001169 ConvertArithOpLit(cu, kOpRsub, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001170 break;
1171 case Instruction::MUL_INT_LIT16:
1172 case Instruction::MUL_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001173 ConvertArithOpLit(cu, kOpMul, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001174 break;
1175 case Instruction::DIV_INT_LIT16:
1176 case Instruction::DIV_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001177 ConvertArithOpLit(cu, kOpDiv, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001178 break;
1179 case Instruction::REM_INT_LIT16:
1180 case Instruction::REM_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001181 ConvertArithOpLit(cu, kOpRem, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001182 break;
1183 case Instruction::AND_INT_LIT16:
1184 case Instruction::AND_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001185 ConvertArithOpLit(cu, kOpAnd, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001186 break;
1187 case Instruction::OR_INT_LIT16:
1188 case Instruction::OR_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001189 ConvertArithOpLit(cu, kOpOr, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001190 break;
1191 case Instruction::XOR_INT_LIT16:
1192 case Instruction::XOR_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001193 ConvertArithOpLit(cu, kOpXor, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001194 break;
1195 case Instruction::SHL_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001196 ConvertShiftLit(cu, greenland::IntrinsicHelper::SHLInt,
1197 rl_dest, rl_src[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001198 break;
1199 case Instruction::SHR_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001200 ConvertShiftLit(cu, greenland::IntrinsicHelper::SHRInt,
1201 rl_dest, rl_src[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001202 break;
1203 case Instruction::USHR_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001204 ConvertShiftLit(cu, greenland::IntrinsicHelper::USHRInt,
1205 rl_dest, rl_src[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001206 break;
1207
1208 case Instruction::ADD_FLOAT:
1209 case Instruction::ADD_FLOAT_2ADDR:
1210 case Instruction::ADD_DOUBLE:
1211 case Instruction::ADD_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001212 ConvertFPArithOp(cu, kOpAdd, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001213 break;
1214
1215 case Instruction::SUB_FLOAT:
1216 case Instruction::SUB_FLOAT_2ADDR:
1217 case Instruction::SUB_DOUBLE:
1218 case Instruction::SUB_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001219 ConvertFPArithOp(cu, kOpSub, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001220 break;
1221
1222 case Instruction::MUL_FLOAT:
1223 case Instruction::MUL_FLOAT_2ADDR:
1224 case Instruction::MUL_DOUBLE:
1225 case Instruction::MUL_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001226 ConvertFPArithOp(cu, kOpMul, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001227 break;
1228
1229 case Instruction::DIV_FLOAT:
1230 case Instruction::DIV_FLOAT_2ADDR:
1231 case Instruction::DIV_DOUBLE:
1232 case Instruction::DIV_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001233 ConvertFPArithOp(cu, kOpDiv, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001234 break;
1235
1236 case Instruction::REM_FLOAT:
1237 case Instruction::REM_FLOAT_2ADDR:
1238 case Instruction::REM_DOUBLE:
1239 case Instruction::REM_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001240 ConvertFPArithOp(cu, kOpRem, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001241 break;
1242
buzbee6969d502012-06-15 16:40:31 -07001243 case Instruction::INVOKE_STATIC:
buzbeefa57c472012-11-21 12:06:18 -08001244 ConvertInvoke(cu, bb, mir, kStatic, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001245 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001246 break;
1247 case Instruction::INVOKE_STATIC_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001248 ConvertInvoke(cu, bb, mir, kStatic, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001249 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001250 break;
1251
1252 case Instruction::INVOKE_DIRECT:
buzbeefa57c472012-11-21 12:06:18 -08001253 ConvertInvoke(cu, bb, mir, kDirect, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001254 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001255 break;
1256 case Instruction::INVOKE_DIRECT_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001257 ConvertInvoke(cu, bb, mir, kDirect, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001258 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001259 break;
1260
1261 case Instruction::INVOKE_VIRTUAL:
buzbeefa57c472012-11-21 12:06:18 -08001262 ConvertInvoke(cu, bb, mir, kVirtual, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001263 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001264 break;
1265 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001266 ConvertInvoke(cu, bb, mir, kVirtual, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001267 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001268 break;
1269
1270 case Instruction::INVOKE_SUPER:
buzbeefa57c472012-11-21 12:06:18 -08001271 ConvertInvoke(cu, bb, mir, kSuper, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001272 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001273 break;
1274 case Instruction::INVOKE_SUPER_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001275 ConvertInvoke(cu, bb, mir, kSuper, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001276 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001277 break;
1278
1279 case Instruction::INVOKE_INTERFACE:
buzbeefa57c472012-11-21 12:06:18 -08001280 ConvertInvoke(cu, bb, mir, kInterface, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001281 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001282 break;
1283 case Instruction::INVOKE_INTERFACE_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001284 ConvertInvoke(cu, bb, mir, kInterface, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001285 false /* NewFilledArray */);
1286 break;
1287 case Instruction::FILLED_NEW_ARRAY:
buzbeefa57c472012-11-21 12:06:18 -08001288 ConvertInvoke(cu, bb, mir, kInterface, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001289 true /* NewFilledArray */);
1290 break;
1291 case Instruction::FILLED_NEW_ARRAY_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001292 ConvertInvoke(cu, bb, mir, kInterface, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001293 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001294 break;
1295
1296 case Instruction::CONST_STRING:
1297 case Instruction::CONST_STRING_JUMBO:
buzbeefa57c472012-11-21 12:06:18 -08001298 ConvertConstObject(cu, vB, greenland::IntrinsicHelper::ConstString,
1299 rl_dest);
buzbee101305f2012-06-28 18:00:56 -07001300 break;
1301
1302 case Instruction::CONST_CLASS:
buzbeefa57c472012-11-21 12:06:18 -08001303 ConvertConstObject(cu, vB, greenland::IntrinsicHelper::ConstClass,
1304 rl_dest);
buzbee101305f2012-06-28 18:00:56 -07001305 break;
1306
1307 case Instruction::CHECK_CAST:
buzbeefa57c472012-11-21 12:06:18 -08001308 ConvertCheckCast(cu, vB, rl_src[0]);
buzbee6969d502012-06-15 16:40:31 -07001309 break;
1310
buzbee4f1181f2012-06-22 13:52:12 -07001311 case Instruction::NEW_INSTANCE:
buzbeefa57c472012-11-21 12:06:18 -08001312 ConvertNewInstance(cu, vB, rl_dest);
buzbee4f1181f2012-06-22 13:52:12 -07001313 break;
1314
buzbee32412962012-06-26 16:27:56 -07001315 case Instruction::MOVE_EXCEPTION:
buzbeefa57c472012-11-21 12:06:18 -08001316 ConvertMoveException(cu, rl_dest);
buzbee32412962012-06-26 16:27:56 -07001317 break;
1318
1319 case Instruction::THROW:
buzbeefa57c472012-11-21 12:06:18 -08001320 ConvertThrow(cu, rl_src[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001321 /*
1322 * If this throw is standalone, terminate.
1323 * If it might rethrow, force termination
1324 * of the following block.
1325 */
buzbeefa57c472012-11-21 12:06:18 -08001326 if (bb->fall_through == NULL) {
1327 cu->irb->CreateUnreachable();
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001328 } else {
buzbeefa57c472012-11-21 12:06:18 -08001329 bb->fall_through->fall_through = NULL;
1330 bb->fall_through->taken = NULL;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001331 }
buzbee32412962012-06-26 16:27:56 -07001332 break;
1333
buzbee2cfc6392012-05-07 14:51:40 -07001334 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001335 case Instruction::MOVE_RESULT:
1336 case Instruction::MOVE_RESULT_OBJECT:
buzbee9a2487f2012-07-26 14:01:13 -07001337 /*
jeffhao9a4f0032012-08-30 16:17:40 -07001338 * All move_results should have been folded into the preceeding invoke.
buzbee9a2487f2012-07-26 14:01:13 -07001339 */
jeffhao9a4f0032012-08-30 16:17:40 -07001340 LOG(FATAL) << "Unexpected move_result";
buzbee2cfc6392012-05-07 14:51:40 -07001341 break;
1342
1343 case Instruction::MONITOR_ENTER:
buzbeefa57c472012-11-21 12:06:18 -08001344 ConvertMonitorEnterExit(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001345 greenland::IntrinsicHelper::MonitorEnter,
buzbeefa57c472012-11-21 12:06:18 -08001346 rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001347 break;
1348
1349 case Instruction::MONITOR_EXIT:
buzbeefa57c472012-11-21 12:06:18 -08001350 ConvertMonitorEnterExit(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001351 greenland::IntrinsicHelper::MonitorExit,
buzbeefa57c472012-11-21 12:06:18 -08001352 rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001353 break;
1354
1355 case Instruction::ARRAY_LENGTH:
buzbeefa57c472012-11-21 12:06:18 -08001356 ConvertArrayLength(cu, opt_flags, rl_dest, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001357 break;
1358
1359 case Instruction::NEW_ARRAY:
buzbeefa57c472012-11-21 12:06:18 -08001360 ConvertNewArray(cu, vC, rl_dest, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001361 break;
1362
1363 case Instruction::INSTANCE_OF:
buzbeefa57c472012-11-21 12:06:18 -08001364 ConvertInstanceOf(cu, vC, rl_dest, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001365 break;
1366
1367 case Instruction::AGET:
buzbeefa57c472012-11-21 12:06:18 -08001368 if (rl_dest.fp) {
1369 ConvertAget(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001370 greenland::IntrinsicHelper::HLArrayGetFloat,
buzbeefa57c472012-11-21 12:06:18 -08001371 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001372 } else {
buzbeefa57c472012-11-21 12:06:18 -08001373 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGet,
1374 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001375 }
1376 break;
1377 case Instruction::AGET_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -08001378 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetObject,
1379 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001380 break;
1381 case Instruction::AGET_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -08001382 ConvertAget(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001383 greenland::IntrinsicHelper::HLArrayGetBoolean,
buzbeefa57c472012-11-21 12:06:18 -08001384 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001385 break;
1386 case Instruction::AGET_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001387 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetByte,
1388 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001389 break;
1390 case Instruction::AGET_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001391 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetChar,
1392 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001393 break;
1394 case Instruction::AGET_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001395 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetShort,
1396 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001397 break;
1398 case Instruction::AGET_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001399 if (rl_dest.fp) {
1400 ConvertAget(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001401 greenland::IntrinsicHelper::HLArrayGetDouble,
buzbeefa57c472012-11-21 12:06:18 -08001402 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001403 } else {
buzbeefa57c472012-11-21 12:06:18 -08001404 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetWide,
1405 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001406 }
1407 break;
1408
1409 case Instruction::APUT:
buzbeefa57c472012-11-21 12:06:18 -08001410 if (rl_src[0].fp) {
1411 ConvertAput(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001412 greenland::IntrinsicHelper::HLArrayPutFloat,
buzbeefa57c472012-11-21 12:06:18 -08001413 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001414 } else {
buzbeefa57c472012-11-21 12:06:18 -08001415 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPut,
1416 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001417 }
1418 break;
1419 case Instruction::APUT_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -08001420 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutObject,
1421 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001422 break;
1423 case Instruction::APUT_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -08001424 ConvertAput(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001425 greenland::IntrinsicHelper::HLArrayPutBoolean,
buzbeefa57c472012-11-21 12:06:18 -08001426 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001427 break;
1428 case Instruction::APUT_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001429 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutByte,
1430 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001431 break;
1432 case Instruction::APUT_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001433 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutChar,
1434 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001435 break;
1436 case Instruction::APUT_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001437 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutShort,
1438 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001439 break;
1440 case Instruction::APUT_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001441 if (rl_src[0].fp) {
1442 ConvertAput(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001443 greenland::IntrinsicHelper::HLArrayPutDouble,
buzbeefa57c472012-11-21 12:06:18 -08001444 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001445 } else {
buzbeefa57c472012-11-21 12:06:18 -08001446 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutWide,
1447 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001448 }
1449 break;
1450
buzbee101305f2012-06-28 18:00:56 -07001451 case Instruction::IGET:
buzbeefa57c472012-11-21 12:06:18 -08001452 if (rl_dest.fp) {
1453 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetFloat,
1454 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001455 } else {
buzbeefa57c472012-11-21 12:06:18 -08001456 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGet,
1457 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001458 }
buzbee2cfc6392012-05-07 14:51:40 -07001459 break;
buzbee101305f2012-06-28 18:00:56 -07001460 case Instruction::IGET_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -08001461 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetObject,
1462 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001463 break;
1464 case Instruction::IGET_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -08001465 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetBoolean,
1466 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001467 break;
1468 case Instruction::IGET_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001469 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetByte,
1470 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001471 break;
1472 case Instruction::IGET_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001473 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetChar,
1474 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001475 break;
1476 case Instruction::IGET_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001477 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetShort,
1478 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001479 break;
1480 case Instruction::IGET_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001481 if (rl_dest.fp) {
1482 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetDouble,
1483 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001484 } else {
buzbeefa57c472012-11-21 12:06:18 -08001485 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetWide,
1486 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001487 }
1488 break;
1489 case Instruction::IPUT:
buzbeefa57c472012-11-21 12:06:18 -08001490 if (rl_src[0].fp) {
1491 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutFloat,
1492 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001493 } else {
buzbeefa57c472012-11-21 12:06:18 -08001494 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPut,
1495 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001496 }
1497 break;
1498 case Instruction::IPUT_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -08001499 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutObject,
1500 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001501 break;
1502 case Instruction::IPUT_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -08001503 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutBoolean,
1504 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001505 break;
1506 case Instruction::IPUT_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001507 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutByte,
1508 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001509 break;
1510 case Instruction::IPUT_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001511 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutChar,
1512 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001513 break;
1514 case Instruction::IPUT_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001515 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutShort,
1516 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001517 break;
1518 case Instruction::IPUT_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001519 if (rl_src[0].fp) {
1520 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutDouble,
1521 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001522 } else {
buzbeefa57c472012-11-21 12:06:18 -08001523 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutWide,
1524 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001525 }
buzbee2cfc6392012-05-07 14:51:40 -07001526 break;
1527
1528 case Instruction::FILL_ARRAY_DATA:
buzbeefa57c472012-11-21 12:06:18 -08001529 ConvertFillArrayData(cu, vB, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001530 break;
1531
buzbee76592632012-06-29 15:18:35 -07001532 case Instruction::LONG_TO_INT:
buzbeefa57c472012-11-21 12:06:18 -08001533 ConvertLongToInt(cu, rl_dest, rl_src[0]);
buzbee76592632012-06-29 15:18:35 -07001534 break;
1535
buzbee101305f2012-06-28 18:00:56 -07001536 case Instruction::INT_TO_LONG:
buzbeefa57c472012-11-21 12:06:18 -08001537 ConvertIntToLong(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001538 break;
1539
buzbee101305f2012-06-28 18:00:56 -07001540 case Instruction::INT_TO_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001541 ConvertIntNarrowing(cu, rl_dest, rl_src[0],
buzbee101305f2012-06-28 18:00:56 -07001542 greenland::IntrinsicHelper::IntToChar);
1543 break;
1544 case Instruction::INT_TO_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001545 ConvertIntNarrowing(cu, rl_dest, rl_src[0],
buzbee101305f2012-06-28 18:00:56 -07001546 greenland::IntrinsicHelper::IntToByte);
1547 break;
1548 case Instruction::INT_TO_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001549 ConvertIntNarrowing(cu, rl_dest, rl_src[0],
buzbee101305f2012-06-28 18:00:56 -07001550 greenland::IntrinsicHelper::IntToShort);
1551 break;
1552
buzbee76592632012-06-29 15:18:35 -07001553 case Instruction::INT_TO_FLOAT:
1554 case Instruction::LONG_TO_FLOAT:
buzbeefa57c472012-11-21 12:06:18 -08001555 ConvertIntToFP(cu, cu->irb->getFloatTy(), rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001556 break;
1557
buzbee76592632012-06-29 15:18:35 -07001558 case Instruction::INT_TO_DOUBLE:
1559 case Instruction::LONG_TO_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001560 ConvertIntToFP(cu, cu->irb->getDoubleTy(), rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001561 break;
1562
buzbee76592632012-06-29 15:18:35 -07001563 case Instruction::FLOAT_TO_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001564 ConvertFloatToDouble(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001565 break;
1566
buzbee76592632012-06-29 15:18:35 -07001567 case Instruction::DOUBLE_TO_FLOAT:
buzbeefa57c472012-11-21 12:06:18 -08001568 ConvertDoubleToFloat(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001569 break;
1570
1571 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001572 case Instruction::NEG_INT:
buzbeefa57c472012-11-21 12:06:18 -08001573 ConvertNeg(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001574 break;
1575
1576 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001577 case Instruction::NEG_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001578 ConvertNegFP(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001579 break;
1580
buzbee76592632012-06-29 15:18:35 -07001581 case Instruction::NOT_LONG:
1582 case Instruction::NOT_INT:
buzbeefa57c472012-11-21 12:06:18 -08001583 ConvertNot(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001584 break;
1585
buzbee2cfc6392012-05-07 14:51:40 -07001586 case Instruction::FLOAT_TO_INT:
buzbeefa57c472012-11-21 12:06:18 -08001587 ConvertFPToInt(cu, greenland::IntrinsicHelper::F2I, rl_dest, rl_src[0]);
TDYa1274ec8ccd2012-08-11 07:04:57 -07001588 break;
1589
buzbee2cfc6392012-05-07 14:51:40 -07001590 case Instruction::DOUBLE_TO_INT:
buzbeefa57c472012-11-21 12:06:18 -08001591 ConvertFPToInt(cu, greenland::IntrinsicHelper::D2I, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001592 break;
1593
buzbee76592632012-06-29 15:18:35 -07001594 case Instruction::FLOAT_TO_LONG:
buzbeefa57c472012-11-21 12:06:18 -08001595 ConvertFPToInt(cu, greenland::IntrinsicHelper::F2L, rl_dest, rl_src[0]);
TDYa1274ec8ccd2012-08-11 07:04:57 -07001596 break;
1597
buzbee76592632012-06-29 15:18:35 -07001598 case Instruction::DOUBLE_TO_LONG:
buzbeefa57c472012-11-21 12:06:18 -08001599 ConvertFPToInt(cu, greenland::IntrinsicHelper::D2L, rl_dest, rl_src[0]);
buzbee76592632012-06-29 15:18:35 -07001600 break;
1601
1602 case Instruction::CMPL_FLOAT:
buzbeefa57c472012-11-21 12:06:18 -08001603 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmplFloat,
1604 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001605 break;
1606 case Instruction::CMPG_FLOAT:
buzbeefa57c472012-11-21 12:06:18 -08001607 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmpgFloat,
1608 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001609 break;
1610 case Instruction::CMPL_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001611 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmplDouble,
1612 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001613 break;
1614 case Instruction::CMPG_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001615 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmpgDouble,
1616 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001617 break;
1618 case Instruction::CMP_LONG:
buzbeefa57c472012-11-21 12:06:18 -08001619 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmpLong,
1620 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001621 break;
1622
buzbee76592632012-06-29 15:18:35 -07001623 case Instruction::PACKED_SWITCH:
buzbeefa57c472012-11-21 12:06:18 -08001624 ConvertPackedSwitch(cu, bb, vB, rl_src[0]);
buzbee76592632012-06-29 15:18:35 -07001625 break;
1626
1627 case Instruction::SPARSE_SWITCH:
buzbeefa57c472012-11-21 12:06:18 -08001628 ConvertSparseSwitch(cu, bb, vB, rl_src[0]);
buzbee76592632012-06-29 15:18:35 -07001629 break;
buzbee2cfc6392012-05-07 14:51:40 -07001630
1631 default:
buzbee32412962012-06-26 16:27:56 -07001632 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001633 res = true;
1634 }
1635 return res;
1636}
1637
buzbeefa57c472012-11-21 12:06:18 -08001638static void SetDexOffset(CompilationUnit* cu, int32_t offset)
buzbee2cfc6392012-05-07 14:51:40 -07001639{
buzbeefa57c472012-11-21 12:06:18 -08001640 cu->current_dalvik_offset = offset;
1641 llvm::SmallVector<llvm::Value*, 1> array_ref;
1642 array_ref.push_back(cu->irb->getInt32(offset));
1643 llvm::MDNode* node = llvm::MDNode::get(*cu->context, array_ref);
1644 cu->irb->SetDexOffset(node);
buzbee2cfc6392012-05-07 14:51:40 -07001645}
1646
1647// Attach method info as metadata to special intrinsic
buzbeefa57c472012-11-21 12:06:18 -08001648static void SetMethodInfo(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -07001649{
1650 // We don't want dex offset on this
buzbeefa57c472012-11-21 12:06:18 -08001651 cu->irb->SetDexOffset(NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001652 greenland::IntrinsicHelper::IntrinsicId id;
1653 id = greenland::IntrinsicHelper::MethodInfo;
buzbeefa57c472012-11-21 12:06:18 -08001654 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
1655 llvm::Instruction* inst = cu->irb->CreateCall(intr);
1656 llvm::SmallVector<llvm::Value*, 2> reg_info;
1657 reg_info.push_back(cu->irb->getInt32(cu->num_ins));
1658 reg_info.push_back(cu->irb->getInt32(cu->num_regs));
1659 reg_info.push_back(cu->irb->getInt32(cu->num_outs));
1660 reg_info.push_back(cu->irb->getInt32(cu->num_compiler_temps));
1661 reg_info.push_back(cu->irb->getInt32(cu->num_ssa_regs));
1662 llvm::MDNode* reg_info_node = llvm::MDNode::get(*cu->context, reg_info);
1663 inst->setMetadata("RegInfo", reg_info_node);
1664 int promo_size = cu->num_dalvik_registers + cu->num_compiler_temps + 1;
buzbee2cfc6392012-05-07 14:51:40 -07001665 llvm::SmallVector<llvm::Value*, 50> pmap;
buzbeefa57c472012-11-21 12:06:18 -08001666 for (int i = 0; i < promo_size; i++) {
1667 PromotionMap* p = &cu->promotion_map[i];
1668 int32_t map_data = ((p->first_in_pair & 0xff) << 24) |
buzbee52a77fc2012-11-20 19:50:46 -08001669 ((p->FpReg & 0xff) << 16) |
buzbeefa57c472012-11-21 12:06:18 -08001670 ((p->core_reg & 0xff) << 8) |
1671 ((p->fp_location & 0xf) << 4) |
1672 (p->core_location & 0xf);
1673 pmap.push_back(cu->irb->getInt32(map_data));
buzbee2cfc6392012-05-07 14:51:40 -07001674 }
buzbeefa57c472012-11-21 12:06:18 -08001675 llvm::MDNode* map_node = llvm::MDNode::get(*cu->context, pmap);
1676 inst->setMetadata("PromotionMap", map_node);
1677 SetDexOffset(cu, cu->current_dalvik_offset);
buzbee2cfc6392012-05-07 14:51:40 -07001678}
1679
buzbee26f10ee2012-12-21 11:16:29 -08001680static void HandlePhiNodes(CompilationUnit* cu, BasicBlock* bb, llvm::BasicBlock* llvm_bb)
1681{
1682 SetDexOffset(cu, bb->start_offset);
1683 for (MIR* mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
1684 int opcode = mir->dalvikInsn.opcode;
1685 if (opcode < kMirOpFirst) {
1686 // Stop after first non-pseudo MIR op.
1687 continue;
1688 }
1689 if (opcode != kMirOpPhi) {
1690 // Skip other mir Pseudos.
1691 continue;
1692 }
1693 RegLocation rl_dest = cu->reg_location[mir->ssa_rep->defs[0]];
1694 /*
1695 * The Art compiler's Phi nodes only handle 32-bit operands,
1696 * representing wide values using a matched set of Phi nodes
1697 * for the lower and upper halves. In the llvm world, we only
1698 * want a single Phi for wides. Here we will simply discard
1699 * the Phi node representing the high word.
1700 */
1701 if (rl_dest.high_word) {
1702 continue; // No Phi node - handled via low word
1703 }
1704 int* incoming = reinterpret_cast<int*>(mir->dalvikInsn.vB);
1705 llvm::Type* phi_type =
1706 LlvmTypeFromLocRec(cu, rl_dest);
1707 llvm::PHINode* phi = cu->irb->CreatePHI(phi_type, mir->ssa_rep->num_uses);
1708 for (int i = 0; i < mir->ssa_rep->num_uses; i++) {
1709 RegLocation loc;
1710 // Don't check width here.
1711 loc = GetRawSrc(cu, mir, i);
1712 DCHECK_EQ(rl_dest.wide, loc.wide);
1713 DCHECK_EQ(rl_dest.wide & rl_dest.high_word, loc.wide & loc.high_word);
1714 DCHECK_EQ(rl_dest.fp, loc.fp);
1715 DCHECK_EQ(rl_dest.core, loc.core);
1716 DCHECK_EQ(rl_dest.ref, loc.ref);
1717 SafeMap<unsigned int, unsigned int>::iterator it;
1718 it = cu->block_id_map.find(incoming[i]);
1719 DCHECK(it != cu->block_id_map.end());
1720 DCHECK(GetLLVMValue(cu, loc.orig_sreg) != NULL);
1721 DCHECK(GetLLVMBlock(cu, it->second) != NULL);
1722 phi->addIncoming(GetLLVMValue(cu, loc.orig_sreg),
1723 GetLLVMBlock(cu, it->second));
1724 }
1725 DefineValueOnly(cu, phi, rl_dest.orig_sreg);
1726 }
1727}
1728
1729/* Extended MIR instructions like PHI */
1730static void ConvertExtendedMIR(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
1731 llvm::BasicBlock* llvm_bb)
1732{
1733
1734 switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) {
1735 case kMirOpPhi: {
1736 // The llvm Phi node already emitted - just DefineValue() here.
1737 RegLocation rl_dest = cu->reg_location[mir->ssa_rep->defs[0]];
1738 if (!rl_dest.high_word) {
1739 // Only consider low word of pairs.
1740 DCHECK(GetLLVMValue(cu, rl_dest.orig_sreg) != NULL);
1741 llvm::Value* phi = GetLLVMValue(cu, rl_dest.orig_sreg);
1742 if (1) SetVregOnValue(cu, phi, rl_dest.orig_sreg);
1743 }
1744 break;
1745 }
1746 case kMirOpCopy: {
1747 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1748 break;
1749 }
1750 case kMirOpNop:
1751 if ((mir == bb->last_mir_insn) && (bb->taken == NULL) &&
1752 (bb->fall_through == NULL)) {
1753 cu->irb->CreateUnreachable();
1754 }
1755 break;
1756
1757 // TODO: need GBC intrinsic to take advantage of fused operations
1758 case kMirOpFusedCmplFloat:
1759 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpFloat unsupported";
1760 break;
1761 case kMirOpFusedCmpgFloat:
1762 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmgFloat unsupported";
1763 break;
1764 case kMirOpFusedCmplDouble:
1765 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmplDouble unsupported";
1766 break;
1767 case kMirOpFusedCmpgDouble:
1768 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpgDouble unsupported";
1769 break;
1770 case kMirOpFusedCmpLong:
1771 UNIMPLEMENTED(FATAL) << "kMirOpLongCmpBranch unsupported";
1772 break;
1773 default:
1774 break;
1775 }
1776}
1777
buzbee2cfc6392012-05-07 14:51:40 -07001778/* Handle the content in each basic block */
buzbeefa57c472012-11-21 12:06:18 -08001779static bool BlockBitcodeConversion(CompilationUnit* cu, BasicBlock* bb)
buzbee2cfc6392012-05-07 14:51:40 -07001780{
buzbeefa57c472012-11-21 12:06:18 -08001781 if (bb->block_type == kDead) return false;
1782 llvm::BasicBlock* llvm_bb = GetLLVMBlock(cu, bb->id);
1783 if (llvm_bb == NULL) {
1784 CHECK(bb->block_type == kExitBlock);
buzbeef5f5a122012-09-21 13:57:36 -07001785 } else {
buzbeefa57c472012-11-21 12:06:18 -08001786 cu->irb->SetInsertPoint(llvm_bb);
1787 SetDexOffset(cu, bb->start_offset);
buzbeef5f5a122012-09-21 13:57:36 -07001788 }
buzbee2cfc6392012-05-07 14:51:40 -07001789
buzbeefa57c472012-11-21 12:06:18 -08001790 if (cu->verbose) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001791 LOG(INFO) << "................................";
1792 LOG(INFO) << "Block id " << bb->id;
buzbeefa57c472012-11-21 12:06:18 -08001793 if (llvm_bb != NULL) {
1794 LOG(INFO) << "label " << llvm_bb->getName().str().c_str();
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001795 } else {
buzbeefa57c472012-11-21 12:06:18 -08001796 LOG(INFO) << "llvm_bb is NULL";
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001797 }
1798 }
1799
buzbeefa57c472012-11-21 12:06:18 -08001800 if (bb->block_type == kEntryBlock) {
1801 SetMethodInfo(cu);
1802 bool *can_be_ref = static_cast<bool*>(NewMem(cu, sizeof(bool) * cu->num_dalvik_registers,
buzbeecbd6d442012-11-17 14:11:25 -08001803 true, kAllocMisc));
buzbeefa57c472012-11-21 12:06:18 -08001804 for (int i = 0; i < cu->num_ssa_regs; i++) {
1805 int v_reg = SRegToVReg(cu, i);
1806 if (v_reg > SSA_METHOD_BASEREG) {
1807 can_be_ref[SRegToVReg(cu, i)] |= cu->reg_location[i].ref;
buzbee6ec5e232012-09-20 15:50:03 -07001808 }
buzbeeb03f4872012-06-11 15:22:11 -07001809 }
buzbeefa57c472012-11-21 12:06:18 -08001810 for (int i = 0; i < cu->num_dalvik_registers; i++) {
1811 if (can_be_ref[i]) {
1812 cu->num_shadow_frame_entries++;
buzbeeb03f4872012-06-11 15:22:11 -07001813 }
1814 }
buzbeefa57c472012-11-21 12:06:18 -08001815 if (cu->num_shadow_frame_entries > 0) {
1816 cu->shadow_map = static_cast<int*>(NewMem(cu, sizeof(int) * cu->num_shadow_frame_entries,
buzbeecbd6d442012-11-17 14:11:25 -08001817 true, kAllocMisc));
buzbeefa57c472012-11-21 12:06:18 -08001818 for (int i = 0, j = 0; i < cu->num_dalvik_registers; i++) {
1819 if (can_be_ref[i]) {
1820 cu->shadow_map[j++] = i;
buzbeeb03f4872012-06-11 15:22:11 -07001821 }
1822 }
buzbeeb03f4872012-06-11 15:22:11 -07001823 }
Shih-wei Liao569daf12012-08-10 23:22:33 -07001824 greenland::IntrinsicHelper::IntrinsicId id =
1825 greenland::IntrinsicHelper::AllocaShadowFrame;
buzbeefa57c472012-11-21 12:06:18 -08001826 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id);
1827 llvm::Value* entries = cu->irb->getInt32(cu->num_shadow_frame_entries);
buzbeed8506212012-12-20 14:15:05 -08001828 cu->irb->CreateCall(func, entries);
buzbeefa57c472012-11-21 12:06:18 -08001829 } else if (bb->block_type == kExitBlock) {
buzbee2cfc6392012-05-07 14:51:40 -07001830 /*
1831 * Because of the differences between how MIR/LIR and llvm handle exit
1832 * blocks, we won't explicitly covert them. On the llvm-to-lir
1833 * path, it will need to be regenereated.
1834 */
1835 return false;
buzbeefa57c472012-11-21 12:06:18 -08001836 } else if (bb->block_type == kExceptionHandling) {
buzbee6969d502012-06-15 16:40:31 -07001837 /*
1838 * Because we're deferring null checking, delete the associated empty
1839 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001840 */
buzbeefa57c472012-11-21 12:06:18 -08001841 llvm_bb->eraseFromParent();
buzbee6969d502012-06-15 16:40:31 -07001842 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001843 }
1844
buzbee26f10ee2012-12-21 11:16:29 -08001845 HandlePhiNodes(cu, bb, llvm_bb);
1846
buzbee28c9a832012-11-21 15:39:13 -08001847 for (MIR* mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
buzbee2cfc6392012-05-07 14:51:40 -07001848
buzbeefa57c472012-11-21 12:06:18 -08001849 SetDexOffset(cu, mir->offset);
buzbee2cfc6392012-05-07 14:51:40 -07001850
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001851 int opcode = mir->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -08001852 Instruction::Format dalvik_format =
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001853 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001854
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001855 if (opcode == kMirOpCheck) {
1856 // Combine check and work halves of throwing instruction.
buzbeefa57c472012-11-21 12:06:18 -08001857 MIR* work_half = mir->meta.throw_insn;
1858 mir->dalvikInsn.opcode = work_half->dalvikInsn.opcode;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001859 opcode = mir->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -08001860 SSARepresentation* ssa_rep = work_half->ssa_rep;
1861 work_half->ssa_rep = mir->ssa_rep;
1862 mir->ssa_rep = ssa_rep;
buzbeea169e1d2012-12-05 14:26:44 -08001863 work_half->meta.original_opcode = work_half->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -08001864 work_half->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1865 if (bb->successor_block_list.block_list_type == kCatch) {
1866 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001867 greenland::IntrinsicHelper::CatchTargets);
buzbeefa57c472012-11-21 12:06:18 -08001868 llvm::Value* switch_key =
1869 cu->irb->CreateCall(intr, cu->irb->getInt32(mir->offset));
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001870 GrowableListIterator iter;
buzbeefa57c472012-11-21 12:06:18 -08001871 GrowableListIteratorInit(&bb->successor_block_list.blocks, &iter);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001872 // New basic block to use for work half
buzbeefa57c472012-11-21 12:06:18 -08001873 llvm::BasicBlock* work_bb =
1874 llvm::BasicBlock::Create(*cu->context, "", cu->func);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001875 llvm::SwitchInst* sw =
buzbeefa57c472012-11-21 12:06:18 -08001876 cu->irb->CreateSwitch(switch_key, work_bb,
1877 bb->successor_block_list.blocks.num_used);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001878 while (true) {
buzbeefa57c472012-11-21 12:06:18 -08001879 SuccessorBlockInfo *successor_block_info =
buzbee52a77fc2012-11-20 19:50:46 -08001880 reinterpret_cast<SuccessorBlockInfo*>(GrowableListIteratorNext(&iter));
buzbeefa57c472012-11-21 12:06:18 -08001881 if (successor_block_info == NULL) break;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001882 llvm::BasicBlock *target =
buzbeefa57c472012-11-21 12:06:18 -08001883 GetLLVMBlock(cu, successor_block_info->block->id);
1884 int type_index = successor_block_info->key;
1885 sw->addCase(cu->irb->getInt32(type_index), target);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001886 }
buzbeefa57c472012-11-21 12:06:18 -08001887 llvm_bb = work_bb;
1888 cu->irb->SetInsertPoint(llvm_bb);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001889 }
1890 }
1891
1892 if (opcode >= kMirOpFirst) {
buzbeefa57c472012-11-21 12:06:18 -08001893 ConvertExtendedMIR(cu, bb, mir, llvm_bb);
buzbee2cfc6392012-05-07 14:51:40 -07001894 continue;
1895 }
1896
buzbeefa57c472012-11-21 12:06:18 -08001897 bool not_handled = ConvertMIRNode(cu, mir, bb, llvm_bb,
1898 NULL /* label_list */);
1899 if (not_handled) {
1900 Instruction::Code dalvik_opcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001901 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001902 mir->offset, opcode,
buzbeefa57c472012-11-21 12:06:18 -08001903 Instruction::Name(dalvik_opcode),
1904 dalvik_format);
buzbee2cfc6392012-05-07 14:51:40 -07001905 }
1906 }
1907
buzbeefa57c472012-11-21 12:06:18 -08001908 if (bb->block_type == kEntryBlock) {
1909 cu->entryTarget_bb = GetLLVMBlock(cu, bb->fall_through->id);
1910 } else if ((bb->fall_through != NULL) && !bb->has_return) {
1911 cu->irb->CreateBr(GetLLVMBlock(cu, bb->fall_through->id));
buzbee2cfc6392012-05-07 14:51:40 -07001912 }
1913
1914 return false;
1915}
1916
buzbeefa57c472012-11-21 12:06:18 -08001917char RemapShorty(char shorty_type) {
buzbee4f4dfc72012-07-02 14:54:44 -07001918 /*
1919 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1920 * and longs/doubles are represented as a pair of registers. When sub-word
1921 * arguments (and method results) are passed, they are extended to Dalvik
1922 * virtual register containers. Because llvm is picky about type consistency,
1923 * we must either cast the "real" type to 32-bit container multiple Dalvik
1924 * register types, or always use the expanded values.
1925 * Here, we're doing the latter. We map the shorty signature to container
1926 * types (which is valid so long as we always do a real expansion of passed
1927 * arguments and field loads).
1928 */
buzbeefa57c472012-11-21 12:06:18 -08001929 switch(shorty_type) {
1930 case 'Z' : shorty_type = 'I'; break;
1931 case 'B' : shorty_type = 'I'; break;
1932 case 'S' : shorty_type = 'I'; break;
1933 case 'C' : shorty_type = 'I'; break;
buzbee4f4dfc72012-07-02 14:54:44 -07001934 default: break;
1935 }
buzbeefa57c472012-11-21 12:06:18 -08001936 return shorty_type;
buzbee4f4dfc72012-07-02 14:54:44 -07001937}
1938
buzbeefa57c472012-11-21 12:06:18 -08001939static llvm::FunctionType* GetFunctionType(CompilationUnit* cu) {
buzbee2cfc6392012-05-07 14:51:40 -07001940
1941 // Get return type
buzbeefa57c472012-11-21 12:06:18 -08001942 llvm::Type* ret_type = cu->irb->GetJType(RemapShorty(cu->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001943 greenland::kAccurate);
1944
1945 // Get argument type
1946 std::vector<llvm::Type*> args_type;
1947
1948 // method object
buzbeefa57c472012-11-21 12:06:18 -08001949 args_type.push_back(cu->irb->GetJMethodTy());
buzbee2cfc6392012-05-07 14:51:40 -07001950
1951 // Do we have a "this"?
buzbeefa57c472012-11-21 12:06:18 -08001952 if ((cu->access_flags & kAccStatic) == 0) {
1953 args_type.push_back(cu->irb->GetJObjectTy());
buzbee2cfc6392012-05-07 14:51:40 -07001954 }
1955
buzbeefa57c472012-11-21 12:06:18 -08001956 for (uint32_t i = 1; i < strlen(cu->shorty); ++i) {
1957 args_type.push_back(cu->irb->GetJType(RemapShorty(cu->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001958 greenland::kAccurate));
1959 }
1960
1961 return llvm::FunctionType::get(ret_type, args_type, false);
1962}
1963
buzbeefa57c472012-11-21 12:06:18 -08001964static bool CreateFunction(CompilationUnit* cu) {
1965 std::string func_name(PrettyMethod(cu->method_idx, *cu->dex_file,
buzbee2cfc6392012-05-07 14:51:40 -07001966 /* with_signature */ false));
buzbeefa57c472012-11-21 12:06:18 -08001967 llvm::FunctionType* func_type = GetFunctionType(cu);
buzbee2cfc6392012-05-07 14:51:40 -07001968
1969 if (func_type == NULL) {
1970 return false;
1971 }
1972
buzbeefa57c472012-11-21 12:06:18 -08001973 cu->func = llvm::Function::Create(func_type,
buzbee2cfc6392012-05-07 14:51:40 -07001974 llvm::Function::ExternalLinkage,
buzbeefa57c472012-11-21 12:06:18 -08001975 func_name, cu->module);
buzbee2cfc6392012-05-07 14:51:40 -07001976
buzbeefa57c472012-11-21 12:06:18 -08001977 llvm::Function::arg_iterator arg_iter(cu->func->arg_begin());
1978 llvm::Function::arg_iterator arg_end(cu->func->arg_end());
buzbee2cfc6392012-05-07 14:51:40 -07001979
1980 arg_iter->setName("method");
1981 ++arg_iter;
1982
buzbeefa57c472012-11-21 12:06:18 -08001983 int start_sreg = cu->num_regs;
buzbee2cfc6392012-05-07 14:51:40 -07001984
1985 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
buzbeefa57c472012-11-21 12:06:18 -08001986 arg_iter->setName(StringPrintf("v%i_0", start_sreg));
1987 start_sreg += cu->reg_location[start_sreg].wide ? 2 : 1;
buzbee2cfc6392012-05-07 14:51:40 -07001988 }
1989
1990 return true;
1991}
1992
buzbeefa57c472012-11-21 12:06:18 -08001993static bool CreateLLVMBasicBlock(CompilationUnit* cu, BasicBlock* bb)
buzbee2cfc6392012-05-07 14:51:40 -07001994{
1995 // Skip the exit block
buzbeefa57c472012-11-21 12:06:18 -08001996 if ((bb->block_type == kDead) ||(bb->block_type == kExitBlock)) {
1997 cu->id_to_block_map.Put(bb->id, NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001998 } else {
buzbeefa57c472012-11-21 12:06:18 -08001999 int offset = bb->start_offset;
2000 bool entry_block = (bb->block_type == kEntryBlock);
2001 llvm::BasicBlock* llvm_bb =
2002 llvm::BasicBlock::Create(*cu->context, entry_block ? "entry" :
2003 StringPrintf(kLabelFormat, bb->catch_entry ? kCatchBlock :
2004 kNormalBlock, offset, bb->id), cu->func);
2005 if (entry_block) {
2006 cu->entry_bb = llvm_bb;
2007 cu->placeholder_bb =
2008 llvm::BasicBlock::Create(*cu->context, "placeholder",
2009 cu->func);
buzbee2cfc6392012-05-07 14:51:40 -07002010 }
buzbeefa57c472012-11-21 12:06:18 -08002011 cu->id_to_block_map.Put(bb->id, llvm_bb);
buzbee2cfc6392012-05-07 14:51:40 -07002012 }
2013 return false;
2014}
2015
2016
2017/*
2018 * Convert MIR to LLVM_IR
2019 * o For each ssa name, create LLVM named value. Type these
2020 * appropriately, and ignore high half of wide and double operands.
2021 * o For each MIR basic block, create an LLVM basic block.
2022 * o Iterate through the MIR a basic block at a time, setting arguments
2023 * to recovered ssa name.
2024 */
buzbeefa57c472012-11-21 12:06:18 -08002025void MethodMIR2Bitcode(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -07002026{
buzbeefa57c472012-11-21 12:06:18 -08002027 InitIR(cu);
2028 CompilerInitGrowableList(cu, &cu->llvm_values, cu->num_ssa_regs);
buzbee2cfc6392012-05-07 14:51:40 -07002029
2030 // Create the function
buzbeefa57c472012-11-21 12:06:18 -08002031 CreateFunction(cu);
buzbee2cfc6392012-05-07 14:51:40 -07002032
2033 // Create an LLVM basic block for each MIR block in dfs preorder
buzbeefa57c472012-11-21 12:06:18 -08002034 DataFlowAnalysisDispatcher(cu, CreateLLVMBasicBlock,
2035 kPreOrderDFSTraversal, false /* is_iterative */);
buzbee2cfc6392012-05-07 14:51:40 -07002036 /*
2037 * Create an llvm named value for each MIR SSA name. Note: we'll use
2038 * placeholders for all non-argument values (because we haven't seen
2039 * the definition yet).
2040 */
buzbeefa57c472012-11-21 12:06:18 -08002041 cu->irb->SetInsertPoint(cu->placeholder_bb);
2042 llvm::Function::arg_iterator arg_iter(cu->func->arg_begin());
buzbee2cfc6392012-05-07 14:51:40 -07002043 arg_iter++; /* Skip path method */
buzbeefa57c472012-11-21 12:06:18 -08002044 for (int i = 0; i < cu->num_ssa_regs; i++) {
buzbee2cfc6392012-05-07 14:51:40 -07002045 llvm::Value* val;
buzbeefa57c472012-11-21 12:06:18 -08002046 RegLocation rl_temp = cu->reg_location[i];
2047 if ((SRegToVReg(cu, i) < 0) || rl_temp.high_word) {
2048 InsertGrowableList(cu, &cu->llvm_values, 0);
2049 } else if ((i < cu->num_regs) ||
2050 (i >= (cu->num_regs + cu->num_ins))) {
2051 llvm::Constant* imm_value = cu->reg_location[i].wide ?
2052 cu->irb->GetJLong(0) : cu->irb->GetJInt(0);
2053 val = EmitConst(cu, imm_value, cu->reg_location[i]);
2054 val->setName(LlvmSSAName(cu, i));
2055 InsertGrowableList(cu, &cu->llvm_values, reinterpret_cast<uintptr_t>(val));
buzbee2cfc6392012-05-07 14:51:40 -07002056 } else {
2057 // Recover previously-created argument values
buzbeefa57c472012-11-21 12:06:18 -08002058 llvm::Value* arg_val = arg_iter++;
2059 InsertGrowableList(cu, &cu->llvm_values, reinterpret_cast<uintptr_t>(arg_val));
buzbee2cfc6392012-05-07 14:51:40 -07002060 }
2061 }
buzbee2cfc6392012-05-07 14:51:40 -07002062
buzbeefa57c472012-11-21 12:06:18 -08002063 DataFlowAnalysisDispatcher(cu, BlockBitcodeConversion,
buzbee2cfc6392012-05-07 14:51:40 -07002064 kPreOrderDFSTraversal, false /* Iterative */);
2065
buzbee4be777b2012-07-12 14:38:18 -07002066 /*
2067 * In a few rare cases of verification failure, the verifier will
2068 * replace one or more Dalvik opcodes with the special
2069 * throw-verification-failure opcode. This can leave the SSA graph
2070 * in an invalid state, as definitions may be lost, while uses retained.
2071 * To work around this problem, we insert placeholder definitions for
2072 * all Dalvik SSA regs in the "placeholder" block. Here, after
2073 * bitcode conversion is complete, we examine those placeholder definitions
2074 * and delete any with no references (which normally is all of them).
2075 *
2076 * If any definitions remain, we link the placeholder block into the
2077 * CFG. Otherwise, it is deleted.
2078 */
buzbeefa57c472012-11-21 12:06:18 -08002079 for (llvm::BasicBlock::iterator it = cu->placeholder_bb->begin(),
2080 it_end = cu->placeholder_bb->end(); it != it_end;) {
buzbee4be777b2012-07-12 14:38:18 -07002081 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2082 DCHECK(inst != NULL);
2083 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2084 DCHECK(val != NULL);
2085 if (val->getNumUses() == 0) {
2086 inst->eraseFromParent();
2087 }
2088 }
buzbeefa57c472012-11-21 12:06:18 -08002089 SetDexOffset(cu, 0);
2090 if (cu->placeholder_bb->empty()) {
2091 cu->placeholder_bb->eraseFromParent();
buzbee4be777b2012-07-12 14:38:18 -07002092 } else {
buzbeefa57c472012-11-21 12:06:18 -08002093 cu->irb->SetInsertPoint(cu->placeholder_bb);
2094 cu->irb->CreateBr(cu->entryTarget_bb);
2095 cu->entryTarget_bb = cu->placeholder_bb;
buzbee4be777b2012-07-12 14:38:18 -07002096 }
buzbeefa57c472012-11-21 12:06:18 -08002097 cu->irb->SetInsertPoint(cu->entry_bb);
2098 cu->irb->CreateBr(cu->entryTarget_bb);
buzbee2cfc6392012-05-07 14:51:40 -07002099
buzbeefa57c472012-11-21 12:06:18 -08002100 if (cu->enable_debug & (1 << kDebugVerifyBitcode)) {
2101 if (llvm::verifyFunction(*cu->func, llvm::PrintMessageAction)) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002102 LOG(INFO) << "Bitcode verification FAILED for "
buzbeefa57c472012-11-21 12:06:18 -08002103 << PrettyMethod(cu->method_idx, *cu->dex_file)
2104 << " of size " << cu->insns_size;
2105 cu->enable_debug |= (1 << kDebugDumpBitcodeFile);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002106 }
2107 }
buzbee2cfc6392012-05-07 14:51:40 -07002108
buzbeefa57c472012-11-21 12:06:18 -08002109 if (cu->enable_debug & (1 << kDebugDumpBitcodeFile)) {
buzbeead8f15e2012-06-18 14:49:45 -07002110 // Write bitcode to file
2111 std::string errmsg;
buzbeefa57c472012-11-21 12:06:18 -08002112 std::string fname(PrettyMethod(cu->method_idx, *cu->dex_file));
buzbee52a77fc2012-11-20 19:50:46 -08002113 ReplaceSpecialChars(fname);
buzbee6459e7c2012-10-02 14:42:41 -07002114 // TODO: make configurable change naming mechanism to avoid fname length issues.
buzbee4f1181f2012-06-22 13:52:12 -07002115 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002116
buzbee6459e7c2012-10-02 14:42:41 -07002117 if (fname.size() > 240) {
2118 LOG(INFO) << "Warning: bitcode filename too long. Truncated.";
2119 fname.resize(240);
2120 }
2121
buzbeead8f15e2012-06-18 14:49:45 -07002122 llvm::OwningPtr<llvm::tool_output_file> out_file(
2123 new llvm::tool_output_file(fname.c_str(), errmsg,
2124 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002125
buzbeead8f15e2012-06-18 14:49:45 -07002126 if (!errmsg.empty()) {
2127 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2128 }
2129
buzbeefa57c472012-11-21 12:06:18 -08002130 llvm::WriteBitcodeToFile(cu->module, out_file->os());
buzbeead8f15e2012-06-18 14:49:45 -07002131 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002132 }
buzbee2cfc6392012-05-07 14:51:40 -07002133}
2134
buzbeefa57c472012-11-21 12:06:18 -08002135static RegLocation GetLoc(CompilationUnit* cu, llvm::Value* val) {
buzbee2cfc6392012-05-07 14:51:40 -07002136 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002137 DCHECK(val != NULL);
buzbeefa57c472012-11-21 12:06:18 -08002138 SafeMap<llvm::Value*, RegLocation>::iterator it = cu->loc_map.find(val);
2139 if (it == cu->loc_map.end()) {
2140 std::string val_name = val->getName().str();
2141 if (val_name.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002142 // FIXME: need to be more robust, handle FP and be in a position to
2143 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002144 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2145 memset(&res, 0, sizeof(res));
2146 res.location = kLocPhysReg;
buzbeefa57c472012-11-21 12:06:18 -08002147 res.low_reg = AllocTemp(cu);
buzbee4f1181f2012-06-22 13:52:12 -07002148 res.home = true;
buzbeefa57c472012-11-21 12:06:18 -08002149 res.s_reg_low = INVALID_SREG;
2150 res.orig_sreg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002151 llvm::Type* ty = val->getType();
buzbeefa57c472012-11-21 12:06:18 -08002152 res.wide = ((ty == cu->irb->getInt64Ty()) ||
2153 (ty == cu->irb->getDoubleTy()));
buzbee101305f2012-06-28 18:00:56 -07002154 if (res.wide) {
buzbeefa57c472012-11-21 12:06:18 -08002155 res.high_reg = AllocTemp(cu);
buzbee101305f2012-06-28 18:00:56 -07002156 }
buzbeefa57c472012-11-21 12:06:18 -08002157 cu->loc_map.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002158 } else {
buzbeefa57c472012-11-21 12:06:18 -08002159 DCHECK_EQ(val_name[0], 'v');
2160 int base_sreg = INVALID_SREG;
2161 sscanf(val_name.c_str(), "v%d_", &base_sreg);
2162 res = cu->reg_location[base_sreg];
2163 cu->loc_map.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002164 }
2165 } else {
2166 res = it->second;
2167 }
2168 return res;
2169}
2170
buzbeefa57c472012-11-21 12:06:18 -08002171static Instruction::Code GetDalvikOpcode(OpKind op, bool is_const, bool is_wide)
buzbee2cfc6392012-05-07 14:51:40 -07002172{
2173 Instruction::Code res = Instruction::NOP;
buzbeefa57c472012-11-21 12:06:18 -08002174 if (is_wide) {
buzbee2cfc6392012-05-07 14:51:40 -07002175 switch(op) {
2176 case kOpAdd: res = Instruction::ADD_LONG; break;
2177 case kOpSub: res = Instruction::SUB_LONG; break;
2178 case kOpMul: res = Instruction::MUL_LONG; break;
2179 case kOpDiv: res = Instruction::DIV_LONG; break;
2180 case kOpRem: res = Instruction::REM_LONG; break;
2181 case kOpAnd: res = Instruction::AND_LONG; break;
2182 case kOpOr: res = Instruction::OR_LONG; break;
2183 case kOpXor: res = Instruction::XOR_LONG; break;
2184 case kOpLsl: res = Instruction::SHL_LONG; break;
2185 case kOpLsr: res = Instruction::USHR_LONG; break;
2186 case kOpAsr: res = Instruction::SHR_LONG; break;
2187 default: LOG(FATAL) << "Unexpected OpKind " << op;
2188 }
buzbeefa57c472012-11-21 12:06:18 -08002189 } else if (is_const){
buzbee2cfc6392012-05-07 14:51:40 -07002190 switch(op) {
2191 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2192 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2193 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2194 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2195 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2196 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2197 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2198 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2199 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2200 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2201 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2202 default: LOG(FATAL) << "Unexpected OpKind " << op;
2203 }
2204 } else {
2205 switch(op) {
2206 case kOpAdd: res = Instruction::ADD_INT; break;
2207 case kOpSub: res = Instruction::SUB_INT; break;
2208 case kOpMul: res = Instruction::MUL_INT; break;
2209 case kOpDiv: res = Instruction::DIV_INT; break;
2210 case kOpRem: res = Instruction::REM_INT; break;
2211 case kOpAnd: res = Instruction::AND_INT; break;
2212 case kOpOr: res = Instruction::OR_INT; break;
2213 case kOpXor: res = Instruction::XOR_INT; break;
2214 case kOpLsl: res = Instruction::SHL_INT; break;
2215 case kOpLsr: res = Instruction::USHR_INT; break;
2216 case kOpAsr: res = Instruction::SHR_INT; break;
2217 default: LOG(FATAL) << "Unexpected OpKind " << op;
2218 }
2219 }
2220 return res;
2221}
2222
buzbeefa57c472012-11-21 12:06:18 -08002223static Instruction::Code GetDalvikFPOpcode(OpKind op, bool is_const, bool is_wide)
buzbee4f1181f2012-06-22 13:52:12 -07002224{
2225 Instruction::Code res = Instruction::NOP;
buzbeefa57c472012-11-21 12:06:18 -08002226 if (is_wide) {
buzbee4f1181f2012-06-22 13:52:12 -07002227 switch(op) {
2228 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2229 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2230 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2231 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2232 case kOpRem: res = Instruction::REM_DOUBLE; break;
2233 default: LOG(FATAL) << "Unexpected OpKind " << op;
2234 }
2235 } else {
2236 switch(op) {
2237 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2238 case kOpSub: res = Instruction::SUB_FLOAT; break;
2239 case kOpMul: res = Instruction::MUL_FLOAT; break;
2240 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2241 case kOpRem: res = Instruction::REM_FLOAT; break;
2242 default: LOG(FATAL) << "Unexpected OpKind " << op;
2243 }
2244 }
2245 return res;
2246}
2247
buzbeefa57c472012-11-21 12:06:18 -08002248static void CvtBinFPOp(CompilationUnit* cu, OpKind op, llvm::Instruction* inst)
buzbee4f1181f2012-06-22 13:52:12 -07002249{
buzbee02031b12012-11-23 09:41:35 -08002250 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002251 RegLocation rl_dest = GetLoc(cu, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002252 /*
2253 * Normally, we won't ever generate an FP operation with an immediate
2254 * operand (not supported in Dex instruction set). However, the IR builder
buzbeefa57c472012-11-21 12:06:18 -08002255 * may insert them - in particular for create_neg_fp. Recognize this case
buzbee4f4dfc72012-07-02 14:54:44 -07002256 * and deal with it.
2257 */
2258 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2259 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2260 DCHECK(op2C == NULL);
2261 if ((op1C != NULL) && (op == kOpSub)) {
buzbeefa57c472012-11-21 12:06:18 -08002262 RegLocation rl_src = GetLoc(cu, inst->getOperand(1));
2263 if (rl_dest.wide) {
buzbee02031b12012-11-23 09:41:35 -08002264 cg->GenArithOpDouble(cu, Instruction::NEG_DOUBLE, rl_dest, rl_src, rl_src);
buzbee4f4dfc72012-07-02 14:54:44 -07002265 } else {
buzbee02031b12012-11-23 09:41:35 -08002266 cg->GenArithOpFloat(cu, Instruction::NEG_FLOAT, rl_dest, rl_src, rl_src);
buzbee4f4dfc72012-07-02 14:54:44 -07002267 }
buzbee4f1181f2012-06-22 13:52:12 -07002268 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002269 DCHECK(op1C == NULL);
buzbeefa57c472012-11-21 12:06:18 -08002270 RegLocation rl_src1 = GetLoc(cu, inst->getOperand(0));
2271 RegLocation rl_src2 = GetLoc(cu, inst->getOperand(1));
2272 Instruction::Code dalvik_op = GetDalvikFPOpcode(op, false, rl_dest.wide);
2273 if (rl_dest.wide) {
buzbee02031b12012-11-23 09:41:35 -08002274 cg->GenArithOpDouble(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
buzbee4f4dfc72012-07-02 14:54:44 -07002275 } else {
buzbee02031b12012-11-23 09:41:35 -08002276 cg->GenArithOpFloat(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
buzbee4f4dfc72012-07-02 14:54:44 -07002277 }
buzbee4f1181f2012-06-22 13:52:12 -07002278 }
2279}
2280
buzbeefa57c472012-11-21 12:06:18 -08002281static void CvtIntNarrowing(CompilationUnit* cu, llvm::Instruction* inst,
buzbee101305f2012-06-28 18:00:56 -07002282 Instruction::Code opcode)
2283{
buzbee02031b12012-11-23 09:41:35 -08002284 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002285 RegLocation rl_dest = GetLoc(cu, inst);
2286 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
buzbee02031b12012-11-23 09:41:35 -08002287 cg->GenIntNarrowing(cu, opcode, rl_dest, rl_src);
buzbee101305f2012-06-28 18:00:56 -07002288}
2289
buzbeefa57c472012-11-21 12:06:18 -08002290static void CvtIntToFP(CompilationUnit* cu, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002291{
buzbee02031b12012-11-23 09:41:35 -08002292 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002293 RegLocation rl_dest = GetLoc(cu, inst);
2294 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002295 Instruction::Code opcode;
buzbeefa57c472012-11-21 12:06:18 -08002296 if (rl_dest.wide) {
2297 if (rl_src.wide) {
buzbee76592632012-06-29 15:18:35 -07002298 opcode = Instruction::LONG_TO_DOUBLE;
2299 } else {
2300 opcode = Instruction::INT_TO_DOUBLE;
2301 }
2302 } else {
buzbeefa57c472012-11-21 12:06:18 -08002303 if (rl_src.wide) {
buzbee76592632012-06-29 15:18:35 -07002304 opcode = Instruction::LONG_TO_FLOAT;
2305 } else {
2306 opcode = Instruction::INT_TO_FLOAT;
2307 }
2308 }
buzbee02031b12012-11-23 09:41:35 -08002309 cg->GenConversion(cu, opcode, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002310}
2311
buzbeefa57c472012-11-21 12:06:18 -08002312static void CvtFPToInt(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002313{
buzbee02031b12012-11-23 09:41:35 -08002314 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002315 RegLocation rl_dest = GetLoc(cu, call_inst);
2316 RegLocation rl_src = GetLoc(cu, call_inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002317 Instruction::Code opcode;
buzbeefa57c472012-11-21 12:06:18 -08002318 if (rl_dest.wide) {
2319 if (rl_src.wide) {
buzbee76592632012-06-29 15:18:35 -07002320 opcode = Instruction::DOUBLE_TO_LONG;
2321 } else {
2322 opcode = Instruction::FLOAT_TO_LONG;
2323 }
2324 } else {
buzbeefa57c472012-11-21 12:06:18 -08002325 if (rl_src.wide) {
buzbee76592632012-06-29 15:18:35 -07002326 opcode = Instruction::DOUBLE_TO_INT;
2327 } else {
2328 opcode = Instruction::FLOAT_TO_INT;
2329 }
2330 }
buzbee02031b12012-11-23 09:41:35 -08002331 cg->GenConversion(cu, opcode, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002332}
2333
buzbeefa57c472012-11-21 12:06:18 -08002334static void CvtFloatToDouble(CompilationUnit* cu, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002335{
buzbee02031b12012-11-23 09:41:35 -08002336 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002337 RegLocation rl_dest = GetLoc(cu, inst);
2338 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
buzbee02031b12012-11-23 09:41:35 -08002339 cg->GenConversion(cu, Instruction::FLOAT_TO_DOUBLE, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002340}
2341
buzbeefa57c472012-11-21 12:06:18 -08002342static void CvtTrunc(CompilationUnit* cu, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002343{
buzbee02031b12012-11-23 09:41:35 -08002344 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002345 RegLocation rl_dest = GetLoc(cu, inst);
2346 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
2347 rl_src = UpdateLocWide(cu, rl_src);
2348 rl_src = WideToNarrow(cu, rl_src);
buzbee02031b12012-11-23 09:41:35 -08002349 cg->StoreValue(cu, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002350}
2351
buzbeefa57c472012-11-21 12:06:18 -08002352static void CvtDoubleToFloat(CompilationUnit* cu, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002353{
buzbee02031b12012-11-23 09:41:35 -08002354 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002355 RegLocation rl_dest = GetLoc(cu, inst);
2356 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
buzbee02031b12012-11-23 09:41:35 -08002357 cg->GenConversion(cu, Instruction::DOUBLE_TO_FLOAT, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002358}
2359
2360
buzbeefa57c472012-11-21 12:06:18 -08002361static void CvtIntExt(CompilationUnit* cu, llvm::Instruction* inst, bool is_signed)
buzbee101305f2012-06-28 18:00:56 -07002362{
buzbee02031b12012-11-23 09:41:35 -08002363 Codegen* cg = cu->cg.get();
buzbee101305f2012-06-28 18:00:56 -07002364 // TODO: evaluate src/tgt types and add general support for more than int to long
buzbeefa57c472012-11-21 12:06:18 -08002365 RegLocation rl_dest = GetLoc(cu, inst);
2366 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
2367 DCHECK(rl_dest.wide);
2368 DCHECK(!rl_src.wide);
2369 DCHECK(!rl_dest.fp);
2370 DCHECK(!rl_src.fp);
2371 RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
2372 if (rl_src.location == kLocPhysReg) {
buzbee02031b12012-11-23 09:41:35 -08002373 cg->OpRegCopy(cu, rl_result.low_reg, rl_src.low_reg);
buzbee101305f2012-06-28 18:00:56 -07002374 } else {
buzbee02031b12012-11-23 09:41:35 -08002375 cg->LoadValueDirect(cu, rl_src, rl_result.low_reg);
buzbee101305f2012-06-28 18:00:56 -07002376 }
buzbeefa57c472012-11-21 12:06:18 -08002377 if (is_signed) {
buzbee02031b12012-11-23 09:41:35 -08002378 cg->OpRegRegImm(cu, kOpAsr, rl_result.high_reg, rl_result.low_reg, 31);
buzbee101305f2012-06-28 18:00:56 -07002379 } else {
buzbee02031b12012-11-23 09:41:35 -08002380 cg->LoadConstant(cu, rl_result.high_reg, 0);
buzbee101305f2012-06-28 18:00:56 -07002381 }
buzbee02031b12012-11-23 09:41:35 -08002382 cg->StoreValueWide(cu, rl_dest, rl_result);
buzbee101305f2012-06-28 18:00:56 -07002383}
2384
buzbeefa57c472012-11-21 12:06:18 -08002385static void CvtBinOp(CompilationUnit* cu, OpKind op, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002386{
buzbee02031b12012-11-23 09:41:35 -08002387 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002388 RegLocation rl_dest = GetLoc(cu, inst);
buzbee2cfc6392012-05-07 14:51:40 -07002389 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002390 // Special-case RSUB/NEG
buzbeefa57c472012-11-21 12:06:18 -08002391 llvm::ConstantInt* lhs_imm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2392 if ((op == kOpSub) && (lhs_imm != NULL)) {
2393 RegLocation rl_src1 = GetLoc(cu, inst->getOperand(1));
2394 if (rl_src1.wide) {
2395 DCHECK_EQ(lhs_imm->getSExtValue(), 0);
buzbee02031b12012-11-23 09:41:35 -08002396 cg->GenArithOpLong(cu, Instruction::NEG_LONG, rl_dest, rl_src1, rl_src1);
buzbeef58c12c2012-07-03 15:06:29 -07002397 } else {
buzbee02031b12012-11-23 09:41:35 -08002398 cg->GenArithOpIntLit(cu, Instruction::RSUB_INT, rl_dest, rl_src1,
buzbeefa57c472012-11-21 12:06:18 -08002399 lhs_imm->getSExtValue());
buzbeef58c12c2012-07-03 15:06:29 -07002400 }
buzbee4f1181f2012-06-22 13:52:12 -07002401 return;
2402 }
buzbeefa57c472012-11-21 12:06:18 -08002403 DCHECK(lhs_imm == NULL);
2404 RegLocation rl_src1 = GetLoc(cu, inst->getOperand(0));
buzbee2cfc6392012-05-07 14:51:40 -07002405 llvm::Value* rhs = inst->getOperand(1);
buzbeefa57c472012-11-21 12:06:18 -08002406 llvm::ConstantInt* const_rhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2407 if (!rl_dest.wide && (const_rhs != NULL)) {
2408 Instruction::Code dalvik_op = GetDalvikOpcode(op, true, false);
buzbee02031b12012-11-23 09:41:35 -08002409 cg->GenArithOpIntLit(cu, dalvik_op, rl_dest, rl_src1, const_rhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002410 } else {
buzbeefa57c472012-11-21 12:06:18 -08002411 Instruction::Code dalvik_op = GetDalvikOpcode(op, false, rl_dest.wide);
2412 RegLocation rl_src2;
2413 if (const_rhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002414 // ir_builder converts NOT_LONG to xor src, -1. Restore
buzbeefa57c472012-11-21 12:06:18 -08002415 DCHECK_EQ(dalvik_op, Instruction::XOR_LONG);
2416 DCHECK_EQ(-1L, const_rhs->getSExtValue());
2417 dalvik_op = Instruction::NOT_LONG;
2418 rl_src2 = rl_src1;
buzbee9a2487f2012-07-26 14:01:13 -07002419 } else {
buzbeefa57c472012-11-21 12:06:18 -08002420 rl_src2 = GetLoc(cu, rhs);
buzbee9a2487f2012-07-26 14:01:13 -07002421 }
buzbeefa57c472012-11-21 12:06:18 -08002422 if (rl_dest.wide) {
buzbee02031b12012-11-23 09:41:35 -08002423 cg->GenArithOpLong(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
buzbee2cfc6392012-05-07 14:51:40 -07002424 } else {
buzbee02031b12012-11-23 09:41:35 -08002425 cg->GenArithOpInt(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
buzbee2cfc6392012-05-07 14:51:40 -07002426 }
2427 }
2428}
2429
buzbeefa57c472012-11-21 12:06:18 -08002430static void CvtShiftOp(CompilationUnit* cu, Instruction::Code opcode, llvm::CallInst* call_inst)
buzbee101305f2012-06-28 18:00:56 -07002431{
buzbee02031b12012-11-23 09:41:35 -08002432 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002433 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2434 RegLocation rl_dest = GetLoc(cu, call_inst);
2435 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(0));
2436 llvm::Value* rhs = call_inst->getArgOperand(1);
buzbee2a83e8f2012-07-13 16:42:30 -07002437 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
buzbeefa57c472012-11-21 12:06:18 -08002438 DCHECK(!rl_dest.wide);
buzbee02031b12012-11-23 09:41:35 -08002439 cg->GenArithOpIntLit(cu, opcode, rl_dest, rl_src, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002440 } else {
buzbeefa57c472012-11-21 12:06:18 -08002441 RegLocation rl_shift = GetLoc(cu, rhs);
2442 if (call_inst->getType() == cu->irb->getInt64Ty()) {
buzbee02031b12012-11-23 09:41:35 -08002443 cg->GenShiftOpLong(cu, opcode, rl_dest, rl_src, rl_shift);
buzbee2a83e8f2012-07-13 16:42:30 -07002444 } else {
buzbee02031b12012-11-23 09:41:35 -08002445 cg->GenArithOpInt(cu, opcode, rl_dest, rl_src, rl_shift);
buzbee2a83e8f2012-07-13 16:42:30 -07002446 }
buzbee101305f2012-06-28 18:00:56 -07002447 }
2448}
2449
buzbeefa57c472012-11-21 12:06:18 -08002450static void CvtBr(CompilationUnit* cu, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002451{
buzbee02031b12012-11-23 09:41:35 -08002452 Codegen* cg = cu->cg.get();
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);
buzbee02031b12012-11-23 09:41:35 -08002457 cg->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{
buzbee02031b12012-11-23 09:41:35 -08002467 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002468 llvm::ReturnInst* ret_inst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2469 llvm::Value* ret_val = ret_inst->getReturnValue();
2470 if (ret_val != NULL) {
2471 RegLocation rl_src = GetLoc(cu, ret_val);
2472 if (rl_src.wide) {
buzbee02031b12012-11-23 09:41:35 -08002473 cg->StoreValueWide(cu, GetReturnWide(cu, rl_src.fp), rl_src);
buzbee2cfc6392012-05-07 14:51:40 -07002474 } else {
buzbee02031b12012-11-23 09:41:35 -08002475 cg->StoreValue(cu, GetReturn(cu, rl_src.fp), rl_src);
buzbee2cfc6392012-05-07 14:51:40 -07002476 }
2477 }
buzbee02031b12012-11-23 09:41:35 -08002478 cg->GenExitSequence(cu);
buzbee2cfc6392012-05-07 14:51:40 -07002479}
2480
buzbeefa57c472012-11-21 12:06:18 -08002481static ConditionCode GetCond(llvm::ICmpInst::Predicate llvm_cond)
buzbee2cfc6392012-05-07 14:51:40 -07002482{
2483 ConditionCode res = kCondAl;
buzbeefa57c472012-11-21 12:06:18 -08002484 switch(llvm_cond) {
buzbee6969d502012-06-15 16:40:31 -07002485 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002486 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2487 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2488 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002489 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002490 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002491 default: LOG(FATAL) << "Unexpected llvm condition";
2492 }
2493 return res;
2494}
2495
buzbeefa57c472012-11-21 12:06:18 -08002496static void CvtICmp(CompilationUnit* cu, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002497{
buzbee02031b12012-11-23 09:41:35 -08002498 // cg->GenCmpLong(cu, rl_dest, rl_src1, rl_src2)
buzbee2cfc6392012-05-07 14:51:40 -07002499 UNIMPLEMENTED(FATAL);
2500}
2501
buzbeefa57c472012-11-21 12:06:18 -08002502static void CvtICmpBr(CompilationUnit* cu, llvm::Instruction* inst,
2503 llvm::BranchInst* br_inst)
buzbee2cfc6392012-05-07 14:51:40 -07002504{
buzbee02031b12012-11-23 09:41:35 -08002505 Codegen* cg = cu->cg.get();
buzbee2cfc6392012-05-07 14:51:40 -07002506 // Get targets
buzbeefa57c472012-11-21 12:06:18 -08002507 llvm::BasicBlock* taken_bb = br_inst->getSuccessor(0);
2508 LIR* taken = cu->block_to_label_map.Get(taken_bb);
2509 llvm::BasicBlock* fallthrough_bb = br_inst->getSuccessor(1);
2510 LIR* fall_through = cu->block_to_label_map.Get(fallthrough_bb);
buzbee2cfc6392012-05-07 14:51:40 -07002511 // Get comparison operands
buzbeefa57c472012-11-21 12:06:18 -08002512 llvm::ICmpInst* i_cmp_inst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2513 ConditionCode cond = GetCond(i_cmp_inst->getPredicate());
2514 llvm::Value* lhs = i_cmp_inst->getOperand(0);
buzbee2cfc6392012-05-07 14:51:40 -07002515 // Not expecting a constant as 1st operand
2516 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
buzbeefa57c472012-11-21 12:06:18 -08002517 RegLocation rl_src1 = GetLoc(cu, inst->getOperand(0));
buzbee02031b12012-11-23 09:41:35 -08002518 rl_src1 = cg->LoadValue(cu, rl_src1, kCoreReg);
buzbee2cfc6392012-05-07 14:51:40 -07002519 llvm::Value* rhs = inst->getOperand(1);
buzbeefa57c472012-11-21 12:06:18 -08002520 if (cu->instruction_set == kMips) {
buzbeeb046e162012-10-30 15:48:42 -07002521 // Compare and branch in one shot
2522 UNIMPLEMENTED(FATAL);
2523 }
buzbee2cfc6392012-05-07 14:51:40 -07002524 //Compare, then branch
2525 // TODO: handle fused CMP_LONG/IF_xxZ case
2526 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
buzbee02031b12012-11-23 09:41:35 -08002527 cg->OpRegImm(cu, kOpCmp, rl_src1.low_reg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002528 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
buzbee02031b12012-11-23 09:41:35 -08002529 cg->OpRegImm(cu, kOpCmp, rl_src1.low_reg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002530 } else {
buzbeefa57c472012-11-21 12:06:18 -08002531 RegLocation rl_src2 = GetLoc(cu, rhs);
buzbee02031b12012-11-23 09:41:35 -08002532 rl_src2 = cg->LoadValue(cu, rl_src2, kCoreReg);
2533 cg->OpRegReg(cu, kOpCmp, rl_src1.low_reg, rl_src2.low_reg);
buzbee2cfc6392012-05-07 14:51:40 -07002534 }
buzbee02031b12012-11-23 09:41:35 -08002535 cg->OpCondBranch(cu, cond, taken);
buzbee2cfc6392012-05-07 14:51:40 -07002536 // Fallthrough
buzbee02031b12012-11-23 09:41:35 -08002537 cg->OpUnconditionalBranch(cu, fall_through);
buzbee2cfc6392012-05-07 14:51:40 -07002538}
2539
buzbeefa57c472012-11-21 12:06:18 -08002540static void CvtCopy(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee2cfc6392012-05-07 14:51:40 -07002541{
buzbee02031b12012-11-23 09:41:35 -08002542 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002543 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2544 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(0));
2545 RegLocation rl_dest = GetLoc(cu, call_inst);
2546 DCHECK_EQ(rl_src.wide, rl_dest.wide);
2547 DCHECK_EQ(rl_src.fp, rl_dest.fp);
2548 if (rl_src.wide) {
buzbee02031b12012-11-23 09:41:35 -08002549 cg->StoreValueWide(cu, rl_dest, rl_src);
buzbee2cfc6392012-05-07 14:51:40 -07002550 } else {
buzbee02031b12012-11-23 09:41:35 -08002551 cg->StoreValue(cu, rl_dest, rl_src);
buzbee2cfc6392012-05-07 14:51:40 -07002552 }
2553}
2554
2555// Note: Immediate arg is a ConstantInt regardless of result type
buzbeefa57c472012-11-21 12:06:18 -08002556static void CvtConst(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee2cfc6392012-05-07 14:51:40 -07002557{
buzbee02031b12012-11-23 09:41:35 -08002558 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002559 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002560 llvm::ConstantInt* src =
buzbeefa57c472012-11-21 12:06:18 -08002561 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
buzbee2cfc6392012-05-07 14:51:40 -07002562 uint64_t immval = src->getZExtValue();
buzbeefa57c472012-11-21 12:06:18 -08002563 RegLocation rl_dest = GetLoc(cu, call_inst);
2564 RegLocation rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
2565 if (rl_dest.wide) {
buzbee02031b12012-11-23 09:41:35 -08002566 cg->LoadConstantValueWide(cu, rl_result.low_reg, rl_result.high_reg,
buzbee2cfc6392012-05-07 14:51:40 -07002567 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
buzbee02031b12012-11-23 09:41:35 -08002568 cg->StoreValueWide(cu, rl_dest, rl_result);
buzbee2cfc6392012-05-07 14:51:40 -07002569 } else {
buzbee7da142f2012-11-29 16:33:42 -08002570 int immediate = immval & 0xffffffff;
2571 cg->LoadConstantNoClobber(cu, rl_result.low_reg, immediate);
buzbee02031b12012-11-23 09:41:35 -08002572 cg->StoreValue(cu, rl_dest, rl_result);
buzbee7da142f2012-11-29 16:33:42 -08002573 if (immediate == 0) {
2574 cg->Workaround7250540(cu, rl_dest, rl_result.low_reg);
2575 }
buzbee2cfc6392012-05-07 14:51:40 -07002576 }
2577}
2578
buzbeefa57c472012-11-21 12:06:18 -08002579static void CvtConstObject(CompilationUnit* cu, llvm::CallInst* call_inst, bool is_string)
buzbee6969d502012-06-15 16:40:31 -07002580{
buzbee02031b12012-11-23 09:41:35 -08002581 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002582 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2583 llvm::ConstantInt* idx_val =
2584 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2585 uint32_t index = idx_val->getZExtValue();
2586 RegLocation rl_dest = GetLoc(cu, call_inst);
2587 if (is_string) {
buzbee02031b12012-11-23 09:41:35 -08002588 cg->GenConstString(cu, index, rl_dest);
buzbee101305f2012-06-28 18:00:56 -07002589 } else {
buzbee02031b12012-11-23 09:41:35 -08002590 cg->GenConstClass(cu, index, rl_dest);
buzbee101305f2012-06-28 18:00:56 -07002591 }
2592}
2593
buzbeefa57c472012-11-21 12:06:18 -08002594static void CvtFillArrayData(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee101305f2012-06-28 18:00:56 -07002595{
buzbee02031b12012-11-23 09:41:35 -08002596 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002597 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2598 llvm::ConstantInt* offset_val =
2599 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2600 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
buzbee02031b12012-11-23 09:41:35 -08002601 cg->GenFillArrayData(cu, offset_val->getSExtValue(), rl_src);
buzbee6969d502012-06-15 16:40:31 -07002602}
2603
buzbeefa57c472012-11-21 12:06:18 -08002604static void CvtNewInstance(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee4f1181f2012-06-22 13:52:12 -07002605{
buzbee02031b12012-11-23 09:41:35 -08002606 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002607 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2608 llvm::ConstantInt* type_idx_val =
2609 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2610 uint32_t type_idx = type_idx_val->getZExtValue();
2611 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002612 cg->GenNewInstance(cu, type_idx, rl_dest);
buzbee4f1181f2012-06-22 13:52:12 -07002613}
2614
buzbeefa57c472012-11-21 12:06:18 -08002615static void CvtNewArray(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee8fa0fda2012-06-27 15:44:52 -07002616{
buzbee02031b12012-11-23 09:41:35 -08002617 Codegen* cg = cu->cg.get();
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* len = call_inst->getArgOperand(1);
2623 RegLocation rl_len = GetLoc(cu, len);
2624 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002625 cg->GenNewArray(cu, type_idx, rl_dest, rl_len);
buzbee8fa0fda2012-06-27 15:44:52 -07002626}
2627
buzbeefa57c472012-11-21 12:06:18 -08002628static void CvtInstanceOf(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee8fa0fda2012-06-27 15:44:52 -07002629{
buzbee02031b12012-11-23 09:41:35 -08002630 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002631 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2632 llvm::ConstantInt* type_idx_val =
2633 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2634 uint32_t type_idx = type_idx_val->getZExtValue();
2635 llvm::Value* src = call_inst->getArgOperand(1);
2636 RegLocation rl_src = GetLoc(cu, src);
2637 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002638 cg->GenInstanceof(cu, type_idx, rl_dest, rl_src);
buzbee8fa0fda2012-06-27 15:44:52 -07002639}
2640
buzbeefa57c472012-11-21 12:06:18 -08002641static void CvtThrow(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee32412962012-06-26 16:27:56 -07002642{
buzbee02031b12012-11-23 09:41:35 -08002643 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002644 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2645 llvm::Value* src = call_inst->getArgOperand(0);
2646 RegLocation rl_src = GetLoc(cu, src);
buzbee02031b12012-11-23 09:41:35 -08002647 cg->GenThrow(cu, rl_src);
buzbee32412962012-06-26 16:27:56 -07002648}
2649
buzbeefa57c472012-11-21 12:06:18 -08002650static void CvtMonitorEnterExit(CompilationUnit* cu, bool is_enter,
2651 llvm::CallInst* call_inst)
buzbee8fa0fda2012-06-27 15:44:52 -07002652{
buzbee02031b12012-11-23 09:41:35 -08002653 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002654 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2655 llvm::ConstantInt* opt_flags =
2656 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2657 llvm::Value* src = call_inst->getArgOperand(1);
2658 RegLocation rl_src = GetLoc(cu, src);
2659 if (is_enter) {
buzbee02031b12012-11-23 09:41:35 -08002660 cg->GenMonitorEnter(cu, opt_flags->getZExtValue(), rl_src);
buzbee8fa0fda2012-06-27 15:44:52 -07002661 } else {
buzbee02031b12012-11-23 09:41:35 -08002662 cg->GenMonitorExit(cu, opt_flags->getZExtValue(), rl_src);
buzbee8fa0fda2012-06-27 15:44:52 -07002663 }
2664}
2665
buzbeefa57c472012-11-21 12:06:18 -08002666static void CvtArrayLength(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee8fa0fda2012-06-27 15:44:52 -07002667{
buzbee02031b12012-11-23 09:41:35 -08002668 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002669 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2670 llvm::ConstantInt* opt_flags =
2671 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2672 llvm::Value* src = call_inst->getArgOperand(1);
2673 RegLocation rl_src = GetLoc(cu, src);
buzbee02031b12012-11-23 09:41:35 -08002674 rl_src = cg->LoadValue(cu, rl_src, kCoreReg);
2675 cg->GenNullCheck(cu, rl_src.s_reg_low, rl_src.low_reg, opt_flags->getZExtValue());
buzbeefa57c472012-11-21 12:06:18 -08002676 RegLocation rl_dest = GetLoc(cu, call_inst);
2677 RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
2678 int len_offset = Array::LengthOffset().Int32Value();
buzbee02031b12012-11-23 09:41:35 -08002679 cg->LoadWordDisp(cu, rl_src.low_reg, len_offset, rl_result.low_reg);
2680 cg->StoreValue(cu, rl_dest, rl_result);
buzbee8fa0fda2012-06-27 15:44:52 -07002681}
2682
buzbeefa57c472012-11-21 12:06:18 -08002683static void CvtMoveException(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee32412962012-06-26 16:27:56 -07002684{
buzbee02031b12012-11-23 09:41:35 -08002685 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002686 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002687 cg->GenMoveException(cu, rl_dest);
buzbee32412962012-06-26 16:27:56 -07002688}
2689
buzbeefa57c472012-11-21 12:06:18 -08002690static void CvtSget(CompilationUnit* cu, llvm::CallInst* call_inst, bool is_wide, bool is_object)
buzbee4f1181f2012-06-22 13:52:12 -07002691{
buzbee02031b12012-11-23 09:41:35 -08002692 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002693 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2694 llvm::ConstantInt* type_idx_val =
2695 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2696 uint32_t type_idx = type_idx_val->getZExtValue();
2697 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002698 cg->GenSget(cu, type_idx, rl_dest, is_wide, is_object);
buzbee4f1181f2012-06-22 13:52:12 -07002699}
2700
buzbeefa57c472012-11-21 12:06:18 -08002701static void CvtSput(CompilationUnit* cu, llvm::CallInst* call_inst, bool is_wide, bool is_object)
buzbee8fa0fda2012-06-27 15:44:52 -07002702{
buzbee02031b12012-11-23 09:41:35 -08002703 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002704 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2705 llvm::ConstantInt* type_idx_val =
2706 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2707 uint32_t type_idx = type_idx_val->getZExtValue();
2708 llvm::Value* src = call_inst->getArgOperand(1);
2709 RegLocation rl_src = GetLoc(cu, src);
buzbee02031b12012-11-23 09:41:35 -08002710 cg->GenSput(cu, type_idx, rl_src, is_wide, is_object);
buzbee8fa0fda2012-06-27 15:44:52 -07002711}
2712
buzbeefa57c472012-11-21 12:06:18 -08002713static void CvtAget(CompilationUnit* cu, llvm::CallInst* call_inst, OpSize size, int scale)
buzbee8fa0fda2012-06-27 15:44:52 -07002714{
buzbee02031b12012-11-23 09:41:35 -08002715 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002716 DCHECK_EQ(call_inst->getNumArgOperands(), 3U);
2717 llvm::ConstantInt* opt_flags =
2718 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2719 RegLocation rl_array = GetLoc(cu, call_inst->getArgOperand(1));
2720 RegLocation rl_index = GetLoc(cu, call_inst->getArgOperand(2));
2721 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002722 cg->GenArrayGet(cu, opt_flags->getZExtValue(), size, rl_array, rl_index,
buzbeefa57c472012-11-21 12:06:18 -08002723 rl_dest, scale);
buzbee8fa0fda2012-06-27 15:44:52 -07002724}
2725
buzbeefa57c472012-11-21 12:06:18 -08002726static void CvtAput(CompilationUnit* cu, llvm::CallInst* call_inst, OpSize size,
2727 int scale, bool is_object)
buzbee8fa0fda2012-06-27 15:44:52 -07002728{
buzbee02031b12012-11-23 09:41:35 -08002729 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002730 DCHECK_EQ(call_inst->getNumArgOperands(), 4U);
2731 llvm::ConstantInt* opt_flags =
2732 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2733 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
2734 RegLocation rl_array = GetLoc(cu, call_inst->getArgOperand(2));
2735 RegLocation rl_index = GetLoc(cu, call_inst->getArgOperand(3));
2736 if (is_object) {
buzbee02031b12012-11-23 09:41:35 -08002737 cg->GenArrayObjPut(cu, opt_flags->getZExtValue(), rl_array, rl_index,
buzbeefa57c472012-11-21 12:06:18 -08002738 rl_src, scale);
buzbeef1f86362012-07-10 15:18:31 -07002739 } else {
buzbee02031b12012-11-23 09:41:35 -08002740 cg->GenArrayPut(cu, opt_flags->getZExtValue(), size, rl_array, rl_index,
buzbeefa57c472012-11-21 12:06:18 -08002741 rl_src, scale);
buzbeef1f86362012-07-10 15:18:31 -07002742 }
2743}
2744
buzbeefa57c472012-11-21 12:06:18 -08002745static void CvtAputObj(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbeef1f86362012-07-10 15:18:31 -07002746{
buzbeefa57c472012-11-21 12:06:18 -08002747 CvtAput(cu, call_inst, kWord, 2, true /* is_object */);
buzbeef1f86362012-07-10 15:18:31 -07002748}
2749
buzbeefa57c472012-11-21 12:06:18 -08002750static void CvtAputPrimitive(CompilationUnit* cu, llvm::CallInst* call_inst,
buzbeef1f86362012-07-10 15:18:31 -07002751 OpSize size, int scale)
2752{
buzbeefa57c472012-11-21 12:06:18 -08002753 CvtAput(cu, call_inst, size, scale, false /* is_object */);
buzbee8fa0fda2012-06-27 15:44:52 -07002754}
2755
buzbeefa57c472012-11-21 12:06:18 -08002756static void CvtIget(CompilationUnit* cu, llvm::CallInst* call_inst, OpSize size,
2757 bool is_wide, bool is_obj)
buzbee101305f2012-06-28 18:00:56 -07002758{
buzbee02031b12012-11-23 09:41:35 -08002759 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002760 DCHECK_EQ(call_inst->getNumArgOperands(), 3U);
2761 llvm::ConstantInt* opt_flags =
2762 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2763 RegLocation rl_obj = GetLoc(cu, call_inst->getArgOperand(1));
2764 llvm::ConstantInt* field_idx =
2765 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(2));
2766 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002767 cg->GenIGet(cu, field_idx->getZExtValue(), opt_flags->getZExtValue(),
buzbeefa57c472012-11-21 12:06:18 -08002768 size, rl_dest, rl_obj, is_wide, is_obj);
buzbee101305f2012-06-28 18:00:56 -07002769}
2770
buzbeefa57c472012-11-21 12:06:18 -08002771static void CvtIput(CompilationUnit* cu, llvm::CallInst* call_inst, OpSize size,
2772 bool is_wide, bool is_obj)
buzbee101305f2012-06-28 18:00:56 -07002773{
buzbee02031b12012-11-23 09:41:35 -08002774 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002775 DCHECK_EQ(call_inst->getNumArgOperands(), 4U);
2776 llvm::ConstantInt* opt_flags =
2777 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2778 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
2779 RegLocation rl_obj = GetLoc(cu, call_inst->getArgOperand(2));
2780 llvm::ConstantInt* field_idx =
2781 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(3));
buzbee02031b12012-11-23 09:41:35 -08002782 cg->GenIPut(cu, field_idx->getZExtValue(), opt_flags->getZExtValue(),
buzbeefa57c472012-11-21 12:06:18 -08002783 size, rl_src, rl_obj, is_wide, is_obj);
buzbee101305f2012-06-28 18:00:56 -07002784}
2785
buzbeefa57c472012-11-21 12:06:18 -08002786static void CvtCheckCast(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee101305f2012-06-28 18:00:56 -07002787{
buzbee02031b12012-11-23 09:41:35 -08002788 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002789 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2790 llvm::ConstantInt* type_idx =
2791 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2792 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
buzbee02031b12012-11-23 09:41:35 -08002793 cg->GenCheckCast(cu, type_idx->getZExtValue(), rl_src);
buzbee101305f2012-06-28 18:00:56 -07002794}
2795
buzbeefa57c472012-11-21 12:06:18 -08002796static void CvtFPCompare(CompilationUnit* cu, llvm::CallInst* call_inst,
buzbeeaad94382012-11-21 07:40:50 -08002797 Instruction::Code opcode)
buzbee76592632012-06-29 15:18:35 -07002798{
buzbee02031b12012-11-23 09:41:35 -08002799 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002800 RegLocation rl_src1 = GetLoc(cu, call_inst->getArgOperand(0));
2801 RegLocation rl_src2 = GetLoc(cu, call_inst->getArgOperand(1));
2802 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002803 cg->GenCmpFP(cu, opcode, rl_dest, rl_src1, rl_src2);
buzbee76592632012-06-29 15:18:35 -07002804}
2805
buzbeefa57c472012-11-21 12:06:18 -08002806static void CvtLongCompare(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002807{
buzbee02031b12012-11-23 09:41:35 -08002808 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002809 RegLocation rl_src1 = GetLoc(cu, call_inst->getArgOperand(0));
2810 RegLocation rl_src2 = GetLoc(cu, call_inst->getArgOperand(1));
2811 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002812 cg->GenCmpLong(cu, rl_dest, rl_src1, rl_src2);
buzbee76592632012-06-29 15:18:35 -07002813}
2814
buzbeefa57c472012-11-21 12:06:18 -08002815static void CvtSwitch(CompilationUnit* cu, llvm::Instruction* inst)
buzbeef58c12c2012-07-03 15:06:29 -07002816{
buzbee02031b12012-11-23 09:41:35 -08002817 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002818 llvm::SwitchInst* sw_inst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2819 DCHECK(sw_inst != NULL);
2820 llvm::Value* test_val = sw_inst->getCondition();
2821 llvm::MDNode* table_offset_node = sw_inst->getMetadata("SwitchTable");
2822 DCHECK(table_offset_node != NULL);
2823 llvm::ConstantInt* table_offset_value =
2824 static_cast<llvm::ConstantInt*>(table_offset_node->getOperand(0));
2825 int32_t table_offset = table_offset_value->getSExtValue();
2826 RegLocation rl_src = GetLoc(cu, test_val);
2827 const uint16_t* table = cu->insns + cu->current_dalvik_offset + table_offset;
2828 uint16_t table_magic = *table;
2829 if (table_magic == 0x100) {
buzbee02031b12012-11-23 09:41:35 -08002830 cg->GenPackedSwitch(cu, table_offset, rl_src);
buzbeea1da8a52012-07-09 14:00:21 -07002831 } else {
buzbeefa57c472012-11-21 12:06:18 -08002832 DCHECK_EQ(table_magic, 0x200);
buzbee02031b12012-11-23 09:41:35 -08002833 cg->GenSparseSwitch(cu, table_offset, rl_src);
buzbeea1da8a52012-07-09 14:00:21 -07002834 }
buzbeef58c12c2012-07-03 15:06:29 -07002835}
2836
buzbeefa57c472012-11-21 12:06:18 -08002837static void CvtInvoke(CompilationUnit* cu, llvm::CallInst* call_inst, bool is_void,
2838 bool is_filled_new_array)
buzbee6969d502012-06-15 16:40:31 -07002839{
buzbee02031b12012-11-23 09:41:35 -08002840 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002841 CallInfo* info = static_cast<CallInfo*>(NewMem(cu, sizeof(CallInfo), true, kAllocMisc));
2842 if (is_void) {
buzbee6969d502012-06-15 16:40:31 -07002843 info->result.location = kLocInvalid;
2844 } else {
buzbeefa57c472012-11-21 12:06:18 -08002845 info->result = GetLoc(cu, call_inst);
buzbee6969d502012-06-15 16:40:31 -07002846 }
buzbeefa57c472012-11-21 12:06:18 -08002847 llvm::ConstantInt* invoke_type_val =
2848 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2849 llvm::ConstantInt* method_index_val =
2850 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(1));
2851 llvm::ConstantInt* opt_flags_val =
2852 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(2));
2853 info->type = static_cast<InvokeType>(invoke_type_val->getZExtValue());
2854 info->index = method_index_val->getZExtValue();
2855 info->opt_flags = opt_flags_val->getZExtValue();
2856 info->offset = cu->current_dalvik_offset;
buzbee6969d502012-06-15 16:40:31 -07002857
buzbee6969d502012-06-15 16:40:31 -07002858 // Count the argument words, and then build argument array.
buzbeefa57c472012-11-21 12:06:18 -08002859 info->num_arg_words = 0;
2860 for (unsigned int i = 3; i < call_inst->getNumArgOperands(); i++) {
2861 RegLocation t_loc = GetLoc(cu, call_inst->getArgOperand(i));
2862 info->num_arg_words += t_loc.wide ? 2 : 1;
buzbee6969d502012-06-15 16:40:31 -07002863 }
buzbeefa57c472012-11-21 12:06:18 -08002864 info->args = (info->num_arg_words == 0) ? NULL : static_cast<RegLocation*>
2865 (NewMem(cu, sizeof(RegLocation) * info->num_arg_words, false, kAllocMisc));
buzbee6969d502012-06-15 16:40:31 -07002866 // Now, fill in the location records, synthesizing high loc of wide vals
buzbeefa57c472012-11-21 12:06:18 -08002867 for (int i = 3, next = 0; next < info->num_arg_words;) {
2868 info->args[next] = GetLoc(cu, call_inst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002869 if (info->args[next].wide) {
2870 next++;
2871 // TODO: Might make sense to mark this as an invalid loc
buzbeefa57c472012-11-21 12:06:18 -08002872 info->args[next].orig_sreg = info->args[next-1].orig_sreg+1;
2873 info->args[next].s_reg_low = info->args[next-1].s_reg_low+1;
buzbee6969d502012-06-15 16:40:31 -07002874 }
2875 next++;
2876 }
buzbeefa57c472012-11-21 12:06:18 -08002877 // TODO - rework such that we no longer need is_range
2878 info->is_range = (info->num_arg_words > 5);
buzbee4f4dfc72012-07-02 14:54:44 -07002879
buzbeefa57c472012-11-21 12:06:18 -08002880 if (is_filled_new_array) {
buzbee02031b12012-11-23 09:41:35 -08002881 cg->GenFilledNewArray(cu, info);
buzbee101305f2012-06-28 18:00:56 -07002882 } else {
buzbee02031b12012-11-23 09:41:35 -08002883 cg->GenInvoke(cu, info);
buzbee101305f2012-06-28 18:00:56 -07002884 }
buzbee6969d502012-06-15 16:40:31 -07002885}
2886
buzbeead8f15e2012-06-18 14:49:45 -07002887/* Look up the RegLocation associated with a Value. Must already be defined */
buzbeefa57c472012-11-21 12:06:18 -08002888static RegLocation ValToLoc(CompilationUnit* cu, llvm::Value* val)
buzbeead8f15e2012-06-18 14:49:45 -07002889{
buzbeefa57c472012-11-21 12:06:18 -08002890 SafeMap<llvm::Value*, RegLocation>::iterator it = cu->loc_map.find(val);
2891 DCHECK(it != cu->loc_map.end()) << "Missing definition";
buzbeead8f15e2012-06-18 14:49:45 -07002892 return it->second;
2893}
2894
buzbeefa57c472012-11-21 12:06:18 -08002895static bool BitcodeBlockCodeGen(CompilationUnit* cu, llvm::BasicBlock* bb)
buzbee2cfc6392012-05-07 14:51:40 -07002896{
buzbee02031b12012-11-23 09:41:35 -08002897 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002898 while (cu->llvm_blocks.find(bb) == cu->llvm_blocks.end()) {
2899 llvm::BasicBlock* next_bb = NULL;
2900 cu->llvm_blocks.insert(bb);
2901 bool is_entry = (bb == &cu->func->getEntryBlock());
buzbee0967a252012-09-14 10:43:54 -07002902 // Define the starting label
buzbeefa57c472012-11-21 12:06:18 -08002903 LIR* block_label = cu->block_to_label_map.Get(bb);
buzbee0967a252012-09-14 10:43:54 -07002904 // Extract the type and starting offset from the block's name
buzbeefa57c472012-11-21 12:06:18 -08002905 char block_type = kInvalidBlock;
2906 if (is_entry) {
2907 block_type = kNormalBlock;
2908 block_label->operands[0] = 0;
buzbee951c0a12012-10-03 16:31:39 -07002909 } else if (!bb->hasName()) {
buzbeefa57c472012-11-21 12:06:18 -08002910 block_type = kNormalBlock;
2911 block_label->operands[0] = DexFile::kDexNoIndex;
buzbee0967a252012-09-14 10:43:54 -07002912 } else {
buzbeefa57c472012-11-21 12:06:18 -08002913 std::string block_name = bb->getName().str();
buzbee951c0a12012-10-03 16:31:39 -07002914 int dummy;
buzbeefa57c472012-11-21 12:06:18 -08002915 sscanf(block_name.c_str(), kLabelFormat, &block_type, &block_label->operands[0], &dummy);
2916 cu->current_dalvik_offset = block_label->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002917 }
buzbeefa57c472012-11-21 12:06:18 -08002918 DCHECK((block_type == kNormalBlock) || (block_type == kCatchBlock));
2919 cu->current_dalvik_offset = block_label->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002920 // Set the label kind
buzbeefa57c472012-11-21 12:06:18 -08002921 block_label->opcode = kPseudoNormalBlockLabel;
buzbee0967a252012-09-14 10:43:54 -07002922 // Insert the label
buzbeefa57c472012-11-21 12:06:18 -08002923 AppendLIR(cu, block_label);
buzbee2cfc6392012-05-07 14:51:40 -07002924
buzbeefa57c472012-11-21 12:06:18 -08002925 LIR* head_lir = NULL;
buzbee8320f382012-09-11 16:29:42 -07002926
buzbeefa57c472012-11-21 12:06:18 -08002927 if (block_type == kCatchBlock) {
2928 head_lir = NewLIR0(cu, kPseudoExportedPC);
buzbee0967a252012-09-14 10:43:54 -07002929 }
buzbee8320f382012-09-11 16:29:42 -07002930
buzbee0967a252012-09-14 10:43:54 -07002931 // Free temp registers and reset redundant store tracking */
buzbeefa57c472012-11-21 12:06:18 -08002932 ResetRegPool(cu);
2933 ResetDefTracking(cu);
buzbee2cfc6392012-05-07 14:51:40 -07002934
buzbee0967a252012-09-14 10:43:54 -07002935 //TODO: restore oat incoming liveness optimization
buzbeefa57c472012-11-21 12:06:18 -08002936 ClobberAllRegs(cu);
buzbee2cfc6392012-05-07 14:51:40 -07002937
buzbeefa57c472012-11-21 12:06:18 -08002938 if (is_entry) {
buzbee52a77fc2012-11-20 19:50:46 -08002939 RegLocation* ArgLocs = static_cast<RegLocation*>
buzbeefa57c472012-11-21 12:06:18 -08002940 (NewMem(cu, sizeof(RegLocation) * cu->num_ins, true, kAllocMisc));
2941 llvm::Function::arg_iterator it(cu->func->arg_begin());
2942 llvm::Function::arg_iterator it_end(cu->func->arg_end());
buzbee0967a252012-09-14 10:43:54 -07002943 // Skip past Method*
2944 it++;
2945 for (unsigned i = 0; it != it_end; ++it) {
2946 llvm::Value* val = it;
buzbeefa57c472012-11-21 12:06:18 -08002947 ArgLocs[i++] = ValToLoc(cu, val);
buzbee0967a252012-09-14 10:43:54 -07002948 llvm::Type* ty = val->getType();
buzbeefa57c472012-11-21 12:06:18 -08002949 if ((ty == cu->irb->getInt64Ty()) || (ty == cu->irb->getDoubleTy())) {
buzbee52a77fc2012-11-20 19:50:46 -08002950 ArgLocs[i] = ArgLocs[i-1];
buzbeefa57c472012-11-21 12:06:18 -08002951 ArgLocs[i].low_reg = ArgLocs[i].high_reg;
2952 ArgLocs[i].orig_sreg++;
2953 ArgLocs[i].s_reg_low = INVALID_SREG;
2954 ArgLocs[i].high_word = true;
buzbee0967a252012-09-14 10:43:54 -07002955 i++;
2956 }
2957 }
buzbee02031b12012-11-23 09:41:35 -08002958 cg->GenEntrySequence(cu, ArgLocs, cu->method_loc);
buzbee0967a252012-09-14 10:43:54 -07002959 }
2960
2961 // Visit all of the instructions in the block
2962 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2963 llvm::Instruction* inst = it;
buzbeefa57c472012-11-21 12:06:18 -08002964 llvm::BasicBlock::iterator next_it = ++it;
buzbee0967a252012-09-14 10:43:54 -07002965 // Extract the Dalvik offset from the instruction
2966 uint32_t opcode = inst->getOpcode();
buzbeefa57c472012-11-21 12:06:18 -08002967 llvm::MDNode* dex_offset_node = inst->getMetadata("DexOff");
2968 if (dex_offset_node != NULL) {
2969 llvm::ConstantInt* dex_offset_value =
2970 static_cast<llvm::ConstantInt*>(dex_offset_node->getOperand(0));
2971 cu->current_dalvik_offset = dex_offset_value->getZExtValue();
buzbee0967a252012-09-14 10:43:54 -07002972 }
2973
buzbeefa57c472012-11-21 12:06:18 -08002974 ResetRegPool(cu);
2975 if (cu->disable_opt & (1 << kTrackLiveTemps)) {
2976 ClobberAllRegs(cu);
buzbee0967a252012-09-14 10:43:54 -07002977 }
2978
buzbeefa57c472012-11-21 12:06:18 -08002979 if (cu->disable_opt & (1 << kSuppressLoads)) {
2980 ResetDefTracking(cu);
buzbee0967a252012-09-14 10:43:54 -07002981 }
2982
2983 #ifndef NDEBUG
2984 /* Reset temp tracking sanity check */
buzbeefa57c472012-11-21 12:06:18 -08002985 cu->live_sreg = INVALID_SREG;
buzbee0967a252012-09-14 10:43:54 -07002986 #endif
2987
2988 // TODO: use llvm opcode name here instead of "boundary" if verbose
buzbeefa57c472012-11-21 12:06:18 -08002989 LIR* boundary_lir = MarkBoundary(cu, cu->current_dalvik_offset, "boundary");
buzbee0967a252012-09-14 10:43:54 -07002990
2991 /* Remember the first LIR for thisl block*/
buzbeefa57c472012-11-21 12:06:18 -08002992 if (head_lir == NULL) {
2993 head_lir = boundary_lir;
2994 head_lir->def_mask = ENCODE_ALL;
buzbee0967a252012-09-14 10:43:54 -07002995 }
2996
2997 switch(opcode) {
2998
2999 case llvm::Instruction::ICmp: {
buzbeefa57c472012-11-21 12:06:18 -08003000 llvm::Instruction* next_inst = next_it;
3001 llvm::BranchInst* br_inst = llvm::dyn_cast<llvm::BranchInst>(next_inst);
3002 if (br_inst != NULL /* and... */) {
3003 CvtICmpBr(cu, inst, br_inst);
buzbee0967a252012-09-14 10:43:54 -07003004 ++it;
3005 } else {
buzbeefa57c472012-11-21 12:06:18 -08003006 CvtICmp(cu, inst);
buzbee0967a252012-09-14 10:43:54 -07003007 }
3008 }
3009 break;
3010
3011 case llvm::Instruction::Call: {
buzbeefa57c472012-11-21 12:06:18 -08003012 llvm::CallInst* call_inst = llvm::dyn_cast<llvm::CallInst>(inst);
3013 llvm::Function* callee = call_inst->getCalledFunction();
buzbee0967a252012-09-14 10:43:54 -07003014 greenland::IntrinsicHelper::IntrinsicId id =
buzbeefa57c472012-11-21 12:06:18 -08003015 cu->intrinsic_helper->GetIntrinsicId(callee);
buzbee0967a252012-09-14 10:43:54 -07003016 switch (id) {
3017 case greenland::IntrinsicHelper::AllocaShadowFrame:
buzbee0967a252012-09-14 10:43:54 -07003018 case greenland::IntrinsicHelper::PopShadowFrame:
TDYa1278e950c12012-11-02 09:58:19 -07003019 case greenland::IntrinsicHelper::SetVReg:
buzbee0967a252012-09-14 10:43:54 -07003020 // Ignore shadow frame stuff for quick compiler
3021 break;
3022 case greenland::IntrinsicHelper::CopyInt:
3023 case greenland::IntrinsicHelper::CopyObj:
3024 case greenland::IntrinsicHelper::CopyFloat:
3025 case greenland::IntrinsicHelper::CopyLong:
3026 case greenland::IntrinsicHelper::CopyDouble:
buzbeefa57c472012-11-21 12:06:18 -08003027 CvtCopy(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003028 break;
3029 case greenland::IntrinsicHelper::ConstInt:
3030 case greenland::IntrinsicHelper::ConstObj:
3031 case greenland::IntrinsicHelper::ConstLong:
3032 case greenland::IntrinsicHelper::ConstFloat:
3033 case greenland::IntrinsicHelper::ConstDouble:
buzbeefa57c472012-11-21 12:06:18 -08003034 CvtConst(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003035 break;
3036 case greenland::IntrinsicHelper::DivInt:
3037 case greenland::IntrinsicHelper::DivLong:
buzbeefa57c472012-11-21 12:06:18 -08003038 CvtBinOp(cu, kOpDiv, inst);
buzbee0967a252012-09-14 10:43:54 -07003039 break;
3040 case greenland::IntrinsicHelper::RemInt:
3041 case greenland::IntrinsicHelper::RemLong:
buzbeefa57c472012-11-21 12:06:18 -08003042 CvtBinOp(cu, kOpRem, inst);
buzbee0967a252012-09-14 10:43:54 -07003043 break;
3044 case greenland::IntrinsicHelper::MethodInfo:
3045 // Already dealt with - just ignore it here.
3046 break;
3047 case greenland::IntrinsicHelper::CheckSuspend:
buzbee02031b12012-11-23 09:41:35 -08003048 cg->GenSuspendTest(cu, 0 /* opt_flags already applied */);
buzbee0967a252012-09-14 10:43:54 -07003049 break;
3050 case greenland::IntrinsicHelper::HLInvokeObj:
3051 case greenland::IntrinsicHelper::HLInvokeFloat:
3052 case greenland::IntrinsicHelper::HLInvokeDouble:
3053 case greenland::IntrinsicHelper::HLInvokeLong:
3054 case greenland::IntrinsicHelper::HLInvokeInt:
buzbeefa57c472012-11-21 12:06:18 -08003055 CvtInvoke(cu, call_inst, false /* is_void */, false /* new_array */);
buzbee0967a252012-09-14 10:43:54 -07003056 break;
3057 case greenland::IntrinsicHelper::HLInvokeVoid:
buzbeefa57c472012-11-21 12:06:18 -08003058 CvtInvoke(cu, call_inst, true /* is_void */, false /* new_array */);
buzbee0967a252012-09-14 10:43:54 -07003059 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003060 case greenland::IntrinsicHelper::HLFilledNewArray:
buzbeefa57c472012-11-21 12:06:18 -08003061 CvtInvoke(cu, call_inst, false /* is_void */, true /* new_array */);
buzbee0967a252012-09-14 10:43:54 -07003062 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003063 case greenland::IntrinsicHelper::HLFillArrayData:
buzbeefa57c472012-11-21 12:06:18 -08003064 CvtFillArrayData(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003065 break;
3066 case greenland::IntrinsicHelper::ConstString:
buzbeefa57c472012-11-21 12:06:18 -08003067 CvtConstObject(cu, call_inst, true /* is_string */);
buzbee0967a252012-09-14 10:43:54 -07003068 break;
3069 case greenland::IntrinsicHelper::ConstClass:
buzbeefa57c472012-11-21 12:06:18 -08003070 CvtConstObject(cu, call_inst, false /* is_string */);
buzbee0967a252012-09-14 10:43:54 -07003071 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003072 case greenland::IntrinsicHelper::HLCheckCast:
buzbeefa57c472012-11-21 12:06:18 -08003073 CvtCheckCast(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003074 break;
3075 case greenland::IntrinsicHelper::NewInstance:
buzbeefa57c472012-11-21 12:06:18 -08003076 CvtNewInstance(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003077 break;
3078 case greenland::IntrinsicHelper::HLSgetObject:
buzbeefa57c472012-11-21 12:06:18 -08003079 CvtSget(cu, call_inst, false /* wide */, true /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003080 break;
3081 case greenland::IntrinsicHelper::HLSget:
3082 case greenland::IntrinsicHelper::HLSgetFloat:
3083 case greenland::IntrinsicHelper::HLSgetBoolean:
3084 case greenland::IntrinsicHelper::HLSgetByte:
3085 case greenland::IntrinsicHelper::HLSgetChar:
3086 case greenland::IntrinsicHelper::HLSgetShort:
buzbeefa57c472012-11-21 12:06:18 -08003087 CvtSget(cu, call_inst, false /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003088 break;
3089 case greenland::IntrinsicHelper::HLSgetWide:
3090 case greenland::IntrinsicHelper::HLSgetDouble:
buzbeefa57c472012-11-21 12:06:18 -08003091 CvtSget(cu, call_inst, true /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003092 break;
3093 case greenland::IntrinsicHelper::HLSput:
3094 case greenland::IntrinsicHelper::HLSputFloat:
3095 case greenland::IntrinsicHelper::HLSputBoolean:
3096 case greenland::IntrinsicHelper::HLSputByte:
3097 case greenland::IntrinsicHelper::HLSputChar:
3098 case greenland::IntrinsicHelper::HLSputShort:
buzbeefa57c472012-11-21 12:06:18 -08003099 CvtSput(cu, call_inst, false /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003100 break;
3101 case greenland::IntrinsicHelper::HLSputWide:
3102 case greenland::IntrinsicHelper::HLSputDouble:
buzbeefa57c472012-11-21 12:06:18 -08003103 CvtSput(cu, call_inst, true /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003104 break;
3105 case greenland::IntrinsicHelper::HLSputObject:
buzbeefa57c472012-11-21 12:06:18 -08003106 CvtSput(cu, call_inst, false /* wide */, true /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003107 break;
3108 case greenland::IntrinsicHelper::GetException:
buzbeefa57c472012-11-21 12:06:18 -08003109 CvtMoveException(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003110 break;
TDYa127f71bf5a2012-07-29 20:09:52 -07003111 case greenland::IntrinsicHelper::HLThrowException:
buzbeefa57c472012-11-21 12:06:18 -08003112 CvtThrow(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003113 break;
3114 case greenland::IntrinsicHelper::MonitorEnter:
buzbeefa57c472012-11-21 12:06:18 -08003115 CvtMonitorEnterExit(cu, true /* is_enter */, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003116 break;
3117 case greenland::IntrinsicHelper::MonitorExit:
buzbeefa57c472012-11-21 12:06:18 -08003118 CvtMonitorEnterExit(cu, false /* is_enter */, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003119 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003120 case greenland::IntrinsicHelper::OptArrayLength:
buzbeefa57c472012-11-21 12:06:18 -08003121 CvtArrayLength(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003122 break;
3123 case greenland::IntrinsicHelper::NewArray:
buzbeefa57c472012-11-21 12:06:18 -08003124 CvtNewArray(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003125 break;
3126 case greenland::IntrinsicHelper::InstanceOf:
buzbeefa57c472012-11-21 12:06:18 -08003127 CvtInstanceOf(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003128 break;
3129
3130 case greenland::IntrinsicHelper::HLArrayGet:
3131 case greenland::IntrinsicHelper::HLArrayGetObject:
3132 case greenland::IntrinsicHelper::HLArrayGetFloat:
buzbeefa57c472012-11-21 12:06:18 -08003133 CvtAget(cu, call_inst, kWord, 2);
buzbee0967a252012-09-14 10:43:54 -07003134 break;
3135 case greenland::IntrinsicHelper::HLArrayGetWide:
3136 case greenland::IntrinsicHelper::HLArrayGetDouble:
buzbeefa57c472012-11-21 12:06:18 -08003137 CvtAget(cu, call_inst, kLong, 3);
buzbee0967a252012-09-14 10:43:54 -07003138 break;
3139 case greenland::IntrinsicHelper::HLArrayGetBoolean:
buzbeefa57c472012-11-21 12:06:18 -08003140 CvtAget(cu, call_inst, kUnsignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003141 break;
3142 case greenland::IntrinsicHelper::HLArrayGetByte:
buzbeefa57c472012-11-21 12:06:18 -08003143 CvtAget(cu, call_inst, kSignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003144 break;
3145 case greenland::IntrinsicHelper::HLArrayGetChar:
buzbeefa57c472012-11-21 12:06:18 -08003146 CvtAget(cu, call_inst, kUnsignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003147 break;
3148 case greenland::IntrinsicHelper::HLArrayGetShort:
buzbeefa57c472012-11-21 12:06:18 -08003149 CvtAget(cu, call_inst, kSignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003150 break;
3151
3152 case greenland::IntrinsicHelper::HLArrayPut:
3153 case greenland::IntrinsicHelper::HLArrayPutFloat:
buzbeefa57c472012-11-21 12:06:18 -08003154 CvtAputPrimitive(cu, call_inst, kWord, 2);
buzbee0967a252012-09-14 10:43:54 -07003155 break;
3156 case greenland::IntrinsicHelper::HLArrayPutObject:
buzbeefa57c472012-11-21 12:06:18 -08003157 CvtAputObj(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003158 break;
3159 case greenland::IntrinsicHelper::HLArrayPutWide:
3160 case greenland::IntrinsicHelper::HLArrayPutDouble:
buzbeefa57c472012-11-21 12:06:18 -08003161 CvtAputPrimitive(cu, call_inst, kLong, 3);
buzbee0967a252012-09-14 10:43:54 -07003162 break;
3163 case greenland::IntrinsicHelper::HLArrayPutBoolean:
buzbeefa57c472012-11-21 12:06:18 -08003164 CvtAputPrimitive(cu, call_inst, kUnsignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003165 break;
3166 case greenland::IntrinsicHelper::HLArrayPutByte:
buzbeefa57c472012-11-21 12:06:18 -08003167 CvtAputPrimitive(cu, call_inst, kSignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003168 break;
3169 case greenland::IntrinsicHelper::HLArrayPutChar:
buzbeefa57c472012-11-21 12:06:18 -08003170 CvtAputPrimitive(cu, call_inst, kUnsignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003171 break;
3172 case greenland::IntrinsicHelper::HLArrayPutShort:
buzbeefa57c472012-11-21 12:06:18 -08003173 CvtAputPrimitive(cu, call_inst, kSignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003174 break;
3175
3176 case greenland::IntrinsicHelper::HLIGet:
3177 case greenland::IntrinsicHelper::HLIGetFloat:
buzbeefa57c472012-11-21 12:06:18 -08003178 CvtIget(cu, call_inst, kWord, false /* is_wide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003179 break;
3180 case greenland::IntrinsicHelper::HLIGetObject:
buzbeefa57c472012-11-21 12:06:18 -08003181 CvtIget(cu, call_inst, kWord, false /* is_wide */, true /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003182 break;
3183 case greenland::IntrinsicHelper::HLIGetWide:
3184 case greenland::IntrinsicHelper::HLIGetDouble:
buzbeefa57c472012-11-21 12:06:18 -08003185 CvtIget(cu, call_inst, kLong, true /* is_wide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003186 break;
3187 case greenland::IntrinsicHelper::HLIGetBoolean:
buzbeefa57c472012-11-21 12:06:18 -08003188 CvtIget(cu, call_inst, kUnsignedByte, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003189 false /* obj */);
3190 break;
3191 case greenland::IntrinsicHelper::HLIGetByte:
buzbeefa57c472012-11-21 12:06:18 -08003192 CvtIget(cu, call_inst, kSignedByte, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003193 false /* obj */);
3194 break;
3195 case greenland::IntrinsicHelper::HLIGetChar:
buzbeefa57c472012-11-21 12:06:18 -08003196 CvtIget(cu, call_inst, kUnsignedHalf, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003197 false /* obj */);
3198 break;
3199 case greenland::IntrinsicHelper::HLIGetShort:
buzbeefa57c472012-11-21 12:06:18 -08003200 CvtIget(cu, call_inst, kSignedHalf, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003201 false /* obj */);
3202 break;
3203
3204 case greenland::IntrinsicHelper::HLIPut:
3205 case greenland::IntrinsicHelper::HLIPutFloat:
buzbeefa57c472012-11-21 12:06:18 -08003206 CvtIput(cu, call_inst, kWord, false /* is_wide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003207 break;
3208 case greenland::IntrinsicHelper::HLIPutObject:
buzbeefa57c472012-11-21 12:06:18 -08003209 CvtIput(cu, call_inst, kWord, false /* is_wide */, true /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003210 break;
3211 case greenland::IntrinsicHelper::HLIPutWide:
3212 case greenland::IntrinsicHelper::HLIPutDouble:
buzbeefa57c472012-11-21 12:06:18 -08003213 CvtIput(cu, call_inst, kLong, true /* is_wide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003214 break;
3215 case greenland::IntrinsicHelper::HLIPutBoolean:
buzbeefa57c472012-11-21 12:06:18 -08003216 CvtIput(cu, call_inst, kUnsignedByte, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003217 false /* obj */);
3218 break;
3219 case greenland::IntrinsicHelper::HLIPutByte:
buzbeefa57c472012-11-21 12:06:18 -08003220 CvtIput(cu, call_inst, kSignedByte, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003221 false /* obj */);
3222 break;
3223 case greenland::IntrinsicHelper::HLIPutChar:
buzbeefa57c472012-11-21 12:06:18 -08003224 CvtIput(cu, call_inst, kUnsignedHalf, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003225 false /* obj */);
3226 break;
3227 case greenland::IntrinsicHelper::HLIPutShort:
buzbeefa57c472012-11-21 12:06:18 -08003228 CvtIput(cu, call_inst, kSignedHalf, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003229 false /* obj */);
3230 break;
3231
3232 case greenland::IntrinsicHelper::IntToChar:
buzbeefa57c472012-11-21 12:06:18 -08003233 CvtIntNarrowing(cu, call_inst, Instruction::INT_TO_CHAR);
buzbee0967a252012-09-14 10:43:54 -07003234 break;
3235 case greenland::IntrinsicHelper::IntToShort:
buzbeefa57c472012-11-21 12:06:18 -08003236 CvtIntNarrowing(cu, call_inst, Instruction::INT_TO_SHORT);
buzbee0967a252012-09-14 10:43:54 -07003237 break;
3238 case greenland::IntrinsicHelper::IntToByte:
buzbeefa57c472012-11-21 12:06:18 -08003239 CvtIntNarrowing(cu, call_inst, Instruction::INT_TO_BYTE);
buzbee0967a252012-09-14 10:43:54 -07003240 break;
3241
TDYa1274ec8ccd2012-08-11 07:04:57 -07003242 case greenland::IntrinsicHelper::F2I:
3243 case greenland::IntrinsicHelper::D2I:
3244 case greenland::IntrinsicHelper::F2L:
3245 case greenland::IntrinsicHelper::D2L:
buzbeefa57c472012-11-21 12:06:18 -08003246 CvtFPToInt(cu, call_inst);
TDYa1274ec8ccd2012-08-11 07:04:57 -07003247 break;
3248
buzbee0967a252012-09-14 10:43:54 -07003249 case greenland::IntrinsicHelper::CmplFloat:
buzbeefa57c472012-11-21 12:06:18 -08003250 CvtFPCompare(cu, call_inst, Instruction::CMPL_FLOAT);
buzbee0967a252012-09-14 10:43:54 -07003251 break;
3252 case greenland::IntrinsicHelper::CmpgFloat:
buzbeefa57c472012-11-21 12:06:18 -08003253 CvtFPCompare(cu, call_inst, Instruction::CMPG_FLOAT);
buzbee0967a252012-09-14 10:43:54 -07003254 break;
3255 case greenland::IntrinsicHelper::CmplDouble:
buzbeefa57c472012-11-21 12:06:18 -08003256 CvtFPCompare(cu, call_inst, Instruction::CMPL_DOUBLE);
buzbee0967a252012-09-14 10:43:54 -07003257 break;
3258 case greenland::IntrinsicHelper::CmpgDouble:
buzbeefa57c472012-11-21 12:06:18 -08003259 CvtFPCompare(cu, call_inst, Instruction::CMPG_DOUBLE);
buzbee0967a252012-09-14 10:43:54 -07003260 break;
3261
3262 case greenland::IntrinsicHelper::CmpLong:
buzbeefa57c472012-11-21 12:06:18 -08003263 CvtLongCompare(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003264 break;
3265
3266 case greenland::IntrinsicHelper::SHLLong:
buzbeefa57c472012-11-21 12:06:18 -08003267 CvtShiftOp(cu, Instruction::SHL_LONG, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003268 break;
3269 case greenland::IntrinsicHelper::SHRLong:
buzbeefa57c472012-11-21 12:06:18 -08003270 CvtShiftOp(cu, Instruction::SHR_LONG, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003271 break;
3272 case greenland::IntrinsicHelper::USHRLong:
buzbeefa57c472012-11-21 12:06:18 -08003273 CvtShiftOp(cu, Instruction::USHR_LONG, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003274 break;
3275 case greenland::IntrinsicHelper::SHLInt:
buzbeefa57c472012-11-21 12:06:18 -08003276 CvtShiftOp(cu, Instruction::SHL_INT, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003277 break;
3278 case greenland::IntrinsicHelper::SHRInt:
buzbeefa57c472012-11-21 12:06:18 -08003279 CvtShiftOp(cu, Instruction::SHR_INT, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003280 break;
3281 case greenland::IntrinsicHelper::USHRInt:
buzbeefa57c472012-11-21 12:06:18 -08003282 CvtShiftOp(cu, Instruction::USHR_INT, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003283 break;
3284
3285 case greenland::IntrinsicHelper::CatchTargets: {
buzbeefa57c472012-11-21 12:06:18 -08003286 llvm::SwitchInst* sw_inst =
3287 llvm::dyn_cast<llvm::SwitchInst>(next_it);
3288 DCHECK(sw_inst != NULL);
buzbee0967a252012-09-14 10:43:54 -07003289 /*
3290 * Discard the edges and the following conditional branch.
3291 * Do a direct branch to the default target (which is the
3292 * "work" portion of the pair.
3293 * TODO: awful code layout - rework
3294 */
buzbeefa57c472012-11-21 12:06:18 -08003295 llvm::BasicBlock* target_bb = sw_inst->getDefaultDest();
3296 DCHECK(target_bb != NULL);
buzbee02031b12012-11-23 09:41:35 -08003297 cg->OpUnconditionalBranch(cu, cu->block_to_label_map.Get(target_bb));
buzbee0967a252012-09-14 10:43:54 -07003298 ++it;
3299 // Set next bb to default target - improves code layout
buzbeefa57c472012-11-21 12:06:18 -08003300 next_bb = target_bb;
buzbee0967a252012-09-14 10:43:54 -07003301 }
3302 break;
3303
3304 default:
buzbeefa57c472012-11-21 12:06:18 -08003305 LOG(FATAL) << "Unexpected intrinsic " << cu->intrinsic_helper->GetName(id);
buzbee0967a252012-09-14 10:43:54 -07003306 }
3307 }
3308 break;
3309
buzbeefa57c472012-11-21 12:06:18 -08003310 case llvm::Instruction::Br: CvtBr(cu, inst); break;
3311 case llvm::Instruction::Add: CvtBinOp(cu, kOpAdd, inst); break;
3312 case llvm::Instruction::Sub: CvtBinOp(cu, kOpSub, inst); break;
3313 case llvm::Instruction::Mul: CvtBinOp(cu, kOpMul, inst); break;
3314 case llvm::Instruction::SDiv: CvtBinOp(cu, kOpDiv, inst); break;
3315 case llvm::Instruction::SRem: CvtBinOp(cu, kOpRem, inst); break;
3316 case llvm::Instruction::And: CvtBinOp(cu, kOpAnd, inst); break;
3317 case llvm::Instruction::Or: CvtBinOp(cu, kOpOr, inst); break;
3318 case llvm::Instruction::Xor: CvtBinOp(cu, kOpXor, inst); break;
3319 case llvm::Instruction::PHI: CvtPhi(cu, inst); break;
3320 case llvm::Instruction::Ret: CvtRet(cu, inst); break;
3321 case llvm::Instruction::FAdd: CvtBinFPOp(cu, kOpAdd, inst); break;
3322 case llvm::Instruction::FSub: CvtBinFPOp(cu, kOpSub, inst); break;
3323 case llvm::Instruction::FMul: CvtBinFPOp(cu, kOpMul, inst); break;
3324 case llvm::Instruction::FDiv: CvtBinFPOp(cu, kOpDiv, inst); break;
3325 case llvm::Instruction::FRem: CvtBinFPOp(cu, kOpRem, inst); break;
3326 case llvm::Instruction::SIToFP: CvtIntToFP(cu, inst); break;
3327 case llvm::Instruction::FPTrunc: CvtDoubleToFloat(cu, inst); break;
3328 case llvm::Instruction::FPExt: CvtFloatToDouble(cu, inst); break;
3329 case llvm::Instruction::Trunc: CvtTrunc(cu, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003330
buzbeefa57c472012-11-21 12:06:18 -08003331 case llvm::Instruction::ZExt: CvtIntExt(cu, inst, false /* signed */);
buzbee0967a252012-09-14 10:43:54 -07003332 break;
buzbeefa57c472012-11-21 12:06:18 -08003333 case llvm::Instruction::SExt: CvtIntExt(cu, inst, true /* signed */);
buzbee0967a252012-09-14 10:43:54 -07003334 break;
3335
buzbeefa57c472012-11-21 12:06:18 -08003336 case llvm::Instruction::Switch: CvtSwitch(cu, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003337
3338 case llvm::Instruction::Unreachable:
3339 break; // FIXME: can we really ignore these?
3340
3341 case llvm::Instruction::Shl:
3342 case llvm::Instruction::LShr:
3343 case llvm::Instruction::AShr:
3344 case llvm::Instruction::Invoke:
3345 case llvm::Instruction::FPToUI:
TDYa1274ec8ccd2012-08-11 07:04:57 -07003346 case llvm::Instruction::FPToSI:
buzbee0967a252012-09-14 10:43:54 -07003347 case llvm::Instruction::UIToFP:
3348 case llvm::Instruction::PtrToInt:
3349 case llvm::Instruction::IntToPtr:
3350 case llvm::Instruction::FCmp:
3351 case llvm::Instruction::URem:
3352 case llvm::Instruction::UDiv:
3353 case llvm::Instruction::Resume:
3354 case llvm::Instruction::Alloca:
3355 case llvm::Instruction::GetElementPtr:
3356 case llvm::Instruction::Fence:
3357 case llvm::Instruction::AtomicCmpXchg:
3358 case llvm::Instruction::AtomicRMW:
3359 case llvm::Instruction::BitCast:
3360 case llvm::Instruction::VAArg:
3361 case llvm::Instruction::Select:
3362 case llvm::Instruction::UserOp1:
3363 case llvm::Instruction::UserOp2:
3364 case llvm::Instruction::ExtractElement:
3365 case llvm::Instruction::InsertElement:
3366 case llvm::Instruction::ShuffleVector:
3367 case llvm::Instruction::ExtractValue:
3368 case llvm::Instruction::InsertValue:
3369 case llvm::Instruction::LandingPad:
3370 case llvm::Instruction::IndirectBr:
3371 case llvm::Instruction::Load:
3372 case llvm::Instruction::Store:
3373 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3374
3375 default:
3376 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3377 break;
buzbeead8f15e2012-06-18 14:49:45 -07003378 }
3379 }
buzbee2cfc6392012-05-07 14:51:40 -07003380
buzbeefa57c472012-11-21 12:06:18 -08003381 if (head_lir != NULL) {
3382 ApplyLocalOptimizations(cu, head_lir, cu->last_lir_insn);
buzbee2cfc6392012-05-07 14:51:40 -07003383 }
buzbeefa57c472012-11-21 12:06:18 -08003384 if (next_bb != NULL) {
3385 bb = next_bb;
3386 next_bb = NULL;
buzbee6969d502012-06-15 16:40:31 -07003387 }
buzbee6969d502012-06-15 16:40:31 -07003388 }
buzbee2cfc6392012-05-07 14:51:40 -07003389 return false;
3390}
3391
3392/*
3393 * Convert LLVM_IR to MIR:
3394 * o Iterate through the LLVM_IR and construct a graph using
3395 * standard MIR building blocks.
3396 * o Perform a basic-block optimization pass to remove unnecessary
3397 * store/load sequences.
3398 * o Convert the LLVM Value operands into RegLocations where applicable.
buzbeefa57c472012-11-21 12:06:18 -08003399 * o Create ssa_rep def/use operand arrays for each converted LLVM opcode
buzbee2cfc6392012-05-07 14:51:40 -07003400 * o Perform register promotion
3401 * o Iterate through the graph a basic block at a time, generating
3402 * LIR.
3403 * o Assemble LIR as usual.
3404 * o Profit.
3405 */
buzbeefa57c472012-11-21 12:06:18 -08003406void MethodBitcode2LIR(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -07003407{
buzbee02031b12012-11-23 09:41:35 -08003408 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08003409 llvm::Function* func = cu->func;
3410 int num_basic_blocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003411 // Allocate a list for LIR basic block labels
buzbeefa57c472012-11-21 12:06:18 -08003412 cu->block_label_list =
3413 static_cast<LIR*>(NewMem(cu, sizeof(LIR) * num_basic_blocks, true, kAllocLIR));
3414 LIR* label_list = cu->block_label_list;
3415 int next_label = 0;
buzbee28c9a832012-11-21 15:39:13 -08003416 for (llvm::Function::iterator i = func->begin(), e = func->end(); i != e; ++i) {
buzbeefa57c472012-11-21 12:06:18 -08003417 cu->block_to_label_map.Put(static_cast<llvm::BasicBlock*>(i),
3418 &label_list[next_label++]);
buzbee2cfc6392012-05-07 14:51:40 -07003419 }
buzbeead8f15e2012-06-18 14:49:45 -07003420
3421 /*
buzbeefa57c472012-11-21 12:06:18 -08003422 * Keep honest - clear reg_locations, Value => RegLocation,
buzbeead8f15e2012-06-18 14:49:45 -07003423 * promotion map and VmapTables.
3424 */
buzbeefa57c472012-11-21 12:06:18 -08003425 cu->loc_map.clear(); // Start fresh
3426 cu->reg_location = NULL;
buzbee28c9a832012-11-21 15:39:13 -08003427 for (int i = 0; i < cu->num_dalvik_registers + cu->num_compiler_temps + 1; i++) {
buzbeefa57c472012-11-21 12:06:18 -08003428 cu->promotion_map[i].core_location = kLocDalvikFrame;
3429 cu->promotion_map[i].fp_location = kLocDalvikFrame;
buzbeead8f15e2012-06-18 14:49:45 -07003430 }
buzbeefa57c472012-11-21 12:06:18 -08003431 cu->core_spill_mask = 0;
3432 cu->num_core_spills = 0;
3433 cu->fp_spill_mask = 0;
3434 cu->num_fp_spills = 0;
3435 cu->core_vmap_table.clear();
3436 cu->fp_vmap_table.clear();
buzbeead8f15e2012-06-18 14:49:45 -07003437
3438 /*
3439 * At this point, we've lost all knowledge of register promotion.
3440 * Rebuild that info from the MethodInfo intrinsic (if it
buzbeeca7a5e42012-08-20 11:12:18 -07003441 * exists - not required for correctness). Normally, this will
3442 * be the first instruction we encounter, so we won't have to iterate
3443 * through everything.
buzbeead8f15e2012-06-18 14:49:45 -07003444 */
buzbee28c9a832012-11-21 15:39:13 -08003445 for (llvm::inst_iterator i = llvm::inst_begin(func), e = llvm::inst_end(func); i != e; ++i) {
buzbeefa57c472012-11-21 12:06:18 -08003446 llvm::CallInst* call_inst = llvm::dyn_cast<llvm::CallInst>(&*i);
3447 if (call_inst != NULL) {
3448 llvm::Function* callee = call_inst->getCalledFunction();
buzbeeca7a5e42012-08-20 11:12:18 -07003449 greenland::IntrinsicHelper::IntrinsicId id =
buzbeefa57c472012-11-21 12:06:18 -08003450 cu->intrinsic_helper->GetIntrinsicId(callee);
buzbeeca7a5e42012-08-20 11:12:18 -07003451 if (id == greenland::IntrinsicHelper::MethodInfo) {
buzbeefa57c472012-11-21 12:06:18 -08003452 if (cu->verbose) {
buzbeeca7a5e42012-08-20 11:12:18 -07003453 LOG(INFO) << "Found MethodInfo";
3454 }
buzbeefa57c472012-11-21 12:06:18 -08003455 llvm::MDNode* reg_info_node = call_inst->getMetadata("RegInfo");
3456 if (reg_info_node != NULL) {
3457 llvm::ConstantInt* num_ins_value =
3458 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(0));
3459 llvm::ConstantInt* num_regs_value =
3460 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(1));
3461 llvm::ConstantInt* num_outs_value =
3462 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(2));
3463 llvm::ConstantInt* num_compiler_temps_value =
3464 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(3));
3465 llvm::ConstantInt* num_ssa_regs_value =
3466 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(4));
3467 if (cu->verbose) {
3468 LOG(INFO) << "RegInfo - Ins:" << num_ins_value->getZExtValue()
3469 << ", Regs:" << num_regs_value->getZExtValue()
3470 << ", Outs:" << num_outs_value->getZExtValue()
3471 << ", CTemps:" << num_compiler_temps_value->getZExtValue()
3472 << ", SSARegs:" << num_ssa_regs_value->getZExtValue();
buzbeeca7a5e42012-08-20 11:12:18 -07003473 }
3474 }
buzbeefa57c472012-11-21 12:06:18 -08003475 llvm::MDNode* pmap_info_node = call_inst->getMetadata("PromotionMap");
3476 if (pmap_info_node != NULL) {
3477 int elems = pmap_info_node->getNumOperands();
3478 if (cu->verbose) {
buzbeeca7a5e42012-08-20 11:12:18 -07003479 LOG(INFO) << "PMap size: " << elems;
3480 }
3481 for (int i = 0; i < elems; i++) {
buzbeefa57c472012-11-21 12:06:18 -08003482 llvm::ConstantInt* raw_map_data =
3483 static_cast<llvm::ConstantInt*>(pmap_info_node->getOperand(i));
3484 uint32_t map_data = raw_map_data->getZExtValue();
3485 PromotionMap* p = &cu->promotion_map[i];
3486 p->first_in_pair = (map_data >> 24) & 0xff;
3487 p->FpReg = (map_data >> 16) & 0xff;
3488 p->core_reg = (map_data >> 8) & 0xff;
3489 p->fp_location = static_cast<RegLocationType>((map_data >> 4) & 0xf);
3490 if (p->fp_location == kLocPhysReg) {
3491 RecordFpPromotion(cu, p->FpReg, i);
buzbeeca7a5e42012-08-20 11:12:18 -07003492 }
buzbeefa57c472012-11-21 12:06:18 -08003493 p->core_location = static_cast<RegLocationType>(map_data & 0xf);
3494 if (p->core_location == kLocPhysReg) {
3495 RecordCorePromotion(cu, p->core_reg, i);
buzbeeca7a5e42012-08-20 11:12:18 -07003496 }
3497 }
buzbeefa57c472012-11-21 12:06:18 -08003498 if (cu->verbose) {
3499 DumpPromotionMap(cu);
buzbeeca7a5e42012-08-20 11:12:18 -07003500 }
3501 }
3502 break;
3503 }
3504 }
3505 }
buzbee02031b12012-11-23 09:41:35 -08003506 cg->AdjustSpillMask(cu);
buzbeefa57c472012-11-21 12:06:18 -08003507 cu->frame_size = ComputeFrameSize(cu);
buzbeead8f15e2012-06-18 14:49:45 -07003508
3509 // Create RegLocations for arguments
buzbeefa57c472012-11-21 12:06:18 -08003510 llvm::Function::arg_iterator it(cu->func->arg_begin());
3511 llvm::Function::arg_iterator it_end(cu->func->arg_end());
buzbeead8f15e2012-06-18 14:49:45 -07003512 for (; it != it_end; ++it) {
3513 llvm::Value* val = it;
buzbeefa57c472012-11-21 12:06:18 -08003514 CreateLocFromValue(cu, val);
buzbeead8f15e2012-06-18 14:49:45 -07003515 }
3516 // Create RegLocations for all non-argument defintions
buzbee28c9a832012-11-21 15:39:13 -08003517 for (llvm::inst_iterator i = llvm::inst_begin(func), e = llvm::inst_end(func); i != e; ++i) {
buzbeead8f15e2012-06-18 14:49:45 -07003518 llvm::Value* val = &*i;
3519 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
buzbeefa57c472012-11-21 12:06:18 -08003520 CreateLocFromValue(cu, val);
buzbeead8f15e2012-06-18 14:49:45 -07003521 }
3522 }
3523
buzbee2cfc6392012-05-07 14:51:40 -07003524 // Walk the blocks, generating code.
buzbee28c9a832012-11-21 15:39:13 -08003525 for (llvm::Function::iterator i = cu->func->begin(), e = cu->func->end(); i != e; ++i) {
buzbeefa57c472012-11-21 12:06:18 -08003526 BitcodeBlockCodeGen(cu, static_cast<llvm::BasicBlock*>(i));
buzbee2cfc6392012-05-07 14:51:40 -07003527 }
3528
buzbee02031b12012-11-23 09:41:35 -08003529 cg->HandleSuspendLaunchPads(cu);
buzbee2cfc6392012-05-07 14:51:40 -07003530
buzbee02031b12012-11-23 09:41:35 -08003531 cg->HandleThrowLaunchPads(cu);
buzbee2cfc6392012-05-07 14:51:40 -07003532
buzbee02031b12012-11-23 09:41:35 -08003533 cg->HandleIntrinsicLaunchPads(cu);
buzbee2cfc6392012-05-07 14:51:40 -07003534
buzbeefa57c472012-11-21 12:06:18 -08003535 cu->func->eraseFromParent();
3536 cu->func = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07003537}
3538
3539
3540} // namespace art