blob: a2c2bbcca650877dbdc4e432026feb09b256af63 [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 "codegen_util.h"
Brian Carlstrom641ce032013-01-31 15:21:37 -080031#include "compiler/compiler_internals.h"
32#include "local_optimizations.h"
buzbee1bc37c62012-11-20 13:35:41 -080033#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
TDYa127dc5daa02013-01-09 21:31:37 +080056 greenland::IntrinsicHelper::IntrinsicId id =
57 greenland::IntrinsicHelper::SetVReg;
58 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id);
59 int v_reg = SRegToVReg(cu, s_reg);
60 llvm::Value* table_slot = cu->irb->getInt32(v_reg);
61 llvm::Value* args[] = { table_slot, val };
62 cu->irb->CreateCall(func, args);
buzbee26f10ee2012-12-21 11:16:29 -080063}
64
buzbee2cfc6392012-05-07 14:51:40 -070065// Replace the placeholder value with the real definition
buzbee26f10ee2012-12-21 11:16:29 -080066static void DefineValueOnly(CompilationUnit* cu, llvm::Value* val, int s_reg)
buzbee2cfc6392012-05-07 14:51:40 -070067{
buzbeefa57c472012-11-21 12:06:18 -080068 llvm::Value* placeholder = GetLLVMValue(cu, s_reg);
buzbee9a2487f2012-07-26 14:01:13 -070069 if (placeholder == NULL) {
70 // This can happen on instruction rewrite on verification failure
Bill Buzbeec9f40dd2012-08-15 11:35:25 -070071 LOG(WARNING) << "Null placeholder";
buzbee9a2487f2012-07-26 14:01:13 -070072 return;
73 }
buzbee2cfc6392012-05-07 14:51:40 -070074 placeholder->replaceAllUsesWith(val);
75 val->takeName(placeholder);
buzbeefa57c472012-11-21 12:06:18 -080076 cu->llvm_values.elem_list[s_reg] = reinterpret_cast<uintptr_t>(val);
buzbee4be777b2012-07-12 14:38:18 -070077 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(placeholder);
78 DCHECK(inst != NULL);
79 inst->eraseFromParent();
TDYa1278e950c12012-11-02 09:58:19 -070080
buzbee26f10ee2012-12-21 11:16:29 -080081}
82
83static void DefineValue(CompilationUnit* cu, llvm::Value* val, int s_reg)
84{
85 DefineValueOnly(cu, val, s_reg);
86 SetVregOnValue(cu, val, s_reg);
buzbee2cfc6392012-05-07 14:51:40 -070087}
88
buzbeefa57c472012-11-21 12:06:18 -080089static llvm::Type* LlvmTypeFromLocRec(CompilationUnit* cu, RegLocation loc)
buzbee2cfc6392012-05-07 14:51:40 -070090{
91 llvm::Type* res = NULL;
92 if (loc.wide) {
93 if (loc.fp)
buzbeefa57c472012-11-21 12:06:18 -080094 res = cu->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070095 else
buzbeefa57c472012-11-21 12:06:18 -080096 res = cu->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070097 } else {
98 if (loc.fp) {
buzbeefa57c472012-11-21 12:06:18 -080099 res = cu->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -0700100 } else {
101 if (loc.ref)
buzbeefa57c472012-11-21 12:06:18 -0800102 res = cu->irb->GetJObjectTy();
buzbee2cfc6392012-05-07 14:51:40 -0700103 else
buzbeefa57c472012-11-21 12:06:18 -0800104 res = cu->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -0700105 }
106 }
107 return res;
108}
109
buzbeead8f15e2012-06-18 14:49:45 -0700110/* Create an in-memory RegLocation from an llvm Value. */
buzbeefa57c472012-11-21 12:06:18 -0800111static void CreateLocFromValue(CompilationUnit* cu, llvm::Value* val)
buzbeead8f15e2012-06-18 14:49:45 -0700112{
113 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
114 std::string s(val->getName().str());
buzbeefa57c472012-11-21 12:06:18 -0800115 const char* val_name = s.c_str();
116 SafeMap<llvm::Value*, RegLocation>::iterator it = cu->loc_map.find(val);
117 DCHECK(it == cu->loc_map.end()) << " - already defined: " << val_name;
118 int base_sreg = INVALID_SREG;
buzbeead8f15e2012-06-18 14:49:45 -0700119 int subscript = -1;
buzbeefa57c472012-11-21 12:06:18 -0800120 sscanf(val_name, "v%d_%d", &base_sreg, &subscript);
121 if ((base_sreg == INVALID_SREG) && (!strcmp(val_name, "method"))) {
122 base_sreg = SSA_METHOD_BASEREG;
buzbeead8f15e2012-06-18 14:49:45 -0700123 subscript = 0;
124 }
buzbeefa57c472012-11-21 12:06:18 -0800125 DCHECK_NE(base_sreg, INVALID_SREG);
buzbeead8f15e2012-06-18 14:49:45 -0700126 DCHECK_NE(subscript, -1);
127 // TODO: redo during C++'ification
128 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
129 INVALID_REG, INVALID_SREG, INVALID_SREG};
130 llvm::Type* ty = val->getType();
buzbeefa57c472012-11-21 12:06:18 -0800131 loc.wide = ((ty == cu->irb->getInt64Ty()) ||
132 (ty == cu->irb->getDoubleTy()));
buzbeead8f15e2012-06-18 14:49:45 -0700133 loc.defined = true;
buzbeeca7a5e42012-08-20 11:12:18 -0700134 loc.home = false; // May change during promotion
buzbeefa57c472012-11-21 12:06:18 -0800135 loc.s_reg_low = base_sreg;
136 loc.orig_sreg = cu->loc_map.size();
137 PromotionMap p_map = cu->promotion_map[base_sreg];
138 if (ty == cu->irb->getFloatTy()) {
buzbeeca7a5e42012-08-20 11:12:18 -0700139 loc.fp = true;
buzbeefa57c472012-11-21 12:06:18 -0800140 if (p_map.fp_location == kLocPhysReg) {
141 loc.low_reg = p_map.FpReg;
buzbeeca7a5e42012-08-20 11:12:18 -0700142 loc.location = kLocPhysReg;
143 loc.home = true;
144 }
buzbeefa57c472012-11-21 12:06:18 -0800145 } else if (ty == cu->irb->getDoubleTy()) {
buzbeeca7a5e42012-08-20 11:12:18 -0700146 loc.fp = true;
buzbeefa57c472012-11-21 12:06:18 -0800147 PromotionMap p_map_high = cu->promotion_map[base_sreg + 1];
148 if ((p_map.fp_location == kLocPhysReg) &&
149 (p_map_high.fp_location == kLocPhysReg) &&
150 ((p_map.FpReg & 0x1) == 0) &&
151 (p_map.FpReg + 1 == p_map_high.FpReg)) {
152 loc.low_reg = p_map.FpReg;
153 loc.high_reg = p_map_high.FpReg;
buzbeeca7a5e42012-08-20 11:12:18 -0700154 loc.location = kLocPhysReg;
155 loc.home = true;
156 }
buzbeefa57c472012-11-21 12:06:18 -0800157 } else if (ty == cu->irb->GetJObjectTy()) {
buzbeeca7a5e42012-08-20 11:12:18 -0700158 loc.ref = true;
buzbeefa57c472012-11-21 12:06:18 -0800159 if (p_map.core_location == kLocPhysReg) {
160 loc.low_reg = p_map.core_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700161 loc.location = kLocPhysReg;
162 loc.home = true;
163 }
buzbeefa57c472012-11-21 12:06:18 -0800164 } else if (ty == cu->irb->getInt64Ty()) {
buzbeeca7a5e42012-08-20 11:12:18 -0700165 loc.core = true;
buzbeefa57c472012-11-21 12:06:18 -0800166 PromotionMap p_map_high = cu->promotion_map[base_sreg + 1];
167 if ((p_map.core_location == kLocPhysReg) &&
168 (p_map_high.core_location == kLocPhysReg)) {
169 loc.low_reg = p_map.core_reg;
170 loc.high_reg = p_map_high.core_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700171 loc.location = kLocPhysReg;
172 loc.home = true;
173 }
174 } else {
175 loc.core = true;
buzbeefa57c472012-11-21 12:06:18 -0800176 if (p_map.core_location == kLocPhysReg) {
177 loc.low_reg = p_map.core_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700178 loc.location = kLocPhysReg;
179 loc.home = true;
180 }
181 }
182
buzbeefa57c472012-11-21 12:06:18 -0800183 if (cu->verbose && loc.home) {
buzbeeca7a5e42012-08-20 11:12:18 -0700184 if (loc.wide) {
buzbeefa57c472012-11-21 12:06:18 -0800185 LOG(INFO) << "Promoted wide " << s << " to regs " << loc.low_reg << "/" << loc.high_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700186 } else {
buzbeefa57c472012-11-21 12:06:18 -0800187 LOG(INFO) << "Promoted " << s << " to reg " << loc.low_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700188 }
189 }
buzbeefa57c472012-11-21 12:06:18 -0800190 cu->loc_map.Put(val, loc);
buzbeead8f15e2012-06-18 14:49:45 -0700191}
buzbeeaad94382012-11-21 07:40:50 -0800192
buzbeefa57c472012-11-21 12:06:18 -0800193static void InitIR(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -0700194{
buzbeefa57c472012-11-21 12:06:18 -0800195 LLVMInfo* llvm_info = cu->llvm_info;
196 if (llvm_info == NULL) {
197 CompilerTls* tls = cu->compiler->GetTls();
buzbee4df2bbd2012-10-11 14:46:06 -0700198 CHECK(tls != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800199 llvm_info = static_cast<LLVMInfo*>(tls->GetLLVMInfo());
200 if (llvm_info == NULL) {
201 llvm_info = new LLVMInfo();
202 tls->SetLLVMInfo(llvm_info);
buzbee4df2bbd2012-10-11 14:46:06 -0700203 }
204 }
buzbeefa57c472012-11-21 12:06:18 -0800205 cu->context = llvm_info->GetLLVMContext();
206 cu->module = llvm_info->GetLLVMModule();
207 cu->intrinsic_helper = llvm_info->GetIntrinsicHelper();
208 cu->irb = llvm_info->GetIRBuilder();
buzbee2cfc6392012-05-07 14:51:40 -0700209}
210
buzbeefa57c472012-11-21 12:06:18 -0800211static const char* LlvmSSAName(CompilationUnit* cu, int ssa_reg) {
212 return GET_ELEM_N(cu->ssa_strings, char*, ssa_reg);
buzbee2cfc6392012-05-07 14:51:40 -0700213}
214
buzbeefa57c472012-11-21 12:06:18 -0800215llvm::BasicBlock* FindCaseTarget(CompilationUnit* cu, uint32_t vaddr)
buzbeef58c12c2012-07-03 15:06:29 -0700216{
buzbeefa57c472012-11-21 12:06:18 -0800217 BasicBlock* bb = FindBlock(cu, vaddr);
buzbeef58c12c2012-07-03 15:06:29 -0700218 DCHECK(bb != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800219 return GetLLVMBlock(cu, bb->id);
buzbeef58c12c2012-07-03 15:06:29 -0700220}
221
buzbeefa57c472012-11-21 12:06:18 -0800222static void ConvertPackedSwitch(CompilationUnit* cu, BasicBlock* bb,
223 int32_t table_offset, RegLocation rl_src)
buzbeef58c12c2012-07-03 15:06:29 -0700224{
225 const Instruction::PackedSwitchPayload* payload =
226 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
buzbeefa57c472012-11-21 12:06:18 -0800227 cu->insns + cu->current_dalvik_offset + table_offset);
buzbeef58c12c2012-07-03 15:06:29 -0700228
buzbeefa57c472012-11-21 12:06:18 -0800229 llvm::Value* value = GetLLVMValue(cu, rl_src.orig_sreg);
buzbeef58c12c2012-07-03 15:06:29 -0700230
231 llvm::SwitchInst* sw =
buzbeefa57c472012-11-21 12:06:18 -0800232 cu->irb->CreateSwitch(value, GetLLVMBlock(cu, bb->fall_through->id),
buzbeef58c12c2012-07-03 15:06:29 -0700233 payload->case_count);
234
235 for (uint16_t i = 0; i < payload->case_count; ++i) {
buzbeefa57c472012-11-21 12:06:18 -0800236 llvm::BasicBlock* llvm_bb =
237 FindCaseTarget(cu, cu->current_dalvik_offset + payload->targets[i]);
238 sw->addCase(cu->irb->getInt32(payload->first_key + i), llvm_bb);
buzbeef58c12c2012-07-03 15:06:29 -0700239 }
buzbeefa57c472012-11-21 12:06:18 -0800240 llvm::MDNode* switch_node =
241 llvm::MDNode::get(*cu->context, cu->irb->getInt32(table_offset));
242 sw->setMetadata("SwitchTable", switch_node);
buzbeef58c12c2012-07-03 15:06:29 -0700243 bb->taken = NULL;
buzbeefa57c472012-11-21 12:06:18 -0800244 bb->fall_through = NULL;
buzbeef58c12c2012-07-03 15:06:29 -0700245}
246
buzbeefa57c472012-11-21 12:06:18 -0800247static void ConvertSparseSwitch(CompilationUnit* cu, BasicBlock* bb,
248 int32_t table_offset, RegLocation rl_src)
buzbeea1da8a52012-07-09 14:00:21 -0700249{
250 const Instruction::SparseSwitchPayload* payload =
251 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
buzbeefa57c472012-11-21 12:06:18 -0800252 cu->insns + cu->current_dalvik_offset + table_offset);
buzbeea1da8a52012-07-09 14:00:21 -0700253
254 const int32_t* keys = payload->GetKeys();
255 const int32_t* targets = payload->GetTargets();
256
buzbeefa57c472012-11-21 12:06:18 -0800257 llvm::Value* value = GetLLVMValue(cu, rl_src.orig_sreg);
buzbeea1da8a52012-07-09 14:00:21 -0700258
259 llvm::SwitchInst* sw =
buzbeefa57c472012-11-21 12:06:18 -0800260 cu->irb->CreateSwitch(value, GetLLVMBlock(cu, bb->fall_through->id),
buzbeea1da8a52012-07-09 14:00:21 -0700261 payload->case_count);
262
263 for (size_t i = 0; i < payload->case_count; ++i) {
buzbeefa57c472012-11-21 12:06:18 -0800264 llvm::BasicBlock* llvm_bb =
265 FindCaseTarget(cu, cu->current_dalvik_offset + targets[i]);
266 sw->addCase(cu->irb->getInt32(keys[i]), llvm_bb);
buzbeea1da8a52012-07-09 14:00:21 -0700267 }
buzbeefa57c472012-11-21 12:06:18 -0800268 llvm::MDNode* switch_node =
269 llvm::MDNode::get(*cu->context, cu->irb->getInt32(table_offset));
270 sw->setMetadata("SwitchTable", switch_node);
buzbeea1da8a52012-07-09 14:00:21 -0700271 bb->taken = NULL;
buzbeefa57c472012-11-21 12:06:18 -0800272 bb->fall_through = NULL;
buzbeea1da8a52012-07-09 14:00:21 -0700273}
274
buzbeefa57c472012-11-21 12:06:18 -0800275static void ConvertSget(CompilationUnit* cu, int32_t field_index,
276 greenland::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest)
buzbee4f1181f2012-06-22 13:52:12 -0700277{
buzbeefa57c472012-11-21 12:06:18 -0800278 llvm::Constant* field_idx = cu->irb->getInt32(field_index);
279 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
280 llvm::Value* res = cu->irb->CreateCall(intr, field_idx);
281 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700282}
283
buzbeefa57c472012-11-21 12:06:18 -0800284static void ConvertSput(CompilationUnit* cu, int32_t field_index,
285 greenland::IntrinsicHelper::IntrinsicId id, RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700286{
287 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800288 args.push_back(cu->irb->getInt32(field_index));
289 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
290 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
291 cu->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700292}
293
buzbeefa57c472012-11-21 12:06:18 -0800294static void ConvertFillArrayData(CompilationUnit* cu, int32_t offset, RegLocation rl_array)
buzbee101305f2012-06-28 18:00:56 -0700295{
296 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700297 id = greenland::IntrinsicHelper::HLFillArrayData;
buzbee101305f2012-06-28 18:00:56 -0700298 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800299 args.push_back(cu->irb->getInt32(offset));
300 args.push_back(GetLLVMValue(cu, rl_array.orig_sreg));
301 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
302 cu->irb->CreateCall(intr, args);
buzbee101305f2012-06-28 18:00:56 -0700303}
304
buzbeefa57c472012-11-21 12:06:18 -0800305static llvm::Value* EmitConst(CompilationUnit* cu, llvm::ArrayRef<llvm::Value*> src,
buzbeeaad94382012-11-21 07:40:50 -0800306 RegLocation loc)
buzbee2cfc6392012-05-07 14:51:40 -0700307{
308 greenland::IntrinsicHelper::IntrinsicId id;
309 if (loc.wide) {
310 if (loc.fp) {
311 id = greenland::IntrinsicHelper::ConstDouble;
312 } else {
313 id = greenland::IntrinsicHelper::ConstLong;
314 }
315 } else {
316 if (loc.fp) {
317 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700318 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700319 id = greenland::IntrinsicHelper::ConstObj;
320 } else {
321 id = greenland::IntrinsicHelper::ConstInt;
322 }
323 }
buzbeefa57c472012-11-21 12:06:18 -0800324 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
325 return cu->irb->CreateCall(intr, src);
buzbee2cfc6392012-05-07 14:51:40 -0700326}
buzbeeb03f4872012-06-11 15:22:11 -0700327
buzbeefa57c472012-11-21 12:06:18 -0800328static void EmitPopShadowFrame(CompilationUnit* cu)
buzbeeb03f4872012-06-11 15:22:11 -0700329{
buzbeefa57c472012-11-21 12:06:18 -0800330 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(
buzbeeb03f4872012-06-11 15:22:11 -0700331 greenland::IntrinsicHelper::PopShadowFrame);
buzbeefa57c472012-11-21 12:06:18 -0800332 cu->irb->CreateCall(intr);
buzbeeb03f4872012-06-11 15:22:11 -0700333}
334
buzbeefa57c472012-11-21 12:06:18 -0800335static llvm::Value* EmitCopy(CompilationUnit* cu, llvm::ArrayRef<llvm::Value*> src,
buzbeeaad94382012-11-21 07:40:50 -0800336 RegLocation loc)
buzbee2cfc6392012-05-07 14:51:40 -0700337{
338 greenland::IntrinsicHelper::IntrinsicId id;
339 if (loc.wide) {
340 if (loc.fp) {
341 id = greenland::IntrinsicHelper::CopyDouble;
342 } else {
343 id = greenland::IntrinsicHelper::CopyLong;
344 }
345 } else {
346 if (loc.fp) {
347 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700348 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700349 id = greenland::IntrinsicHelper::CopyObj;
350 } else {
351 id = greenland::IntrinsicHelper::CopyInt;
352 }
353 }
buzbeefa57c472012-11-21 12:06:18 -0800354 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
355 return cu->irb->CreateCall(intr, src);
buzbee2cfc6392012-05-07 14:51:40 -0700356}
357
buzbeefa57c472012-11-21 12:06:18 -0800358static void ConvertMoveException(CompilationUnit* cu, RegLocation rl_dest)
buzbee32412962012-06-26 16:27:56 -0700359{
buzbeefa57c472012-11-21 12:06:18 -0800360 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(
buzbee32412962012-06-26 16:27:56 -0700361 greenland::IntrinsicHelper::GetException);
buzbeefa57c472012-11-21 12:06:18 -0800362 llvm::Value* res = cu->irb->CreateCall(func);
363 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee32412962012-06-26 16:27:56 -0700364}
365
buzbeefa57c472012-11-21 12:06:18 -0800366static void ConvertThrow(CompilationUnit* cu, RegLocation rl_src)
buzbee32412962012-06-26 16:27:56 -0700367{
buzbeefa57c472012-11-21 12:06:18 -0800368 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
369 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(
TDYa127f71bf5a2012-07-29 20:09:52 -0700370 greenland::IntrinsicHelper::HLThrowException);
buzbeefa57c472012-11-21 12:06:18 -0800371 cu->irb->CreateCall(func, src);
buzbee32412962012-06-26 16:27:56 -0700372}
373
buzbeefa57c472012-11-21 12:06:18 -0800374static void ConvertMonitorEnterExit(CompilationUnit* cu, int opt_flags,
buzbeeaad94382012-11-21 07:40:50 -0800375 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800376 RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700377{
378 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800379 args.push_back(cu->irb->getInt32(opt_flags));
380 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
381 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id);
382 cu->irb->CreateCall(func, args);
buzbee8fa0fda2012-06-27 15:44:52 -0700383}
384
buzbeefa57c472012-11-21 12:06:18 -0800385static void ConvertArrayLength(CompilationUnit* cu, int opt_flags,
386 RegLocation rl_dest, RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700387{
388 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800389 args.push_back(cu->irb->getInt32(opt_flags));
390 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
391 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700392 greenland::IntrinsicHelper::OptArrayLength);
buzbeefa57c472012-11-21 12:06:18 -0800393 llvm::Value* res = cu->irb->CreateCall(func, args);
394 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700395}
396
buzbeefa57c472012-11-21 12:06:18 -0800397static void EmitSuspendCheck(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -0700398{
399 greenland::IntrinsicHelper::IntrinsicId id =
400 greenland::IntrinsicHelper::CheckSuspend;
buzbeefa57c472012-11-21 12:06:18 -0800401 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
402 cu->irb->CreateCall(intr);
buzbee2cfc6392012-05-07 14:51:40 -0700403}
404
buzbeefa57c472012-11-21 12:06:18 -0800405static llvm::Value* ConvertCompare(CompilationUnit* cu, ConditionCode cc,
buzbeeaad94382012-11-21 07:40:50 -0800406 llvm::Value* src1, llvm::Value* src2)
buzbee2cfc6392012-05-07 14:51:40 -0700407{
408 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700409 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700410 switch(cc) {
buzbeefa57c472012-11-21 12:06:18 -0800411 case kCondEq: res = cu->irb->CreateICmpEQ(src1, src2); break;
412 case kCondNe: res = cu->irb->CreateICmpNE(src1, src2); break;
413 case kCondLt: res = cu->irb->CreateICmpSLT(src1, src2); break;
414 case kCondGe: res = cu->irb->CreateICmpSGE(src1, src2); break;
415 case kCondGt: res = cu->irb->CreateICmpSGT(src1, src2); break;
416 case kCondLe: res = cu->irb->CreateICmpSLE(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700417 default: LOG(FATAL) << "Unexpected cc value " << cc;
418 }
419 return res;
420}
421
buzbeefa57c472012-11-21 12:06:18 -0800422static void ConvertCompareAndBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
423 ConditionCode cc, RegLocation rl_src1, RegLocation rl_src2)
buzbee2cfc6392012-05-07 14:51:40 -0700424{
buzbeefa57c472012-11-21 12:06:18 -0800425 if (bb->taken->start_offset <= mir->offset) {
426 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -0700427 }
buzbeefa57c472012-11-21 12:06:18 -0800428 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
429 llvm::Value* src2 = GetLLVMValue(cu, rl_src2.orig_sreg);
430 llvm::Value* cond_value = ConvertCompare(cu, cc, src1, src2);
431 cond_value->setName(StringPrintf("t%d", cu->temp_name++));
432 cu->irb->CreateCondBr(cond_value, GetLLVMBlock(cu, bb->taken->id),
433 GetLLVMBlock(cu, bb->fall_through->id));
buzbee6969d502012-06-15 16:40:31 -0700434 // Don't redo the fallthrough branch in the BB driver
buzbeefa57c472012-11-21 12:06:18 -0800435 bb->fall_through = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700436}
437
buzbeefa57c472012-11-21 12:06:18 -0800438static void ConvertCompareZeroAndBranch(CompilationUnit* cu, BasicBlock* bb,
439 MIR* mir, ConditionCode cc, RegLocation rl_src1)
buzbee2cfc6392012-05-07 14:51:40 -0700440{
buzbeefa57c472012-11-21 12:06:18 -0800441 if (bb->taken->start_offset <= mir->offset) {
442 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -0700443 }
buzbeefa57c472012-11-21 12:06:18 -0800444 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700445 llvm::Value* src2;
buzbeefa57c472012-11-21 12:06:18 -0800446 if (rl_src1.ref) {
447 src2 = cu->irb->GetJNull();
buzbee2cfc6392012-05-07 14:51:40 -0700448 } else {
buzbeefa57c472012-11-21 12:06:18 -0800449 src2 = cu->irb->getInt32(0);
buzbee2cfc6392012-05-07 14:51:40 -0700450 }
buzbeefa57c472012-11-21 12:06:18 -0800451 llvm::Value* cond_value = ConvertCompare(cu, cc, src1, src2);
452 cu->irb->CreateCondBr(cond_value, GetLLVMBlock(cu, bb->taken->id),
453 GetLLVMBlock(cu, bb->fall_through->id));
buzbee6969d502012-06-15 16:40:31 -0700454 // Don't redo the fallthrough branch in the BB driver
buzbeefa57c472012-11-21 12:06:18 -0800455 bb->fall_through = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700456}
457
buzbeefa57c472012-11-21 12:06:18 -0800458static llvm::Value* GenDivModOp(CompilationUnit* cu, bool is_div, bool is_long,
buzbeeaad94382012-11-21 07:40:50 -0800459 llvm::Value* src1, llvm::Value* src2)
buzbee2cfc6392012-05-07 14:51:40 -0700460{
461 greenland::IntrinsicHelper::IntrinsicId id;
buzbeefa57c472012-11-21 12:06:18 -0800462 if (is_long) {
463 if (is_div) {
buzbee2cfc6392012-05-07 14:51:40 -0700464 id = greenland::IntrinsicHelper::DivLong;
465 } else {
466 id = greenland::IntrinsicHelper::RemLong;
467 }
Logan Chien554e6072012-07-23 20:00:01 -0700468 } else {
buzbeefa57c472012-11-21 12:06:18 -0800469 if (is_div) {
buzbee2cfc6392012-05-07 14:51:40 -0700470 id = greenland::IntrinsicHelper::DivInt;
471 } else {
472 id = greenland::IntrinsicHelper::RemInt;
Logan Chien554e6072012-07-23 20:00:01 -0700473 }
buzbee2cfc6392012-05-07 14:51:40 -0700474 }
buzbeefa57c472012-11-21 12:06:18 -0800475 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee2cfc6392012-05-07 14:51:40 -0700476 llvm::SmallVector<llvm::Value*, 2>args;
477 args.push_back(src1);
478 args.push_back(src2);
buzbeefa57c472012-11-21 12:06:18 -0800479 return cu->irb->CreateCall(intr, args);
buzbee2cfc6392012-05-07 14:51:40 -0700480}
481
buzbeefa57c472012-11-21 12:06:18 -0800482static llvm::Value* GenArithOp(CompilationUnit* cu, OpKind op, bool is_long,
buzbeeaad94382012-11-21 07:40:50 -0800483 llvm::Value* src1, llvm::Value* src2)
buzbee2cfc6392012-05-07 14:51:40 -0700484{
485 llvm::Value* res = NULL;
486 switch(op) {
buzbeefa57c472012-11-21 12:06:18 -0800487 case kOpAdd: res = cu->irb->CreateAdd(src1, src2); break;
488 case kOpSub: res = cu->irb->CreateSub(src1, src2); break;
489 case kOpRsub: res = cu->irb->CreateSub(src2, src1); break;
490 case kOpMul: res = cu->irb->CreateMul(src1, src2); break;
491 case kOpOr: res = cu->irb->CreateOr(src1, src2); break;
492 case kOpAnd: res = cu->irb->CreateAnd(src1, src2); break;
493 case kOpXor: res = cu->irb->CreateXor(src1, src2); break;
494 case kOpDiv: res = GenDivModOp(cu, true, is_long, src1, src2); break;
495 case kOpRem: res = GenDivModOp(cu, false, is_long, src1, src2); break;
496 case kOpLsl: res = cu->irb->CreateShl(src1, src2); break;
497 case kOpLsr: res = cu->irb->CreateLShr(src1, src2); break;
498 case kOpAsr: res = cu->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700499 default:
500 LOG(FATAL) << "Invalid op " << op;
501 }
502 return res;
503}
504
buzbeefa57c472012-11-21 12:06:18 -0800505static void ConvertFPArithOp(CompilationUnit* cu, OpKind op, RegLocation rl_dest,
506 RegLocation rl_src1, RegLocation rl_src2)
buzbee2cfc6392012-05-07 14:51:40 -0700507{
buzbeefa57c472012-11-21 12:06:18 -0800508 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
509 llvm::Value* src2 = GetLLVMValue(cu, rl_src2.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700510 llvm::Value* res = NULL;
511 switch(op) {
buzbeefa57c472012-11-21 12:06:18 -0800512 case kOpAdd: res = cu->irb->CreateFAdd(src1, src2); break;
513 case kOpSub: res = cu->irb->CreateFSub(src1, src2); break;
514 case kOpMul: res = cu->irb->CreateFMul(src1, src2); break;
515 case kOpDiv: res = cu->irb->CreateFDiv(src1, src2); break;
516 case kOpRem: res = cu->irb->CreateFRem(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700517 default:
518 LOG(FATAL) << "Invalid op " << op;
519 }
buzbeefa57c472012-11-21 12:06:18 -0800520 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700521}
522
buzbeefa57c472012-11-21 12:06:18 -0800523static void ConvertShift(CompilationUnit* cu, greenland::IntrinsicHelper::IntrinsicId id,
524 RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2)
buzbee4f1181f2012-06-22 13:52:12 -0700525{
buzbeefa57c472012-11-21 12:06:18 -0800526 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee2a83e8f2012-07-13 16:42:30 -0700527 llvm::SmallVector<llvm::Value*, 2>args;
buzbeefa57c472012-11-21 12:06:18 -0800528 args.push_back(GetLLVMValue(cu, rl_src1.orig_sreg));
529 args.push_back(GetLLVMValue(cu, rl_src2.orig_sreg));
530 llvm::Value* res = cu->irb->CreateCall(intr, args);
531 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2a83e8f2012-07-13 16:42:30 -0700532}
533
buzbeefa57c472012-11-21 12:06:18 -0800534static void ConvertShiftLit(CompilationUnit* cu, greenland::IntrinsicHelper::IntrinsicId id,
535 RegLocation rl_dest, RegLocation rl_src, int shift_amount)
buzbee2a83e8f2012-07-13 16:42:30 -0700536{
buzbeefa57c472012-11-21 12:06:18 -0800537 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee2a83e8f2012-07-13 16:42:30 -0700538 llvm::SmallVector<llvm::Value*, 2>args;
buzbeefa57c472012-11-21 12:06:18 -0800539 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
540 args.push_back(cu->irb->getInt32(shift_amount));
541 llvm::Value* res = cu->irb->CreateCall(intr, args);
542 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee4f1181f2012-06-22 13:52:12 -0700543}
544
buzbeefa57c472012-11-21 12:06:18 -0800545static void ConvertArithOp(CompilationUnit* cu, OpKind op, RegLocation rl_dest,
546 RegLocation rl_src1, RegLocation rl_src2)
buzbee2cfc6392012-05-07 14:51:40 -0700547{
buzbeefa57c472012-11-21 12:06:18 -0800548 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
549 llvm::Value* src2 = GetLLVMValue(cu, rl_src2.orig_sreg);
buzbee4f4dfc72012-07-02 14:54:44 -0700550 DCHECK_EQ(src1->getType(), src2->getType());
buzbeefa57c472012-11-21 12:06:18 -0800551 llvm::Value* res = GenArithOp(cu, op, rl_dest.wide, src1, src2);
552 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700553}
554
buzbeefa57c472012-11-21 12:06:18 -0800555static void ConvertArithOpLit(CompilationUnit* cu, OpKind op, RegLocation rl_dest,
556 RegLocation rl_src1, int32_t imm)
buzbee2cfc6392012-05-07 14:51:40 -0700557{
buzbeefa57c472012-11-21 12:06:18 -0800558 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
559 llvm::Value* src2 = cu->irb->getInt32(imm);
560 llvm::Value* res = GenArithOp(cu, op, rl_dest.wide, src1, src2);
561 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700562}
563
buzbee101305f2012-06-28 18:00:56 -0700564/*
565 * Process arguments for invoke. Note: this code is also used to
566 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
567 * The requirements are similar.
568 */
buzbeefa57c472012-11-21 12:06:18 -0800569static void ConvertInvoke(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
570 InvokeType invoke_type, bool is_range, bool is_filled_new_array)
buzbee6969d502012-06-15 16:40:31 -0700571{
buzbee02031b12012-11-23 09:41:35 -0800572 Codegen* cg = cu->cg.get();
573 CallInfo* info = cg->NewMemCallInfo(cu, bb, mir, invoke_type, is_range);
buzbee6969d502012-06-15 16:40:31 -0700574 llvm::SmallVector<llvm::Value*, 10> args;
buzbeefa57c472012-11-21 12:06:18 -0800575 // Insert the invoke_type
576 args.push_back(cu->irb->getInt32(static_cast<int>(invoke_type)));
buzbee6969d502012-06-15 16:40:31 -0700577 // Insert the method_idx
buzbeefa57c472012-11-21 12:06:18 -0800578 args.push_back(cu->irb->getInt32(info->index));
buzbee6969d502012-06-15 16:40:31 -0700579 // Insert the optimization flags
buzbeefa57c472012-11-21 12:06:18 -0800580 args.push_back(cu->irb->getInt32(info->opt_flags));
buzbee6969d502012-06-15 16:40:31 -0700581 // Now, insert the actual arguments
buzbeefa57c472012-11-21 12:06:18 -0800582 for (int i = 0; i < info->num_arg_words;) {
583 llvm::Value* val = GetLLVMValue(cu, info->args[i].orig_sreg);
buzbee6969d502012-06-15 16:40:31 -0700584 args.push_back(val);
585 i += info->args[i].wide ? 2 : 1;
586 }
587 /*
588 * Choose the invoke return type based on actual usage. Note: may
589 * be different than shorty. For example, if a function return value
590 * is not used, we'll treat this as a void invoke.
591 */
592 greenland::IntrinsicHelper::IntrinsicId id;
buzbeefa57c472012-11-21 12:06:18 -0800593 if (is_filled_new_array) {
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700594 id = greenland::IntrinsicHelper::HLFilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700595 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700596 id = greenland::IntrinsicHelper::HLInvokeVoid;
597 } else {
598 if (info->result.wide) {
599 if (info->result.fp) {
600 id = greenland::IntrinsicHelper::HLInvokeDouble;
601 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700602 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700603 }
604 } else if (info->result.ref) {
605 id = greenland::IntrinsicHelper::HLInvokeObj;
606 } else if (info->result.fp) {
607 id = greenland::IntrinsicHelper::HLInvokeFloat;
608 } else {
609 id = greenland::IntrinsicHelper::HLInvokeInt;
610 }
611 }
buzbeefa57c472012-11-21 12:06:18 -0800612 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
613 llvm::Value* res = cu->irb->CreateCall(intr, args);
buzbee6969d502012-06-15 16:40:31 -0700614 if (info->result.location != kLocInvalid) {
buzbeefa57c472012-11-21 12:06:18 -0800615 DefineValue(cu, res, info->result.orig_sreg);
buzbee6969d502012-06-15 16:40:31 -0700616 }
617}
618
buzbeefa57c472012-11-21 12:06:18 -0800619static void ConvertConstObject(CompilationUnit* cu, uint32_t idx,
620 greenland::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest)
buzbee6969d502012-06-15 16:40:31 -0700621{
buzbeefa57c472012-11-21 12:06:18 -0800622 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
623 llvm::Value* index = cu->irb->getInt32(idx);
624 llvm::Value* res = cu->irb->CreateCall(intr, index);
625 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee6969d502012-06-15 16:40:31 -0700626}
627
buzbeefa57c472012-11-21 12:06:18 -0800628static void ConvertCheckCast(CompilationUnit* cu, uint32_t type_idx, RegLocation rl_src)
buzbee101305f2012-06-28 18:00:56 -0700629{
630 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700631 id = greenland::IntrinsicHelper::HLCheckCast;
buzbeefa57c472012-11-21 12:06:18 -0800632 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700633 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800634 args.push_back(cu->irb->getInt32(type_idx));
635 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
636 cu->irb->CreateCall(intr, args);
buzbee101305f2012-06-28 18:00:56 -0700637}
638
buzbeefa57c472012-11-21 12:06:18 -0800639static void ConvertNewInstance(CompilationUnit* cu, uint32_t type_idx, RegLocation rl_dest)
buzbee4f1181f2012-06-22 13:52:12 -0700640{
641 greenland::IntrinsicHelper::IntrinsicId id;
642 id = greenland::IntrinsicHelper::NewInstance;
buzbeefa57c472012-11-21 12:06:18 -0800643 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
644 llvm::Value* index = cu->irb->getInt32(type_idx);
645 llvm::Value* res = cu->irb->CreateCall(intr, index);
646 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee4f1181f2012-06-22 13:52:12 -0700647}
648
buzbeefa57c472012-11-21 12:06:18 -0800649static void ConvertNewArray(CompilationUnit* cu, uint32_t type_idx,
650 RegLocation rl_dest, RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700651{
652 greenland::IntrinsicHelper::IntrinsicId id;
653 id = greenland::IntrinsicHelper::NewArray;
buzbeefa57c472012-11-21 12:06:18 -0800654 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700655 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800656 args.push_back(cu->irb->getInt32(type_idx));
657 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
658 llvm::Value* res = cu->irb->CreateCall(intr, args);
659 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700660}
661
buzbeefa57c472012-11-21 12:06:18 -0800662static void ConvertAget(CompilationUnit* cu, int opt_flags,
buzbeeaad94382012-11-21 07:40:50 -0800663 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800664 RegLocation rl_dest, RegLocation rl_array, RegLocation rl_index)
buzbee8fa0fda2012-06-27 15:44:52 -0700665{
666 llvm::SmallVector<llvm::Value*, 3> args;
buzbeefa57c472012-11-21 12:06:18 -0800667 args.push_back(cu->irb->getInt32(opt_flags));
668 args.push_back(GetLLVMValue(cu, rl_array.orig_sreg));
669 args.push_back(GetLLVMValue(cu, rl_index.orig_sreg));
670 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
671 llvm::Value* res = cu->irb->CreateCall(intr, args);
672 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700673}
674
buzbeefa57c472012-11-21 12:06:18 -0800675static void ConvertAput(CompilationUnit* cu, int opt_flags,
buzbeeaad94382012-11-21 07:40:50 -0800676 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800677 RegLocation rl_src, RegLocation rl_array, RegLocation rl_index)
buzbee8fa0fda2012-06-27 15:44:52 -0700678{
679 llvm::SmallVector<llvm::Value*, 4> args;
buzbeefa57c472012-11-21 12:06:18 -0800680 args.push_back(cu->irb->getInt32(opt_flags));
681 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
682 args.push_back(GetLLVMValue(cu, rl_array.orig_sreg));
683 args.push_back(GetLLVMValue(cu, rl_index.orig_sreg));
684 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
685 cu->irb->CreateCall(intr, args);
buzbee8fa0fda2012-06-27 15:44:52 -0700686}
687
buzbeefa57c472012-11-21 12:06:18 -0800688static void ConvertIget(CompilationUnit* cu, int opt_flags,
buzbeeaad94382012-11-21 07:40:50 -0800689 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800690 RegLocation rl_dest, RegLocation rl_obj, int field_index)
buzbee101305f2012-06-28 18:00:56 -0700691{
692 llvm::SmallVector<llvm::Value*, 3> args;
buzbeefa57c472012-11-21 12:06:18 -0800693 args.push_back(cu->irb->getInt32(opt_flags));
694 args.push_back(GetLLVMValue(cu, rl_obj.orig_sreg));
695 args.push_back(cu->irb->getInt32(field_index));
696 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
697 llvm::Value* res = cu->irb->CreateCall(intr, args);
698 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee101305f2012-06-28 18:00:56 -0700699}
700
buzbeefa57c472012-11-21 12:06:18 -0800701static void ConvertIput(CompilationUnit* cu, int opt_flags,
buzbeeaad94382012-11-21 07:40:50 -0800702 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800703 RegLocation rl_src, RegLocation rl_obj, int field_index)
buzbee101305f2012-06-28 18:00:56 -0700704{
705 llvm::SmallVector<llvm::Value*, 4> args;
buzbeefa57c472012-11-21 12:06:18 -0800706 args.push_back(cu->irb->getInt32(opt_flags));
707 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
708 args.push_back(GetLLVMValue(cu, rl_obj.orig_sreg));
709 args.push_back(cu->irb->getInt32(field_index));
710 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
711 cu->irb->CreateCall(intr, args);
buzbee101305f2012-06-28 18:00:56 -0700712}
713
buzbeefa57c472012-11-21 12:06:18 -0800714static void ConvertInstanceOf(CompilationUnit* cu, uint32_t type_idx,
715 RegLocation rl_dest, RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700716{
717 greenland::IntrinsicHelper::IntrinsicId id;
718 id = greenland::IntrinsicHelper::InstanceOf;
buzbeefa57c472012-11-21 12:06:18 -0800719 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700720 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800721 args.push_back(cu->irb->getInt32(type_idx));
722 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
723 llvm::Value* res = cu->irb->CreateCall(intr, args);
724 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700725}
726
buzbeefa57c472012-11-21 12:06:18 -0800727static void ConvertIntToLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee101305f2012-06-28 18:00:56 -0700728{
buzbeefa57c472012-11-21 12:06:18 -0800729 llvm::Value* res = cu->irb->CreateSExt(GetLLVMValue(cu, rl_src.orig_sreg),
730 cu->irb->getInt64Ty());
731 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee101305f2012-06-28 18:00:56 -0700732}
733
buzbeefa57c472012-11-21 12:06:18 -0800734static void ConvertLongToInt(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700735{
buzbeefa57c472012-11-21 12:06:18 -0800736 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
737 llvm::Value* res = cu->irb->CreateTrunc(src, cu->irb->getInt32Ty());
738 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700739}
740
buzbeefa57c472012-11-21 12:06:18 -0800741static void ConvertFloatToDouble(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700742{
buzbeefa57c472012-11-21 12:06:18 -0800743 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
744 llvm::Value* res = cu->irb->CreateFPExt(src, cu->irb->getDoubleTy());
745 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700746}
747
buzbeefa57c472012-11-21 12:06:18 -0800748static void ConvertDoubleToFloat(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700749{
buzbeefa57c472012-11-21 12:06:18 -0800750 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
751 llvm::Value* res = cu->irb->CreateFPTrunc(src, cu->irb->getFloatTy());
752 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700753}
754
buzbeefa57c472012-11-21 12:06:18 -0800755static void ConvertWideComparison(CompilationUnit* cu,
buzbeeaad94382012-11-21 07:40:50 -0800756 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800757 RegLocation rl_dest, RegLocation rl_src1,
758 RegLocation rl_src2)
buzbee76592632012-06-29 15:18:35 -0700759{
buzbeefa57c472012-11-21 12:06:18 -0800760 DCHECK_EQ(rl_src1.fp, rl_src2.fp);
761 DCHECK_EQ(rl_src1.wide, rl_src2.wide);
762 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700763 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800764 args.push_back(GetLLVMValue(cu, rl_src1.orig_sreg));
765 args.push_back(GetLLVMValue(cu, rl_src2.orig_sreg));
766 llvm::Value* res = cu->irb->CreateCall(intr, args);
767 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700768}
769
buzbeefa57c472012-11-21 12:06:18 -0800770static void ConvertIntNarrowing(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src,
buzbeeaad94382012-11-21 07:40:50 -0800771 greenland::IntrinsicHelper::IntrinsicId id)
buzbee101305f2012-06-28 18:00:56 -0700772{
buzbeefa57c472012-11-21 12:06:18 -0800773 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700774 llvm::Value* res =
buzbeefa57c472012-11-21 12:06:18 -0800775 cu->irb->CreateCall(intr, GetLLVMValue(cu, rl_src.orig_sreg));
776 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700777}
778
buzbeefa57c472012-11-21 12:06:18 -0800779static void ConvertNeg(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700780{
buzbeefa57c472012-11-21 12:06:18 -0800781 llvm::Value* res = cu->irb->CreateNeg(GetLLVMValue(cu, rl_src.orig_sreg));
782 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700783}
784
buzbeefa57c472012-11-21 12:06:18 -0800785static void ConvertIntToFP(CompilationUnit* cu, llvm::Type* ty, RegLocation rl_dest,
786 RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700787{
788 llvm::Value* res =
buzbeefa57c472012-11-21 12:06:18 -0800789 cu->irb->CreateSIToFP(GetLLVMValue(cu, rl_src.orig_sreg), ty);
790 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700791}
792
buzbeefa57c472012-11-21 12:06:18 -0800793static void ConvertFPToInt(CompilationUnit* cu, greenland::IntrinsicHelper::IntrinsicId id,
794 RegLocation rl_dest,
795 RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700796{
buzbeefa57c472012-11-21 12:06:18 -0800797 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
798 llvm::Value* res = cu->irb->CreateCall(intr, GetLLVMValue(cu, rl_src.orig_sreg));
799 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700800}
801
802
buzbeefa57c472012-11-21 12:06:18 -0800803static void ConvertNegFP(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700804{
805 llvm::Value* res =
buzbeefa57c472012-11-21 12:06:18 -0800806 cu->irb->CreateFNeg(GetLLVMValue(cu, rl_src.orig_sreg));
807 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700808}
809
buzbeefa57c472012-11-21 12:06:18 -0800810static void ConvertNot(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700811{
buzbeefa57c472012-11-21 12:06:18 -0800812 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
813 llvm::Value* res = cu->irb->CreateXor(src, static_cast<uint64_t>(-1));
814 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee101305f2012-06-28 18:00:56 -0700815}
816
buzbee2cfc6392012-05-07 14:51:40 -0700817/*
818 * Target-independent code generation. Use only high-level
819 * load/store utilities here, or target-dependent genXX() handlers
820 * when necessary.
821 */
buzbeefa57c472012-11-21 12:06:18 -0800822static bool ConvertMIRNode(CompilationUnit* cu, MIR* mir, BasicBlock* bb,
823 llvm::BasicBlock* llvm_bb, LIR* label_list)
buzbee2cfc6392012-05-07 14:51:40 -0700824{
825 bool res = false; // Assume success
buzbeefa57c472012-11-21 12:06:18 -0800826 RegLocation rl_src[3];
buzbee02031b12012-11-23 09:41:35 -0800827 RegLocation rl_dest = GetBadLoc();
buzbee2cfc6392012-05-07 14:51:40 -0700828 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -0800829 int op_val = opcode;
buzbee6969d502012-06-15 16:40:31 -0700830 uint32_t vB = mir->dalvikInsn.vB;
831 uint32_t vC = mir->dalvikInsn.vC;
buzbeefa57c472012-11-21 12:06:18 -0800832 int opt_flags = mir->optimization_flags;
buzbee6969d502012-06-15 16:40:31 -0700833
buzbeefa57c472012-11-21 12:06:18 -0800834 if (cu->verbose) {
835 if (op_val < kMirOpFirst) {
836 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x" << std::hex << op_val;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700837 } else {
buzbeefa57c472012-11-21 12:06:18 -0800838 LOG(INFO) << extended_mir_op_names[op_val - kMirOpFirst] << " 0x" << std::hex << op_val;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700839 }
840 }
841
buzbee2cfc6392012-05-07 14:51:40 -0700842 /* Prep Src and Dest locations */
buzbeefa57c472012-11-21 12:06:18 -0800843 int next_sreg = 0;
844 int next_loc = 0;
845 int attrs = oat_data_flow_attributes[opcode];
buzbee02031b12012-11-23 09:41:35 -0800846 rl_src[0] = rl_src[1] = rl_src[2] = GetBadLoc();
buzbee2cfc6392012-05-07 14:51:40 -0700847 if (attrs & DF_UA) {
848 if (attrs & DF_A_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -0800849 rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
850 next_sreg+= 2;
buzbee2cfc6392012-05-07 14:51:40 -0700851 } else {
buzbeefa57c472012-11-21 12:06:18 -0800852 rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
853 next_sreg++;
buzbee2cfc6392012-05-07 14:51:40 -0700854 }
855 }
856 if (attrs & DF_UB) {
857 if (attrs & DF_B_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -0800858 rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
859 next_sreg+= 2;
buzbee2cfc6392012-05-07 14:51:40 -0700860 } else {
buzbeefa57c472012-11-21 12:06:18 -0800861 rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
862 next_sreg++;
buzbee2cfc6392012-05-07 14:51:40 -0700863 }
864 }
865 if (attrs & DF_UC) {
866 if (attrs & DF_C_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -0800867 rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700868 } else {
buzbeefa57c472012-11-21 12:06:18 -0800869 rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700870 }
871 }
872 if (attrs & DF_DA) {
873 if (attrs & DF_A_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -0800874 rl_dest = GetDestWide(cu, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700875 } else {
buzbeefa57c472012-11-21 12:06:18 -0800876 rl_dest = GetDest(cu, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700877 }
878 }
879
880 switch (opcode) {
881 case Instruction::NOP:
882 break;
883
884 case Instruction::MOVE:
885 case Instruction::MOVE_OBJECT:
886 case Instruction::MOVE_16:
887 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700888 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700889 case Instruction::MOVE_FROM16:
890 case Instruction::MOVE_WIDE:
891 case Instruction::MOVE_WIDE_16:
892 case Instruction::MOVE_WIDE_FROM16: {
893 /*
894 * Moves/copies are meaningless in pure SSA register form,
895 * but we need to preserve them for the conversion back into
896 * MIR (at least until we stop using the Dalvik register maps).
897 * Insert a dummy intrinsic copy call, which will be recognized
898 * by the quick path and removed by the portable path.
899 */
buzbeefa57c472012-11-21 12:06:18 -0800900 llvm::Value* src = GetLLVMValue(cu, rl_src[0].orig_sreg);
901 llvm::Value* res = EmitCopy(cu, src, rl_dest);
902 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700903 }
904 break;
905
906 case Instruction::CONST:
907 case Instruction::CONST_4:
908 case Instruction::CONST_16: {
buzbeefa57c472012-11-21 12:06:18 -0800909 llvm::Constant* imm_value = cu->irb->GetJInt(vB);
910 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
911 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700912 }
913 break;
914
915 case Instruction::CONST_WIDE_16:
916 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700917 // Sign extend to 64 bits
918 int64_t imm = static_cast<int32_t>(vB);
buzbeefa57c472012-11-21 12:06:18 -0800919 llvm::Constant* imm_value = cu->irb->GetJLong(imm);
920 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
921 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700922 }
923 break;
924
925 case Instruction::CONST_HIGH16: {
buzbeefa57c472012-11-21 12:06:18 -0800926 llvm::Constant* imm_value = cu->irb->GetJInt(vB << 16);
927 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
928 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700929 }
930 break;
931
932 case Instruction::CONST_WIDE: {
buzbeefa57c472012-11-21 12:06:18 -0800933 llvm::Constant* imm_value =
934 cu->irb->GetJLong(mir->dalvikInsn.vB_wide);
935 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
936 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee4f1181f2012-06-22 13:52:12 -0700937 }
938 break;
buzbee2cfc6392012-05-07 14:51:40 -0700939 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700940 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbeefa57c472012-11-21 12:06:18 -0800941 llvm::Constant* imm_value = cu->irb->GetJLong(imm);
942 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
943 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee4f1181f2012-06-22 13:52:12 -0700944 }
945 break;
946
buzbee8fa0fda2012-06-27 15:44:52 -0700947 case Instruction::SPUT_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -0800948 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputObject,
949 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700950 break;
951 case Instruction::SPUT:
buzbeefa57c472012-11-21 12:06:18 -0800952 if (rl_src[0].fp) {
953 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputFloat,
954 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700955 } else {
buzbeefa57c472012-11-21 12:06:18 -0800956 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSput, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700957 }
958 break;
959 case Instruction::SPUT_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -0800960 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputBoolean,
961 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700962 break;
963 case Instruction::SPUT_BYTE:
buzbeefa57c472012-11-21 12:06:18 -0800964 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputByte, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700965 break;
966 case Instruction::SPUT_CHAR:
buzbeefa57c472012-11-21 12:06:18 -0800967 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputChar, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700968 break;
969 case Instruction::SPUT_SHORT:
buzbeefa57c472012-11-21 12:06:18 -0800970 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputShort, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700971 break;
972 case Instruction::SPUT_WIDE:
buzbeefa57c472012-11-21 12:06:18 -0800973 if (rl_src[0].fp) {
974 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputDouble,
975 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700976 } else {
buzbeefa57c472012-11-21 12:06:18 -0800977 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputWide,
978 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700979 }
980 break;
981
982 case Instruction::SGET_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -0800983 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetObject, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -0700984 break;
985 case Instruction::SGET:
buzbeefa57c472012-11-21 12:06:18 -0800986 if (rl_dest.fp) {
987 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetFloat, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -0700988 } else {
buzbeefa57c472012-11-21 12:06:18 -0800989 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSget, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -0700990 }
991 break;
992 case Instruction::SGET_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -0800993 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetBoolean, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -0700994 break;
995 case Instruction::SGET_BYTE:
buzbeefa57c472012-11-21 12:06:18 -0800996 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetByte, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -0700997 break;
998 case Instruction::SGET_CHAR:
buzbeefa57c472012-11-21 12:06:18 -0800999 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetChar, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001000 break;
1001 case Instruction::SGET_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001002 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetShort, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001003 break;
1004 case Instruction::SGET_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001005 if (rl_dest.fp) {
1006 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetDouble,
1007 rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001008 } else {
buzbeefa57c472012-11-21 12:06:18 -08001009 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetWide, rl_dest);
buzbee4f1181f2012-06-22 13:52:12 -07001010 }
1011 break;
buzbee2cfc6392012-05-07 14:51:40 -07001012
1013 case Instruction::RETURN_WIDE:
1014 case Instruction::RETURN:
1015 case Instruction::RETURN_OBJECT: {
buzbeefa57c472012-11-21 12:06:18 -08001016 if (!(cu->attrs & METHOD_IS_LEAF)) {
1017 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -07001018 }
buzbeefa57c472012-11-21 12:06:18 -08001019 EmitPopShadowFrame(cu);
1020 cu->irb->CreateRet(GetLLVMValue(cu, rl_src[0].orig_sreg));
buzbeebbdd0532013-02-07 09:33:02 -08001021 DCHECK(bb->terminated_by_return);
buzbee2cfc6392012-05-07 14:51:40 -07001022 }
1023 break;
1024
1025 case Instruction::RETURN_VOID: {
buzbeefa57c472012-11-21 12:06:18 -08001026 if (!(cu->attrs & METHOD_IS_LEAF)) {
1027 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -07001028 }
buzbeefa57c472012-11-21 12:06:18 -08001029 EmitPopShadowFrame(cu);
1030 cu->irb->CreateRetVoid();
buzbeebbdd0532013-02-07 09:33:02 -08001031 DCHECK(bb->terminated_by_return);
buzbee2cfc6392012-05-07 14:51:40 -07001032 }
1033 break;
1034
1035 case Instruction::IF_EQ:
buzbeefa57c472012-11-21 12:06:18 -08001036 ConvertCompareAndBranch(cu, bb, mir, kCondEq, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001037 break;
1038 case Instruction::IF_NE:
buzbeefa57c472012-11-21 12:06:18 -08001039 ConvertCompareAndBranch(cu, bb, mir, kCondNe, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001040 break;
1041 case Instruction::IF_LT:
buzbeefa57c472012-11-21 12:06:18 -08001042 ConvertCompareAndBranch(cu, bb, mir, kCondLt, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001043 break;
1044 case Instruction::IF_GE:
buzbeefa57c472012-11-21 12:06:18 -08001045 ConvertCompareAndBranch(cu, bb, mir, kCondGe, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001046 break;
1047 case Instruction::IF_GT:
buzbeefa57c472012-11-21 12:06:18 -08001048 ConvertCompareAndBranch(cu, bb, mir, kCondGt, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001049 break;
1050 case Instruction::IF_LE:
buzbeefa57c472012-11-21 12:06:18 -08001051 ConvertCompareAndBranch(cu, bb, mir, kCondLe, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001052 break;
1053 case Instruction::IF_EQZ:
buzbeefa57c472012-11-21 12:06:18 -08001054 ConvertCompareZeroAndBranch(cu, bb, mir, kCondEq, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001055 break;
1056 case Instruction::IF_NEZ:
buzbeefa57c472012-11-21 12:06:18 -08001057 ConvertCompareZeroAndBranch(cu, bb, mir, kCondNe, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001058 break;
1059 case Instruction::IF_LTZ:
buzbeefa57c472012-11-21 12:06:18 -08001060 ConvertCompareZeroAndBranch(cu, bb, mir, kCondLt, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001061 break;
1062 case Instruction::IF_GEZ:
buzbeefa57c472012-11-21 12:06:18 -08001063 ConvertCompareZeroAndBranch(cu, bb, mir, kCondGe, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001064 break;
1065 case Instruction::IF_GTZ:
buzbeefa57c472012-11-21 12:06:18 -08001066 ConvertCompareZeroAndBranch(cu, bb, mir, kCondGt, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001067 break;
1068 case Instruction::IF_LEZ:
buzbeefa57c472012-11-21 12:06:18 -08001069 ConvertCompareZeroAndBranch(cu, bb, mir, kCondLe, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001070 break;
1071
1072 case Instruction::GOTO:
1073 case Instruction::GOTO_16:
1074 case Instruction::GOTO_32: {
buzbeefa57c472012-11-21 12:06:18 -08001075 if (bb->taken->start_offset <= bb->start_offset) {
1076 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -07001077 }
buzbeefa57c472012-11-21 12:06:18 -08001078 cu->irb->CreateBr(GetLLVMBlock(cu, bb->taken->id));
buzbee2cfc6392012-05-07 14:51:40 -07001079 }
1080 break;
1081
1082 case Instruction::ADD_LONG:
1083 case Instruction::ADD_LONG_2ADDR:
1084 case Instruction::ADD_INT:
1085 case Instruction::ADD_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001086 ConvertArithOp(cu, kOpAdd, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001087 break;
1088 case Instruction::SUB_LONG:
1089 case Instruction::SUB_LONG_2ADDR:
1090 case Instruction::SUB_INT:
1091 case Instruction::SUB_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001092 ConvertArithOp(cu, kOpSub, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001093 break;
1094 case Instruction::MUL_LONG:
1095 case Instruction::MUL_LONG_2ADDR:
1096 case Instruction::MUL_INT:
1097 case Instruction::MUL_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001098 ConvertArithOp(cu, kOpMul, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001099 break;
1100 case Instruction::DIV_LONG:
1101 case Instruction::DIV_LONG_2ADDR:
1102 case Instruction::DIV_INT:
1103 case Instruction::DIV_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001104 ConvertArithOp(cu, kOpDiv, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001105 break;
1106 case Instruction::REM_LONG:
1107 case Instruction::REM_LONG_2ADDR:
1108 case Instruction::REM_INT:
1109 case Instruction::REM_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001110 ConvertArithOp(cu, kOpRem, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001111 break;
1112 case Instruction::AND_LONG:
1113 case Instruction::AND_LONG_2ADDR:
1114 case Instruction::AND_INT:
1115 case Instruction::AND_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001116 ConvertArithOp(cu, kOpAnd, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001117 break;
1118 case Instruction::OR_LONG:
1119 case Instruction::OR_LONG_2ADDR:
1120 case Instruction::OR_INT:
1121 case Instruction::OR_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001122 ConvertArithOp(cu, kOpOr, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001123 break;
1124 case Instruction::XOR_LONG:
1125 case Instruction::XOR_LONG_2ADDR:
1126 case Instruction::XOR_INT:
1127 case Instruction::XOR_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001128 ConvertArithOp(cu, kOpXor, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001129 break;
1130 case Instruction::SHL_LONG:
1131 case Instruction::SHL_LONG_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001132 ConvertShift(cu, greenland::IntrinsicHelper::SHLLong,
1133 rl_dest, rl_src[0], rl_src[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001134 break;
buzbee2cfc6392012-05-07 14:51:40 -07001135 case Instruction::SHL_INT:
1136 case Instruction::SHL_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001137 ConvertShift(cu, greenland::IntrinsicHelper::SHLInt,
1138 rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001139 break;
1140 case Instruction::SHR_LONG:
1141 case Instruction::SHR_LONG_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001142 ConvertShift(cu, greenland::IntrinsicHelper::SHRLong,
1143 rl_dest, rl_src[0], rl_src[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001144 break;
buzbee2cfc6392012-05-07 14:51:40 -07001145 case Instruction::SHR_INT:
1146 case Instruction::SHR_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001147 ConvertShift(cu, greenland::IntrinsicHelper::SHRInt,
1148 rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001149 break;
1150 case Instruction::USHR_LONG:
1151 case Instruction::USHR_LONG_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001152 ConvertShift(cu, greenland::IntrinsicHelper::USHRLong,
1153 rl_dest, rl_src[0], rl_src[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001154 break;
buzbee2cfc6392012-05-07 14:51:40 -07001155 case Instruction::USHR_INT:
1156 case Instruction::USHR_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001157 ConvertShift(cu, greenland::IntrinsicHelper::USHRInt,
1158 rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001159 break;
1160
1161 case Instruction::ADD_INT_LIT16:
1162 case Instruction::ADD_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001163 ConvertArithOpLit(cu, kOpAdd, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001164 break;
1165 case Instruction::RSUB_INT:
1166 case Instruction::RSUB_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001167 ConvertArithOpLit(cu, kOpRsub, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001168 break;
1169 case Instruction::MUL_INT_LIT16:
1170 case Instruction::MUL_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001171 ConvertArithOpLit(cu, kOpMul, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001172 break;
1173 case Instruction::DIV_INT_LIT16:
1174 case Instruction::DIV_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001175 ConvertArithOpLit(cu, kOpDiv, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001176 break;
1177 case Instruction::REM_INT_LIT16:
1178 case Instruction::REM_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001179 ConvertArithOpLit(cu, kOpRem, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001180 break;
1181 case Instruction::AND_INT_LIT16:
1182 case Instruction::AND_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001183 ConvertArithOpLit(cu, kOpAnd, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001184 break;
1185 case Instruction::OR_INT_LIT16:
1186 case Instruction::OR_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001187 ConvertArithOpLit(cu, kOpOr, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001188 break;
1189 case Instruction::XOR_INT_LIT16:
1190 case Instruction::XOR_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001191 ConvertArithOpLit(cu, kOpXor, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001192 break;
1193 case Instruction::SHL_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001194 ConvertShiftLit(cu, greenland::IntrinsicHelper::SHLInt,
1195 rl_dest, rl_src[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001196 break;
1197 case Instruction::SHR_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001198 ConvertShiftLit(cu, greenland::IntrinsicHelper::SHRInt,
1199 rl_dest, rl_src[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001200 break;
1201 case Instruction::USHR_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001202 ConvertShiftLit(cu, greenland::IntrinsicHelper::USHRInt,
1203 rl_dest, rl_src[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001204 break;
1205
1206 case Instruction::ADD_FLOAT:
1207 case Instruction::ADD_FLOAT_2ADDR:
1208 case Instruction::ADD_DOUBLE:
1209 case Instruction::ADD_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001210 ConvertFPArithOp(cu, kOpAdd, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001211 break;
1212
1213 case Instruction::SUB_FLOAT:
1214 case Instruction::SUB_FLOAT_2ADDR:
1215 case Instruction::SUB_DOUBLE:
1216 case Instruction::SUB_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001217 ConvertFPArithOp(cu, kOpSub, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001218 break;
1219
1220 case Instruction::MUL_FLOAT:
1221 case Instruction::MUL_FLOAT_2ADDR:
1222 case Instruction::MUL_DOUBLE:
1223 case Instruction::MUL_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001224 ConvertFPArithOp(cu, kOpMul, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001225 break;
1226
1227 case Instruction::DIV_FLOAT:
1228 case Instruction::DIV_FLOAT_2ADDR:
1229 case Instruction::DIV_DOUBLE:
1230 case Instruction::DIV_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001231 ConvertFPArithOp(cu, kOpDiv, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001232 break;
1233
1234 case Instruction::REM_FLOAT:
1235 case Instruction::REM_FLOAT_2ADDR:
1236 case Instruction::REM_DOUBLE:
1237 case Instruction::REM_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001238 ConvertFPArithOp(cu, kOpRem, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001239 break;
1240
buzbee6969d502012-06-15 16:40:31 -07001241 case Instruction::INVOKE_STATIC:
buzbeefa57c472012-11-21 12:06:18 -08001242 ConvertInvoke(cu, bb, mir, kStatic, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001243 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001244 break;
1245 case Instruction::INVOKE_STATIC_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001246 ConvertInvoke(cu, bb, mir, kStatic, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001247 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001248 break;
1249
1250 case Instruction::INVOKE_DIRECT:
buzbeefa57c472012-11-21 12:06:18 -08001251 ConvertInvoke(cu, bb, mir, kDirect, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001252 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001253 break;
1254 case Instruction::INVOKE_DIRECT_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001255 ConvertInvoke(cu, bb, mir, kDirect, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001256 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001257 break;
1258
1259 case Instruction::INVOKE_VIRTUAL:
buzbeefa57c472012-11-21 12:06:18 -08001260 ConvertInvoke(cu, bb, mir, kVirtual, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001261 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001262 break;
1263 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001264 ConvertInvoke(cu, bb, mir, kVirtual, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001265 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001266 break;
1267
1268 case Instruction::INVOKE_SUPER:
buzbeefa57c472012-11-21 12:06:18 -08001269 ConvertInvoke(cu, bb, mir, kSuper, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001270 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001271 break;
1272 case Instruction::INVOKE_SUPER_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001273 ConvertInvoke(cu, bb, mir, kSuper, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001274 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001275 break;
1276
1277 case Instruction::INVOKE_INTERFACE:
buzbeefa57c472012-11-21 12:06:18 -08001278 ConvertInvoke(cu, bb, mir, kInterface, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001279 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001280 break;
1281 case Instruction::INVOKE_INTERFACE_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001282 ConvertInvoke(cu, bb, mir, kInterface, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001283 false /* NewFilledArray */);
1284 break;
1285 case Instruction::FILLED_NEW_ARRAY:
buzbeefa57c472012-11-21 12:06:18 -08001286 ConvertInvoke(cu, bb, mir, kInterface, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001287 true /* NewFilledArray */);
1288 break;
1289 case Instruction::FILLED_NEW_ARRAY_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001290 ConvertInvoke(cu, bb, mir, kInterface, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001291 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001292 break;
1293
1294 case Instruction::CONST_STRING:
1295 case Instruction::CONST_STRING_JUMBO:
buzbeefa57c472012-11-21 12:06:18 -08001296 ConvertConstObject(cu, vB, greenland::IntrinsicHelper::ConstString,
1297 rl_dest);
buzbee101305f2012-06-28 18:00:56 -07001298 break;
1299
1300 case Instruction::CONST_CLASS:
buzbeefa57c472012-11-21 12:06:18 -08001301 ConvertConstObject(cu, vB, greenland::IntrinsicHelper::ConstClass,
1302 rl_dest);
buzbee101305f2012-06-28 18:00:56 -07001303 break;
1304
1305 case Instruction::CHECK_CAST:
buzbeefa57c472012-11-21 12:06:18 -08001306 ConvertCheckCast(cu, vB, rl_src[0]);
buzbee6969d502012-06-15 16:40:31 -07001307 break;
1308
buzbee4f1181f2012-06-22 13:52:12 -07001309 case Instruction::NEW_INSTANCE:
buzbeefa57c472012-11-21 12:06:18 -08001310 ConvertNewInstance(cu, vB, rl_dest);
buzbee4f1181f2012-06-22 13:52:12 -07001311 break;
1312
buzbee32412962012-06-26 16:27:56 -07001313 case Instruction::MOVE_EXCEPTION:
buzbeefa57c472012-11-21 12:06:18 -08001314 ConvertMoveException(cu, rl_dest);
buzbee32412962012-06-26 16:27:56 -07001315 break;
1316
1317 case Instruction::THROW:
buzbeefa57c472012-11-21 12:06:18 -08001318 ConvertThrow(cu, rl_src[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001319 /*
1320 * If this throw is standalone, terminate.
1321 * If it might rethrow, force termination
1322 * of the following block.
1323 */
buzbeefa57c472012-11-21 12:06:18 -08001324 if (bb->fall_through == NULL) {
1325 cu->irb->CreateUnreachable();
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001326 } else {
buzbeefa57c472012-11-21 12:06:18 -08001327 bb->fall_through->fall_through = NULL;
1328 bb->fall_through->taken = NULL;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001329 }
buzbee32412962012-06-26 16:27:56 -07001330 break;
1331
buzbee2cfc6392012-05-07 14:51:40 -07001332 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001333 case Instruction::MOVE_RESULT:
1334 case Instruction::MOVE_RESULT_OBJECT:
buzbee9a2487f2012-07-26 14:01:13 -07001335 /*
jeffhao9a4f0032012-08-30 16:17:40 -07001336 * All move_results should have been folded into the preceeding invoke.
buzbee9a2487f2012-07-26 14:01:13 -07001337 */
jeffhao9a4f0032012-08-30 16:17:40 -07001338 LOG(FATAL) << "Unexpected move_result";
buzbee2cfc6392012-05-07 14:51:40 -07001339 break;
1340
1341 case Instruction::MONITOR_ENTER:
buzbeefa57c472012-11-21 12:06:18 -08001342 ConvertMonitorEnterExit(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001343 greenland::IntrinsicHelper::MonitorEnter,
buzbeefa57c472012-11-21 12:06:18 -08001344 rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001345 break;
1346
1347 case Instruction::MONITOR_EXIT:
buzbeefa57c472012-11-21 12:06:18 -08001348 ConvertMonitorEnterExit(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001349 greenland::IntrinsicHelper::MonitorExit,
buzbeefa57c472012-11-21 12:06:18 -08001350 rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001351 break;
1352
1353 case Instruction::ARRAY_LENGTH:
buzbeefa57c472012-11-21 12:06:18 -08001354 ConvertArrayLength(cu, opt_flags, rl_dest, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001355 break;
1356
1357 case Instruction::NEW_ARRAY:
buzbeefa57c472012-11-21 12:06:18 -08001358 ConvertNewArray(cu, vC, rl_dest, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001359 break;
1360
1361 case Instruction::INSTANCE_OF:
buzbeefa57c472012-11-21 12:06:18 -08001362 ConvertInstanceOf(cu, vC, rl_dest, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001363 break;
1364
1365 case Instruction::AGET:
buzbeefa57c472012-11-21 12:06:18 -08001366 if (rl_dest.fp) {
1367 ConvertAget(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001368 greenland::IntrinsicHelper::HLArrayGetFloat,
buzbeefa57c472012-11-21 12:06:18 -08001369 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001370 } else {
buzbeefa57c472012-11-21 12:06:18 -08001371 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGet,
1372 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001373 }
1374 break;
1375 case Instruction::AGET_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -08001376 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetObject,
1377 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001378 break;
1379 case Instruction::AGET_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -08001380 ConvertAget(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001381 greenland::IntrinsicHelper::HLArrayGetBoolean,
buzbeefa57c472012-11-21 12:06:18 -08001382 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001383 break;
1384 case Instruction::AGET_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001385 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetByte,
1386 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001387 break;
1388 case Instruction::AGET_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001389 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetChar,
1390 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001391 break;
1392 case Instruction::AGET_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001393 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetShort,
1394 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001395 break;
1396 case Instruction::AGET_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001397 if (rl_dest.fp) {
1398 ConvertAget(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001399 greenland::IntrinsicHelper::HLArrayGetDouble,
buzbeefa57c472012-11-21 12:06:18 -08001400 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001401 } else {
buzbeefa57c472012-11-21 12:06:18 -08001402 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetWide,
1403 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001404 }
1405 break;
1406
1407 case Instruction::APUT:
buzbeefa57c472012-11-21 12:06:18 -08001408 if (rl_src[0].fp) {
1409 ConvertAput(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001410 greenland::IntrinsicHelper::HLArrayPutFloat,
buzbeefa57c472012-11-21 12:06:18 -08001411 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001412 } else {
buzbeefa57c472012-11-21 12:06:18 -08001413 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPut,
1414 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001415 }
1416 break;
1417 case Instruction::APUT_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -08001418 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutObject,
1419 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001420 break;
1421 case Instruction::APUT_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -08001422 ConvertAput(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001423 greenland::IntrinsicHelper::HLArrayPutBoolean,
buzbeefa57c472012-11-21 12:06:18 -08001424 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001425 break;
1426 case Instruction::APUT_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001427 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutByte,
1428 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001429 break;
1430 case Instruction::APUT_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001431 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutChar,
1432 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001433 break;
1434 case Instruction::APUT_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001435 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutShort,
1436 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001437 break;
1438 case Instruction::APUT_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001439 if (rl_src[0].fp) {
1440 ConvertAput(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001441 greenland::IntrinsicHelper::HLArrayPutDouble,
buzbeefa57c472012-11-21 12:06:18 -08001442 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001443 } else {
buzbeefa57c472012-11-21 12:06:18 -08001444 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutWide,
1445 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001446 }
1447 break;
1448
buzbee101305f2012-06-28 18:00:56 -07001449 case Instruction::IGET:
buzbeefa57c472012-11-21 12:06:18 -08001450 if (rl_dest.fp) {
1451 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetFloat,
1452 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001453 } else {
buzbeefa57c472012-11-21 12:06:18 -08001454 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGet,
1455 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001456 }
buzbee2cfc6392012-05-07 14:51:40 -07001457 break;
buzbee101305f2012-06-28 18:00:56 -07001458 case Instruction::IGET_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -08001459 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetObject,
1460 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001461 break;
1462 case Instruction::IGET_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -08001463 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetBoolean,
1464 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001465 break;
1466 case Instruction::IGET_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001467 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetByte,
1468 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001469 break;
1470 case Instruction::IGET_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001471 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetChar,
1472 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001473 break;
1474 case Instruction::IGET_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001475 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetShort,
1476 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001477 break;
1478 case Instruction::IGET_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001479 if (rl_dest.fp) {
1480 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetDouble,
1481 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001482 } else {
buzbeefa57c472012-11-21 12:06:18 -08001483 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetWide,
1484 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001485 }
1486 break;
1487 case Instruction::IPUT:
buzbeefa57c472012-11-21 12:06:18 -08001488 if (rl_src[0].fp) {
1489 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutFloat,
1490 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001491 } else {
buzbeefa57c472012-11-21 12:06:18 -08001492 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPut,
1493 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001494 }
1495 break;
1496 case Instruction::IPUT_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -08001497 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutObject,
1498 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001499 break;
1500 case Instruction::IPUT_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -08001501 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutBoolean,
1502 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001503 break;
1504 case Instruction::IPUT_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001505 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutByte,
1506 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001507 break;
1508 case Instruction::IPUT_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001509 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutChar,
1510 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001511 break;
1512 case Instruction::IPUT_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001513 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutShort,
1514 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001515 break;
1516 case Instruction::IPUT_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001517 if (rl_src[0].fp) {
1518 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutDouble,
1519 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001520 } else {
buzbeefa57c472012-11-21 12:06:18 -08001521 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutWide,
1522 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001523 }
buzbee2cfc6392012-05-07 14:51:40 -07001524 break;
1525
1526 case Instruction::FILL_ARRAY_DATA:
buzbeefa57c472012-11-21 12:06:18 -08001527 ConvertFillArrayData(cu, vB, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001528 break;
1529
buzbee76592632012-06-29 15:18:35 -07001530 case Instruction::LONG_TO_INT:
buzbeefa57c472012-11-21 12:06:18 -08001531 ConvertLongToInt(cu, rl_dest, rl_src[0]);
buzbee76592632012-06-29 15:18:35 -07001532 break;
1533
buzbee101305f2012-06-28 18:00:56 -07001534 case Instruction::INT_TO_LONG:
buzbeefa57c472012-11-21 12:06:18 -08001535 ConvertIntToLong(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001536 break;
1537
buzbee101305f2012-06-28 18:00:56 -07001538 case Instruction::INT_TO_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001539 ConvertIntNarrowing(cu, rl_dest, rl_src[0],
buzbee101305f2012-06-28 18:00:56 -07001540 greenland::IntrinsicHelper::IntToChar);
1541 break;
1542 case Instruction::INT_TO_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001543 ConvertIntNarrowing(cu, rl_dest, rl_src[0],
buzbee101305f2012-06-28 18:00:56 -07001544 greenland::IntrinsicHelper::IntToByte);
1545 break;
1546 case Instruction::INT_TO_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001547 ConvertIntNarrowing(cu, rl_dest, rl_src[0],
buzbee101305f2012-06-28 18:00:56 -07001548 greenland::IntrinsicHelper::IntToShort);
1549 break;
1550
buzbee76592632012-06-29 15:18:35 -07001551 case Instruction::INT_TO_FLOAT:
1552 case Instruction::LONG_TO_FLOAT:
buzbeefa57c472012-11-21 12:06:18 -08001553 ConvertIntToFP(cu, cu->irb->getFloatTy(), rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001554 break;
1555
buzbee76592632012-06-29 15:18:35 -07001556 case Instruction::INT_TO_DOUBLE:
1557 case Instruction::LONG_TO_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001558 ConvertIntToFP(cu, cu->irb->getDoubleTy(), rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001559 break;
1560
buzbee76592632012-06-29 15:18:35 -07001561 case Instruction::FLOAT_TO_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001562 ConvertFloatToDouble(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001563 break;
1564
buzbee76592632012-06-29 15:18:35 -07001565 case Instruction::DOUBLE_TO_FLOAT:
buzbeefa57c472012-11-21 12:06:18 -08001566 ConvertDoubleToFloat(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001567 break;
1568
1569 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001570 case Instruction::NEG_INT:
buzbeefa57c472012-11-21 12:06:18 -08001571 ConvertNeg(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001572 break;
1573
1574 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001575 case Instruction::NEG_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001576 ConvertNegFP(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001577 break;
1578
buzbee76592632012-06-29 15:18:35 -07001579 case Instruction::NOT_LONG:
1580 case Instruction::NOT_INT:
buzbeefa57c472012-11-21 12:06:18 -08001581 ConvertNot(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001582 break;
1583
buzbee2cfc6392012-05-07 14:51:40 -07001584 case Instruction::FLOAT_TO_INT:
buzbeefa57c472012-11-21 12:06:18 -08001585 ConvertFPToInt(cu, greenland::IntrinsicHelper::F2I, rl_dest, rl_src[0]);
TDYa1274ec8ccd2012-08-11 07:04:57 -07001586 break;
1587
buzbee2cfc6392012-05-07 14:51:40 -07001588 case Instruction::DOUBLE_TO_INT:
buzbeefa57c472012-11-21 12:06:18 -08001589 ConvertFPToInt(cu, greenland::IntrinsicHelper::D2I, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001590 break;
1591
buzbee76592632012-06-29 15:18:35 -07001592 case Instruction::FLOAT_TO_LONG:
buzbeefa57c472012-11-21 12:06:18 -08001593 ConvertFPToInt(cu, greenland::IntrinsicHelper::F2L, rl_dest, rl_src[0]);
TDYa1274ec8ccd2012-08-11 07:04:57 -07001594 break;
1595
buzbee76592632012-06-29 15:18:35 -07001596 case Instruction::DOUBLE_TO_LONG:
buzbeefa57c472012-11-21 12:06:18 -08001597 ConvertFPToInt(cu, greenland::IntrinsicHelper::D2L, rl_dest, rl_src[0]);
buzbee76592632012-06-29 15:18:35 -07001598 break;
1599
1600 case Instruction::CMPL_FLOAT:
buzbeefa57c472012-11-21 12:06:18 -08001601 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmplFloat,
1602 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001603 break;
1604 case Instruction::CMPG_FLOAT:
buzbeefa57c472012-11-21 12:06:18 -08001605 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmpgFloat,
1606 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001607 break;
1608 case Instruction::CMPL_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001609 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmplDouble,
1610 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001611 break;
1612 case Instruction::CMPG_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001613 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmpgDouble,
1614 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001615 break;
1616 case Instruction::CMP_LONG:
buzbeefa57c472012-11-21 12:06:18 -08001617 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmpLong,
1618 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001619 break;
1620
buzbee76592632012-06-29 15:18:35 -07001621 case Instruction::PACKED_SWITCH:
buzbeefa57c472012-11-21 12:06:18 -08001622 ConvertPackedSwitch(cu, bb, vB, rl_src[0]);
buzbee76592632012-06-29 15:18:35 -07001623 break;
1624
1625 case Instruction::SPARSE_SWITCH:
buzbeefa57c472012-11-21 12:06:18 -08001626 ConvertSparseSwitch(cu, bb, vB, rl_src[0]);
buzbee76592632012-06-29 15:18:35 -07001627 break;
buzbee2cfc6392012-05-07 14:51:40 -07001628
1629 default:
buzbee32412962012-06-26 16:27:56 -07001630 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001631 res = true;
1632 }
1633 return res;
1634}
1635
buzbeefa57c472012-11-21 12:06:18 -08001636static void SetDexOffset(CompilationUnit* cu, int32_t offset)
buzbee2cfc6392012-05-07 14:51:40 -07001637{
buzbeefa57c472012-11-21 12:06:18 -08001638 cu->current_dalvik_offset = offset;
1639 llvm::SmallVector<llvm::Value*, 1> array_ref;
1640 array_ref.push_back(cu->irb->getInt32(offset));
1641 llvm::MDNode* node = llvm::MDNode::get(*cu->context, array_ref);
1642 cu->irb->SetDexOffset(node);
buzbee2cfc6392012-05-07 14:51:40 -07001643}
1644
1645// Attach method info as metadata to special intrinsic
buzbeefa57c472012-11-21 12:06:18 -08001646static void SetMethodInfo(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -07001647{
1648 // We don't want dex offset on this
buzbeefa57c472012-11-21 12:06:18 -08001649 cu->irb->SetDexOffset(NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001650 greenland::IntrinsicHelper::IntrinsicId id;
1651 id = greenland::IntrinsicHelper::MethodInfo;
buzbeefa57c472012-11-21 12:06:18 -08001652 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
1653 llvm::Instruction* inst = cu->irb->CreateCall(intr);
1654 llvm::SmallVector<llvm::Value*, 2> reg_info;
1655 reg_info.push_back(cu->irb->getInt32(cu->num_ins));
1656 reg_info.push_back(cu->irb->getInt32(cu->num_regs));
1657 reg_info.push_back(cu->irb->getInt32(cu->num_outs));
1658 reg_info.push_back(cu->irb->getInt32(cu->num_compiler_temps));
1659 reg_info.push_back(cu->irb->getInt32(cu->num_ssa_regs));
1660 llvm::MDNode* reg_info_node = llvm::MDNode::get(*cu->context, reg_info);
1661 inst->setMetadata("RegInfo", reg_info_node);
1662 int promo_size = cu->num_dalvik_registers + cu->num_compiler_temps + 1;
buzbee2cfc6392012-05-07 14:51:40 -07001663 llvm::SmallVector<llvm::Value*, 50> pmap;
buzbeefa57c472012-11-21 12:06:18 -08001664 for (int i = 0; i < promo_size; i++) {
1665 PromotionMap* p = &cu->promotion_map[i];
1666 int32_t map_data = ((p->first_in_pair & 0xff) << 24) |
buzbee52a77fc2012-11-20 19:50:46 -08001667 ((p->FpReg & 0xff) << 16) |
buzbeefa57c472012-11-21 12:06:18 -08001668 ((p->core_reg & 0xff) << 8) |
1669 ((p->fp_location & 0xf) << 4) |
1670 (p->core_location & 0xf);
1671 pmap.push_back(cu->irb->getInt32(map_data));
buzbee2cfc6392012-05-07 14:51:40 -07001672 }
buzbeefa57c472012-11-21 12:06:18 -08001673 llvm::MDNode* map_node = llvm::MDNode::get(*cu->context, pmap);
1674 inst->setMetadata("PromotionMap", map_node);
1675 SetDexOffset(cu, cu->current_dalvik_offset);
buzbee2cfc6392012-05-07 14:51:40 -07001676}
1677
buzbee26f10ee2012-12-21 11:16:29 -08001678static void HandlePhiNodes(CompilationUnit* cu, BasicBlock* bb, llvm::BasicBlock* llvm_bb)
1679{
1680 SetDexOffset(cu, bb->start_offset);
1681 for (MIR* mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
1682 int opcode = mir->dalvikInsn.opcode;
1683 if (opcode < kMirOpFirst) {
1684 // Stop after first non-pseudo MIR op.
1685 continue;
1686 }
1687 if (opcode != kMirOpPhi) {
1688 // Skip other mir Pseudos.
1689 continue;
1690 }
1691 RegLocation rl_dest = cu->reg_location[mir->ssa_rep->defs[0]];
1692 /*
1693 * The Art compiler's Phi nodes only handle 32-bit operands,
1694 * representing wide values using a matched set of Phi nodes
1695 * for the lower and upper halves. In the llvm world, we only
1696 * want a single Phi for wides. Here we will simply discard
1697 * the Phi node representing the high word.
1698 */
1699 if (rl_dest.high_word) {
1700 continue; // No Phi node - handled via low word
1701 }
1702 int* incoming = reinterpret_cast<int*>(mir->dalvikInsn.vB);
1703 llvm::Type* phi_type =
1704 LlvmTypeFromLocRec(cu, rl_dest);
1705 llvm::PHINode* phi = cu->irb->CreatePHI(phi_type, mir->ssa_rep->num_uses);
1706 for (int i = 0; i < mir->ssa_rep->num_uses; i++) {
1707 RegLocation loc;
1708 // Don't check width here.
1709 loc = GetRawSrc(cu, mir, i);
1710 DCHECK_EQ(rl_dest.wide, loc.wide);
1711 DCHECK_EQ(rl_dest.wide & rl_dest.high_word, loc.wide & loc.high_word);
1712 DCHECK_EQ(rl_dest.fp, loc.fp);
1713 DCHECK_EQ(rl_dest.core, loc.core);
1714 DCHECK_EQ(rl_dest.ref, loc.ref);
1715 SafeMap<unsigned int, unsigned int>::iterator it;
1716 it = cu->block_id_map.find(incoming[i]);
1717 DCHECK(it != cu->block_id_map.end());
1718 DCHECK(GetLLVMValue(cu, loc.orig_sreg) != NULL);
1719 DCHECK(GetLLVMBlock(cu, it->second) != NULL);
1720 phi->addIncoming(GetLLVMValue(cu, loc.orig_sreg),
1721 GetLLVMBlock(cu, it->second));
1722 }
1723 DefineValueOnly(cu, phi, rl_dest.orig_sreg);
1724 }
1725}
1726
1727/* Extended MIR instructions like PHI */
1728static void ConvertExtendedMIR(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
1729 llvm::BasicBlock* llvm_bb)
1730{
1731
1732 switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) {
1733 case kMirOpPhi: {
1734 // The llvm Phi node already emitted - just DefineValue() here.
1735 RegLocation rl_dest = cu->reg_location[mir->ssa_rep->defs[0]];
1736 if (!rl_dest.high_word) {
1737 // Only consider low word of pairs.
1738 DCHECK(GetLLVMValue(cu, rl_dest.orig_sreg) != NULL);
1739 llvm::Value* phi = GetLLVMValue(cu, rl_dest.orig_sreg);
1740 if (1) SetVregOnValue(cu, phi, rl_dest.orig_sreg);
1741 }
1742 break;
1743 }
1744 case kMirOpCopy: {
1745 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1746 break;
1747 }
1748 case kMirOpNop:
1749 if ((mir == bb->last_mir_insn) && (bb->taken == NULL) &&
1750 (bb->fall_through == NULL)) {
1751 cu->irb->CreateUnreachable();
1752 }
1753 break;
1754
1755 // TODO: need GBC intrinsic to take advantage of fused operations
1756 case kMirOpFusedCmplFloat:
1757 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpFloat unsupported";
1758 break;
1759 case kMirOpFusedCmpgFloat:
1760 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmgFloat unsupported";
1761 break;
1762 case kMirOpFusedCmplDouble:
1763 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmplDouble unsupported";
1764 break;
1765 case kMirOpFusedCmpgDouble:
1766 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpgDouble unsupported";
1767 break;
1768 case kMirOpFusedCmpLong:
1769 UNIMPLEMENTED(FATAL) << "kMirOpLongCmpBranch unsupported";
1770 break;
1771 default:
1772 break;
1773 }
1774}
1775
buzbee2cfc6392012-05-07 14:51:40 -07001776/* Handle the content in each basic block */
buzbeefa57c472012-11-21 12:06:18 -08001777static bool BlockBitcodeConversion(CompilationUnit* cu, BasicBlock* bb)
buzbee2cfc6392012-05-07 14:51:40 -07001778{
buzbeefa57c472012-11-21 12:06:18 -08001779 if (bb->block_type == kDead) return false;
1780 llvm::BasicBlock* llvm_bb = GetLLVMBlock(cu, bb->id);
1781 if (llvm_bb == NULL) {
1782 CHECK(bb->block_type == kExitBlock);
buzbeef5f5a122012-09-21 13:57:36 -07001783 } else {
buzbeefa57c472012-11-21 12:06:18 -08001784 cu->irb->SetInsertPoint(llvm_bb);
1785 SetDexOffset(cu, bb->start_offset);
buzbeef5f5a122012-09-21 13:57:36 -07001786 }
buzbee2cfc6392012-05-07 14:51:40 -07001787
buzbeefa57c472012-11-21 12:06:18 -08001788 if (cu->verbose) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001789 LOG(INFO) << "................................";
1790 LOG(INFO) << "Block id " << bb->id;
buzbeefa57c472012-11-21 12:06:18 -08001791 if (llvm_bb != NULL) {
1792 LOG(INFO) << "label " << llvm_bb->getName().str().c_str();
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001793 } else {
buzbeefa57c472012-11-21 12:06:18 -08001794 LOG(INFO) << "llvm_bb is NULL";
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001795 }
1796 }
1797
buzbeefa57c472012-11-21 12:06:18 -08001798 if (bb->block_type == kEntryBlock) {
1799 SetMethodInfo(cu);
TDYa127dc5daa02013-01-09 21:31:37 +08001800
1801 { // Allocate shadowframe.
1802 greenland::IntrinsicHelper::IntrinsicId id =
1803 greenland::IntrinsicHelper::AllocaShadowFrame;
1804 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id);
1805 llvm::Value* entries = cu->irb->getInt32(cu->num_dalvik_registers);
1806 cu->irb->CreateCall(func, entries);
buzbeeb03f4872012-06-11 15:22:11 -07001807 }
TDYa127dc5daa02013-01-09 21:31:37 +08001808
1809 { // Store arguments to vregs.
1810 uint16_t arg_reg = cu->num_regs;
1811
1812 llvm::Function::arg_iterator arg_iter(cu->func->arg_begin());
1813 llvm::Function::arg_iterator arg_end(cu->func->arg_end());
1814
1815 const char* shorty = cu->shorty;
1816 uint32_t shorty_size = strlen(shorty);
1817 CHECK_GE(shorty_size, 1u);
1818
1819 ++arg_iter; // skip method object
1820
1821 if ((cu->access_flags & kAccStatic) == 0) {
1822 SetVregOnValue(cu, arg_iter, arg_reg);
1823 ++arg_iter;
1824 ++arg_reg;
buzbeeb03f4872012-06-11 15:22:11 -07001825 }
TDYa127dc5daa02013-01-09 21:31:37 +08001826
1827 for (uint32_t i = 1; i < shorty_size; ++i, ++arg_iter) {
1828 SetVregOnValue(cu, arg_iter, arg_reg);
1829
1830 ++arg_reg;
1831 if (shorty[i] == 'J' || shorty[i] == 'D') {
1832 // Wide types, such as long and double, are using a pair of registers
1833 // to store the value, so we have to increase arg_reg again.
1834 ++arg_reg;
buzbeeb03f4872012-06-11 15:22:11 -07001835 }
1836 }
buzbeeb03f4872012-06-11 15:22:11 -07001837 }
buzbeefa57c472012-11-21 12:06:18 -08001838 } else if (bb->block_type == kExitBlock) {
buzbee2cfc6392012-05-07 14:51:40 -07001839 /*
1840 * Because of the differences between how MIR/LIR and llvm handle exit
1841 * blocks, we won't explicitly covert them. On the llvm-to-lir
1842 * path, it will need to be regenereated.
1843 */
1844 return false;
buzbeefa57c472012-11-21 12:06:18 -08001845 } else if (bb->block_type == kExceptionHandling) {
buzbee6969d502012-06-15 16:40:31 -07001846 /*
1847 * Because we're deferring null checking, delete the associated empty
1848 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001849 */
buzbeefa57c472012-11-21 12:06:18 -08001850 llvm_bb->eraseFromParent();
buzbee6969d502012-06-15 16:40:31 -07001851 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001852 }
1853
buzbee26f10ee2012-12-21 11:16:29 -08001854 HandlePhiNodes(cu, bb, llvm_bb);
1855
buzbee28c9a832012-11-21 15:39:13 -08001856 for (MIR* mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
buzbee2cfc6392012-05-07 14:51:40 -07001857
buzbeefa57c472012-11-21 12:06:18 -08001858 SetDexOffset(cu, mir->offset);
buzbee2cfc6392012-05-07 14:51:40 -07001859
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001860 int opcode = mir->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -08001861 Instruction::Format dalvik_format =
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001862 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001863
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001864 if (opcode == kMirOpCheck) {
1865 // Combine check and work halves of throwing instruction.
buzbeefa57c472012-11-21 12:06:18 -08001866 MIR* work_half = mir->meta.throw_insn;
1867 mir->dalvikInsn.opcode = work_half->dalvikInsn.opcode;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001868 opcode = mir->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -08001869 SSARepresentation* ssa_rep = work_half->ssa_rep;
1870 work_half->ssa_rep = mir->ssa_rep;
1871 mir->ssa_rep = ssa_rep;
buzbeea169e1d2012-12-05 14:26:44 -08001872 work_half->meta.original_opcode = work_half->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -08001873 work_half->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1874 if (bb->successor_block_list.block_list_type == kCatch) {
1875 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001876 greenland::IntrinsicHelper::CatchTargets);
buzbeefa57c472012-11-21 12:06:18 -08001877 llvm::Value* switch_key =
1878 cu->irb->CreateCall(intr, cu->irb->getInt32(mir->offset));
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001879 GrowableListIterator iter;
buzbeefa57c472012-11-21 12:06:18 -08001880 GrowableListIteratorInit(&bb->successor_block_list.blocks, &iter);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001881 // New basic block to use for work half
buzbeefa57c472012-11-21 12:06:18 -08001882 llvm::BasicBlock* work_bb =
1883 llvm::BasicBlock::Create(*cu->context, "", cu->func);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001884 llvm::SwitchInst* sw =
buzbeefa57c472012-11-21 12:06:18 -08001885 cu->irb->CreateSwitch(switch_key, work_bb,
1886 bb->successor_block_list.blocks.num_used);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001887 while (true) {
buzbeefa57c472012-11-21 12:06:18 -08001888 SuccessorBlockInfo *successor_block_info =
buzbee52a77fc2012-11-20 19:50:46 -08001889 reinterpret_cast<SuccessorBlockInfo*>(GrowableListIteratorNext(&iter));
buzbeefa57c472012-11-21 12:06:18 -08001890 if (successor_block_info == NULL) break;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001891 llvm::BasicBlock *target =
buzbeefa57c472012-11-21 12:06:18 -08001892 GetLLVMBlock(cu, successor_block_info->block->id);
1893 int type_index = successor_block_info->key;
1894 sw->addCase(cu->irb->getInt32(type_index), target);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001895 }
buzbeefa57c472012-11-21 12:06:18 -08001896 llvm_bb = work_bb;
1897 cu->irb->SetInsertPoint(llvm_bb);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001898 }
1899 }
1900
1901 if (opcode >= kMirOpFirst) {
buzbeefa57c472012-11-21 12:06:18 -08001902 ConvertExtendedMIR(cu, bb, mir, llvm_bb);
buzbee2cfc6392012-05-07 14:51:40 -07001903 continue;
1904 }
1905
buzbeefa57c472012-11-21 12:06:18 -08001906 bool not_handled = ConvertMIRNode(cu, mir, bb, llvm_bb,
1907 NULL /* label_list */);
1908 if (not_handled) {
1909 Instruction::Code dalvik_opcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001910 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001911 mir->offset, opcode,
buzbeefa57c472012-11-21 12:06:18 -08001912 Instruction::Name(dalvik_opcode),
1913 dalvik_format);
buzbee2cfc6392012-05-07 14:51:40 -07001914 }
1915 }
1916
buzbeefa57c472012-11-21 12:06:18 -08001917 if (bb->block_type == kEntryBlock) {
1918 cu->entryTarget_bb = GetLLVMBlock(cu, bb->fall_through->id);
buzbeebbdd0532013-02-07 09:33:02 -08001919 } else if ((bb->fall_through != NULL) && !bb->terminated_by_return) {
buzbeefa57c472012-11-21 12:06:18 -08001920 cu->irb->CreateBr(GetLLVMBlock(cu, bb->fall_through->id));
buzbee2cfc6392012-05-07 14:51:40 -07001921 }
1922
1923 return false;
1924}
1925
buzbeefa57c472012-11-21 12:06:18 -08001926char RemapShorty(char shorty_type) {
buzbee4f4dfc72012-07-02 14:54:44 -07001927 /*
1928 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1929 * and longs/doubles are represented as a pair of registers. When sub-word
1930 * arguments (and method results) are passed, they are extended to Dalvik
1931 * virtual register containers. Because llvm is picky about type consistency,
1932 * we must either cast the "real" type to 32-bit container multiple Dalvik
1933 * register types, or always use the expanded values.
1934 * Here, we're doing the latter. We map the shorty signature to container
1935 * types (which is valid so long as we always do a real expansion of passed
1936 * arguments and field loads).
1937 */
buzbeefa57c472012-11-21 12:06:18 -08001938 switch(shorty_type) {
1939 case 'Z' : shorty_type = 'I'; break;
1940 case 'B' : shorty_type = 'I'; break;
1941 case 'S' : shorty_type = 'I'; break;
1942 case 'C' : shorty_type = 'I'; break;
buzbee4f4dfc72012-07-02 14:54:44 -07001943 default: break;
1944 }
buzbeefa57c472012-11-21 12:06:18 -08001945 return shorty_type;
buzbee4f4dfc72012-07-02 14:54:44 -07001946}
1947
buzbeefa57c472012-11-21 12:06:18 -08001948static llvm::FunctionType* GetFunctionType(CompilationUnit* cu) {
buzbee2cfc6392012-05-07 14:51:40 -07001949
1950 // Get return type
buzbeefa57c472012-11-21 12:06:18 -08001951 llvm::Type* ret_type = cu->irb->GetJType(RemapShorty(cu->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001952 greenland::kAccurate);
1953
1954 // Get argument type
1955 std::vector<llvm::Type*> args_type;
1956
1957 // method object
buzbeefa57c472012-11-21 12:06:18 -08001958 args_type.push_back(cu->irb->GetJMethodTy());
buzbee2cfc6392012-05-07 14:51:40 -07001959
1960 // Do we have a "this"?
buzbeefa57c472012-11-21 12:06:18 -08001961 if ((cu->access_flags & kAccStatic) == 0) {
1962 args_type.push_back(cu->irb->GetJObjectTy());
buzbee2cfc6392012-05-07 14:51:40 -07001963 }
1964
buzbeefa57c472012-11-21 12:06:18 -08001965 for (uint32_t i = 1; i < strlen(cu->shorty); ++i) {
1966 args_type.push_back(cu->irb->GetJType(RemapShorty(cu->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001967 greenland::kAccurate));
1968 }
1969
1970 return llvm::FunctionType::get(ret_type, args_type, false);
1971}
1972
buzbeefa57c472012-11-21 12:06:18 -08001973static bool CreateFunction(CompilationUnit* cu) {
1974 std::string func_name(PrettyMethod(cu->method_idx, *cu->dex_file,
buzbee2cfc6392012-05-07 14:51:40 -07001975 /* with_signature */ false));
buzbeefa57c472012-11-21 12:06:18 -08001976 llvm::FunctionType* func_type = GetFunctionType(cu);
buzbee2cfc6392012-05-07 14:51:40 -07001977
1978 if (func_type == NULL) {
1979 return false;
1980 }
1981
buzbeefa57c472012-11-21 12:06:18 -08001982 cu->func = llvm::Function::Create(func_type,
buzbee2cfc6392012-05-07 14:51:40 -07001983 llvm::Function::ExternalLinkage,
buzbeefa57c472012-11-21 12:06:18 -08001984 func_name, cu->module);
buzbee2cfc6392012-05-07 14:51:40 -07001985
buzbeefa57c472012-11-21 12:06:18 -08001986 llvm::Function::arg_iterator arg_iter(cu->func->arg_begin());
1987 llvm::Function::arg_iterator arg_end(cu->func->arg_end());
buzbee2cfc6392012-05-07 14:51:40 -07001988
1989 arg_iter->setName("method");
1990 ++arg_iter;
1991
buzbeefa57c472012-11-21 12:06:18 -08001992 int start_sreg = cu->num_regs;
buzbee2cfc6392012-05-07 14:51:40 -07001993
1994 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
buzbeefa57c472012-11-21 12:06:18 -08001995 arg_iter->setName(StringPrintf("v%i_0", start_sreg));
1996 start_sreg += cu->reg_location[start_sreg].wide ? 2 : 1;
buzbee2cfc6392012-05-07 14:51:40 -07001997 }
1998
1999 return true;
2000}
2001
buzbeefa57c472012-11-21 12:06:18 -08002002static bool CreateLLVMBasicBlock(CompilationUnit* cu, BasicBlock* bb)
buzbee2cfc6392012-05-07 14:51:40 -07002003{
2004 // Skip the exit block
buzbeefa57c472012-11-21 12:06:18 -08002005 if ((bb->block_type == kDead) ||(bb->block_type == kExitBlock)) {
2006 cu->id_to_block_map.Put(bb->id, NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002007 } else {
buzbeefa57c472012-11-21 12:06:18 -08002008 int offset = bb->start_offset;
2009 bool entry_block = (bb->block_type == kEntryBlock);
2010 llvm::BasicBlock* llvm_bb =
2011 llvm::BasicBlock::Create(*cu->context, entry_block ? "entry" :
2012 StringPrintf(kLabelFormat, bb->catch_entry ? kCatchBlock :
2013 kNormalBlock, offset, bb->id), cu->func);
2014 if (entry_block) {
2015 cu->entry_bb = llvm_bb;
2016 cu->placeholder_bb =
2017 llvm::BasicBlock::Create(*cu->context, "placeholder",
2018 cu->func);
buzbee2cfc6392012-05-07 14:51:40 -07002019 }
buzbeefa57c472012-11-21 12:06:18 -08002020 cu->id_to_block_map.Put(bb->id, llvm_bb);
buzbee2cfc6392012-05-07 14:51:40 -07002021 }
2022 return false;
2023}
2024
2025
2026/*
2027 * Convert MIR to LLVM_IR
2028 * o For each ssa name, create LLVM named value. Type these
2029 * appropriately, and ignore high half of wide and double operands.
2030 * o For each MIR basic block, create an LLVM basic block.
2031 * o Iterate through the MIR a basic block at a time, setting arguments
2032 * to recovered ssa name.
2033 */
buzbeefa57c472012-11-21 12:06:18 -08002034void MethodMIR2Bitcode(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -07002035{
buzbeefa57c472012-11-21 12:06:18 -08002036 InitIR(cu);
2037 CompilerInitGrowableList(cu, &cu->llvm_values, cu->num_ssa_regs);
buzbee2cfc6392012-05-07 14:51:40 -07002038
2039 // Create the function
buzbeefa57c472012-11-21 12:06:18 -08002040 CreateFunction(cu);
buzbee2cfc6392012-05-07 14:51:40 -07002041
2042 // Create an LLVM basic block for each MIR block in dfs preorder
buzbeefa57c472012-11-21 12:06:18 -08002043 DataFlowAnalysisDispatcher(cu, CreateLLVMBasicBlock,
2044 kPreOrderDFSTraversal, false /* is_iterative */);
buzbee2cfc6392012-05-07 14:51:40 -07002045 /*
2046 * Create an llvm named value for each MIR SSA name. Note: we'll use
2047 * placeholders for all non-argument values (because we haven't seen
2048 * the definition yet).
2049 */
buzbeefa57c472012-11-21 12:06:18 -08002050 cu->irb->SetInsertPoint(cu->placeholder_bb);
2051 llvm::Function::arg_iterator arg_iter(cu->func->arg_begin());
buzbee2cfc6392012-05-07 14:51:40 -07002052 arg_iter++; /* Skip path method */
buzbeefa57c472012-11-21 12:06:18 -08002053 for (int i = 0; i < cu->num_ssa_regs; i++) {
buzbee2cfc6392012-05-07 14:51:40 -07002054 llvm::Value* val;
buzbeefa57c472012-11-21 12:06:18 -08002055 RegLocation rl_temp = cu->reg_location[i];
2056 if ((SRegToVReg(cu, i) < 0) || rl_temp.high_word) {
2057 InsertGrowableList(cu, &cu->llvm_values, 0);
2058 } else if ((i < cu->num_regs) ||
2059 (i >= (cu->num_regs + cu->num_ins))) {
2060 llvm::Constant* imm_value = cu->reg_location[i].wide ?
2061 cu->irb->GetJLong(0) : cu->irb->GetJInt(0);
2062 val = EmitConst(cu, imm_value, cu->reg_location[i]);
2063 val->setName(LlvmSSAName(cu, i));
2064 InsertGrowableList(cu, &cu->llvm_values, reinterpret_cast<uintptr_t>(val));
buzbee2cfc6392012-05-07 14:51:40 -07002065 } else {
2066 // Recover previously-created argument values
buzbeefa57c472012-11-21 12:06:18 -08002067 llvm::Value* arg_val = arg_iter++;
2068 InsertGrowableList(cu, &cu->llvm_values, reinterpret_cast<uintptr_t>(arg_val));
buzbee2cfc6392012-05-07 14:51:40 -07002069 }
2070 }
buzbee2cfc6392012-05-07 14:51:40 -07002071
buzbeefa57c472012-11-21 12:06:18 -08002072 DataFlowAnalysisDispatcher(cu, BlockBitcodeConversion,
buzbee2cfc6392012-05-07 14:51:40 -07002073 kPreOrderDFSTraversal, false /* Iterative */);
2074
buzbee4be777b2012-07-12 14:38:18 -07002075 /*
2076 * In a few rare cases of verification failure, the verifier will
2077 * replace one or more Dalvik opcodes with the special
2078 * throw-verification-failure opcode. This can leave the SSA graph
2079 * in an invalid state, as definitions may be lost, while uses retained.
2080 * To work around this problem, we insert placeholder definitions for
2081 * all Dalvik SSA regs in the "placeholder" block. Here, after
2082 * bitcode conversion is complete, we examine those placeholder definitions
2083 * and delete any with no references (which normally is all of them).
2084 *
2085 * If any definitions remain, we link the placeholder block into the
2086 * CFG. Otherwise, it is deleted.
2087 */
buzbeefa57c472012-11-21 12:06:18 -08002088 for (llvm::BasicBlock::iterator it = cu->placeholder_bb->begin(),
2089 it_end = cu->placeholder_bb->end(); it != it_end;) {
buzbee4be777b2012-07-12 14:38:18 -07002090 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2091 DCHECK(inst != NULL);
2092 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2093 DCHECK(val != NULL);
2094 if (val->getNumUses() == 0) {
2095 inst->eraseFromParent();
2096 }
2097 }
buzbeefa57c472012-11-21 12:06:18 -08002098 SetDexOffset(cu, 0);
2099 if (cu->placeholder_bb->empty()) {
2100 cu->placeholder_bb->eraseFromParent();
buzbee4be777b2012-07-12 14:38:18 -07002101 } else {
buzbeefa57c472012-11-21 12:06:18 -08002102 cu->irb->SetInsertPoint(cu->placeholder_bb);
2103 cu->irb->CreateBr(cu->entryTarget_bb);
2104 cu->entryTarget_bb = cu->placeholder_bb;
buzbee4be777b2012-07-12 14:38:18 -07002105 }
buzbeefa57c472012-11-21 12:06:18 -08002106 cu->irb->SetInsertPoint(cu->entry_bb);
2107 cu->irb->CreateBr(cu->entryTarget_bb);
buzbee2cfc6392012-05-07 14:51:40 -07002108
buzbeefa57c472012-11-21 12:06:18 -08002109 if (cu->enable_debug & (1 << kDebugVerifyBitcode)) {
2110 if (llvm::verifyFunction(*cu->func, llvm::PrintMessageAction)) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002111 LOG(INFO) << "Bitcode verification FAILED for "
buzbeefa57c472012-11-21 12:06:18 -08002112 << PrettyMethod(cu->method_idx, *cu->dex_file)
2113 << " of size " << cu->insns_size;
2114 cu->enable_debug |= (1 << kDebugDumpBitcodeFile);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002115 }
2116 }
buzbee2cfc6392012-05-07 14:51:40 -07002117
buzbeefa57c472012-11-21 12:06:18 -08002118 if (cu->enable_debug & (1 << kDebugDumpBitcodeFile)) {
buzbeead8f15e2012-06-18 14:49:45 -07002119 // Write bitcode to file
2120 std::string errmsg;
buzbeefa57c472012-11-21 12:06:18 -08002121 std::string fname(PrettyMethod(cu->method_idx, *cu->dex_file));
buzbee52a77fc2012-11-20 19:50:46 -08002122 ReplaceSpecialChars(fname);
buzbee6459e7c2012-10-02 14:42:41 -07002123 // TODO: make configurable change naming mechanism to avoid fname length issues.
buzbee4f1181f2012-06-22 13:52:12 -07002124 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002125
buzbee6459e7c2012-10-02 14:42:41 -07002126 if (fname.size() > 240) {
2127 LOG(INFO) << "Warning: bitcode filename too long. Truncated.";
2128 fname.resize(240);
2129 }
2130
buzbeead8f15e2012-06-18 14:49:45 -07002131 llvm::OwningPtr<llvm::tool_output_file> out_file(
2132 new llvm::tool_output_file(fname.c_str(), errmsg,
2133 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002134
buzbeead8f15e2012-06-18 14:49:45 -07002135 if (!errmsg.empty()) {
2136 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2137 }
2138
buzbeefa57c472012-11-21 12:06:18 -08002139 llvm::WriteBitcodeToFile(cu->module, out_file->os());
buzbeead8f15e2012-06-18 14:49:45 -07002140 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002141 }
buzbee2cfc6392012-05-07 14:51:40 -07002142}
2143
buzbeefa57c472012-11-21 12:06:18 -08002144static RegLocation GetLoc(CompilationUnit* cu, llvm::Value* val) {
buzbee2cfc6392012-05-07 14:51:40 -07002145 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002146 DCHECK(val != NULL);
buzbeefa57c472012-11-21 12:06:18 -08002147 SafeMap<llvm::Value*, RegLocation>::iterator it = cu->loc_map.find(val);
2148 if (it == cu->loc_map.end()) {
2149 std::string val_name = val->getName().str();
2150 if (val_name.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002151 // FIXME: need to be more robust, handle FP and be in a position to
2152 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002153 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2154 memset(&res, 0, sizeof(res));
2155 res.location = kLocPhysReg;
buzbeefa57c472012-11-21 12:06:18 -08002156 res.low_reg = AllocTemp(cu);
buzbee4f1181f2012-06-22 13:52:12 -07002157 res.home = true;
buzbeefa57c472012-11-21 12:06:18 -08002158 res.s_reg_low = INVALID_SREG;
2159 res.orig_sreg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002160 llvm::Type* ty = val->getType();
buzbeefa57c472012-11-21 12:06:18 -08002161 res.wide = ((ty == cu->irb->getInt64Ty()) ||
2162 (ty == cu->irb->getDoubleTy()));
buzbee101305f2012-06-28 18:00:56 -07002163 if (res.wide) {
buzbeefa57c472012-11-21 12:06:18 -08002164 res.high_reg = AllocTemp(cu);
buzbee101305f2012-06-28 18:00:56 -07002165 }
buzbeefa57c472012-11-21 12:06:18 -08002166 cu->loc_map.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002167 } else {
buzbeefa57c472012-11-21 12:06:18 -08002168 DCHECK_EQ(val_name[0], 'v');
2169 int base_sreg = INVALID_SREG;
2170 sscanf(val_name.c_str(), "v%d_", &base_sreg);
2171 res = cu->reg_location[base_sreg];
2172 cu->loc_map.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002173 }
2174 } else {
2175 res = it->second;
2176 }
2177 return res;
2178}
2179
buzbeefa57c472012-11-21 12:06:18 -08002180static Instruction::Code GetDalvikOpcode(OpKind op, bool is_const, bool is_wide)
buzbee2cfc6392012-05-07 14:51:40 -07002181{
2182 Instruction::Code res = Instruction::NOP;
buzbeefa57c472012-11-21 12:06:18 -08002183 if (is_wide) {
buzbee2cfc6392012-05-07 14:51:40 -07002184 switch(op) {
2185 case kOpAdd: res = Instruction::ADD_LONG; break;
2186 case kOpSub: res = Instruction::SUB_LONG; break;
2187 case kOpMul: res = Instruction::MUL_LONG; break;
2188 case kOpDiv: res = Instruction::DIV_LONG; break;
2189 case kOpRem: res = Instruction::REM_LONG; break;
2190 case kOpAnd: res = Instruction::AND_LONG; break;
2191 case kOpOr: res = Instruction::OR_LONG; break;
2192 case kOpXor: res = Instruction::XOR_LONG; break;
2193 case kOpLsl: res = Instruction::SHL_LONG; break;
2194 case kOpLsr: res = Instruction::USHR_LONG; break;
2195 case kOpAsr: res = Instruction::SHR_LONG; break;
2196 default: LOG(FATAL) << "Unexpected OpKind " << op;
2197 }
buzbeefa57c472012-11-21 12:06:18 -08002198 } else if (is_const){
buzbee2cfc6392012-05-07 14:51:40 -07002199 switch(op) {
2200 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2201 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2202 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2203 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2204 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2205 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2206 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2207 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2208 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2209 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2210 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2211 default: LOG(FATAL) << "Unexpected OpKind " << op;
2212 }
2213 } else {
2214 switch(op) {
2215 case kOpAdd: res = Instruction::ADD_INT; break;
2216 case kOpSub: res = Instruction::SUB_INT; break;
2217 case kOpMul: res = Instruction::MUL_INT; break;
2218 case kOpDiv: res = Instruction::DIV_INT; break;
2219 case kOpRem: res = Instruction::REM_INT; break;
2220 case kOpAnd: res = Instruction::AND_INT; break;
2221 case kOpOr: res = Instruction::OR_INT; break;
2222 case kOpXor: res = Instruction::XOR_INT; break;
2223 case kOpLsl: res = Instruction::SHL_INT; break;
2224 case kOpLsr: res = Instruction::USHR_INT; break;
2225 case kOpAsr: res = Instruction::SHR_INT; break;
2226 default: LOG(FATAL) << "Unexpected OpKind " << op;
2227 }
2228 }
2229 return res;
2230}
2231
buzbeefa57c472012-11-21 12:06:18 -08002232static Instruction::Code GetDalvikFPOpcode(OpKind op, bool is_const, bool is_wide)
buzbee4f1181f2012-06-22 13:52:12 -07002233{
2234 Instruction::Code res = Instruction::NOP;
buzbeefa57c472012-11-21 12:06:18 -08002235 if (is_wide) {
buzbee4f1181f2012-06-22 13:52:12 -07002236 switch(op) {
2237 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2238 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2239 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2240 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2241 case kOpRem: res = Instruction::REM_DOUBLE; break;
2242 default: LOG(FATAL) << "Unexpected OpKind " << op;
2243 }
2244 } else {
2245 switch(op) {
2246 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2247 case kOpSub: res = Instruction::SUB_FLOAT; break;
2248 case kOpMul: res = Instruction::MUL_FLOAT; break;
2249 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2250 case kOpRem: res = Instruction::REM_FLOAT; break;
2251 default: LOG(FATAL) << "Unexpected OpKind " << op;
2252 }
2253 }
2254 return res;
2255}
2256
buzbeefa57c472012-11-21 12:06:18 -08002257static void CvtBinFPOp(CompilationUnit* cu, OpKind op, llvm::Instruction* inst)
buzbee4f1181f2012-06-22 13:52:12 -07002258{
buzbee02031b12012-11-23 09:41:35 -08002259 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002260 RegLocation rl_dest = GetLoc(cu, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002261 /*
2262 * Normally, we won't ever generate an FP operation with an immediate
2263 * operand (not supported in Dex instruction set). However, the IR builder
buzbeefa57c472012-11-21 12:06:18 -08002264 * may insert them - in particular for create_neg_fp. Recognize this case
buzbee4f4dfc72012-07-02 14:54:44 -07002265 * and deal with it.
2266 */
2267 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2268 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2269 DCHECK(op2C == NULL);
2270 if ((op1C != NULL) && (op == kOpSub)) {
buzbeefa57c472012-11-21 12:06:18 -08002271 RegLocation rl_src = GetLoc(cu, inst->getOperand(1));
2272 if (rl_dest.wide) {
buzbee02031b12012-11-23 09:41:35 -08002273 cg->GenArithOpDouble(cu, Instruction::NEG_DOUBLE, rl_dest, rl_src, rl_src);
buzbee4f4dfc72012-07-02 14:54:44 -07002274 } else {
buzbee02031b12012-11-23 09:41:35 -08002275 cg->GenArithOpFloat(cu, Instruction::NEG_FLOAT, rl_dest, rl_src, rl_src);
buzbee4f4dfc72012-07-02 14:54:44 -07002276 }
buzbee4f1181f2012-06-22 13:52:12 -07002277 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002278 DCHECK(op1C == NULL);
buzbeefa57c472012-11-21 12:06:18 -08002279 RegLocation rl_src1 = GetLoc(cu, inst->getOperand(0));
2280 RegLocation rl_src2 = GetLoc(cu, inst->getOperand(1));
2281 Instruction::Code dalvik_op = GetDalvikFPOpcode(op, false, rl_dest.wide);
2282 if (rl_dest.wide) {
buzbee02031b12012-11-23 09:41:35 -08002283 cg->GenArithOpDouble(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
buzbee4f4dfc72012-07-02 14:54:44 -07002284 } else {
buzbee02031b12012-11-23 09:41:35 -08002285 cg->GenArithOpFloat(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
buzbee4f4dfc72012-07-02 14:54:44 -07002286 }
buzbee4f1181f2012-06-22 13:52:12 -07002287 }
2288}
2289
buzbeefa57c472012-11-21 12:06:18 -08002290static void CvtIntNarrowing(CompilationUnit* cu, llvm::Instruction* inst,
buzbee101305f2012-06-28 18:00:56 -07002291 Instruction::Code opcode)
2292{
buzbee02031b12012-11-23 09:41:35 -08002293 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002294 RegLocation rl_dest = GetLoc(cu, inst);
2295 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
buzbee02031b12012-11-23 09:41:35 -08002296 cg->GenIntNarrowing(cu, opcode, rl_dest, rl_src);
buzbee101305f2012-06-28 18:00:56 -07002297}
2298
buzbeefa57c472012-11-21 12:06:18 -08002299static void CvtIntToFP(CompilationUnit* cu, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002300{
buzbee02031b12012-11-23 09:41:35 -08002301 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002302 RegLocation rl_dest = GetLoc(cu, inst);
2303 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002304 Instruction::Code opcode;
buzbeefa57c472012-11-21 12:06:18 -08002305 if (rl_dest.wide) {
2306 if (rl_src.wide) {
buzbee76592632012-06-29 15:18:35 -07002307 opcode = Instruction::LONG_TO_DOUBLE;
2308 } else {
2309 opcode = Instruction::INT_TO_DOUBLE;
2310 }
2311 } else {
buzbeefa57c472012-11-21 12:06:18 -08002312 if (rl_src.wide) {
buzbee76592632012-06-29 15:18:35 -07002313 opcode = Instruction::LONG_TO_FLOAT;
2314 } else {
2315 opcode = Instruction::INT_TO_FLOAT;
2316 }
2317 }
buzbee02031b12012-11-23 09:41:35 -08002318 cg->GenConversion(cu, opcode, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002319}
2320
buzbeefa57c472012-11-21 12:06:18 -08002321static void CvtFPToInt(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002322{
buzbee02031b12012-11-23 09:41:35 -08002323 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002324 RegLocation rl_dest = GetLoc(cu, call_inst);
2325 RegLocation rl_src = GetLoc(cu, call_inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002326 Instruction::Code opcode;
buzbeefa57c472012-11-21 12:06:18 -08002327 if (rl_dest.wide) {
2328 if (rl_src.wide) {
buzbee76592632012-06-29 15:18:35 -07002329 opcode = Instruction::DOUBLE_TO_LONG;
2330 } else {
2331 opcode = Instruction::FLOAT_TO_LONG;
2332 }
2333 } else {
buzbeefa57c472012-11-21 12:06:18 -08002334 if (rl_src.wide) {
buzbee76592632012-06-29 15:18:35 -07002335 opcode = Instruction::DOUBLE_TO_INT;
2336 } else {
2337 opcode = Instruction::FLOAT_TO_INT;
2338 }
2339 }
buzbee02031b12012-11-23 09:41:35 -08002340 cg->GenConversion(cu, opcode, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002341}
2342
buzbeefa57c472012-11-21 12:06:18 -08002343static void CvtFloatToDouble(CompilationUnit* cu, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002344{
buzbee02031b12012-11-23 09:41:35 -08002345 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002346 RegLocation rl_dest = GetLoc(cu, inst);
2347 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
buzbee02031b12012-11-23 09:41:35 -08002348 cg->GenConversion(cu, Instruction::FLOAT_TO_DOUBLE, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002349}
2350
buzbeefa57c472012-11-21 12:06:18 -08002351static void CvtTrunc(CompilationUnit* cu, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002352{
buzbee02031b12012-11-23 09:41:35 -08002353 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002354 RegLocation rl_dest = GetLoc(cu, inst);
2355 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
2356 rl_src = UpdateLocWide(cu, rl_src);
2357 rl_src = WideToNarrow(cu, rl_src);
buzbee02031b12012-11-23 09:41:35 -08002358 cg->StoreValue(cu, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002359}
2360
buzbeefa57c472012-11-21 12:06:18 -08002361static void CvtDoubleToFloat(CompilationUnit* cu, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002362{
buzbee02031b12012-11-23 09:41:35 -08002363 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002364 RegLocation rl_dest = GetLoc(cu, inst);
2365 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
buzbee02031b12012-11-23 09:41:35 -08002366 cg->GenConversion(cu, Instruction::DOUBLE_TO_FLOAT, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002367}
2368
2369
buzbeefa57c472012-11-21 12:06:18 -08002370static void CvtIntExt(CompilationUnit* cu, llvm::Instruction* inst, bool is_signed)
buzbee101305f2012-06-28 18:00:56 -07002371{
buzbee02031b12012-11-23 09:41:35 -08002372 Codegen* cg = cu->cg.get();
buzbee101305f2012-06-28 18:00:56 -07002373 // TODO: evaluate src/tgt types and add general support for more than int to long
buzbeefa57c472012-11-21 12:06:18 -08002374 RegLocation rl_dest = GetLoc(cu, inst);
2375 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
2376 DCHECK(rl_dest.wide);
2377 DCHECK(!rl_src.wide);
2378 DCHECK(!rl_dest.fp);
2379 DCHECK(!rl_src.fp);
2380 RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
2381 if (rl_src.location == kLocPhysReg) {
buzbee02031b12012-11-23 09:41:35 -08002382 cg->OpRegCopy(cu, rl_result.low_reg, rl_src.low_reg);
buzbee101305f2012-06-28 18:00:56 -07002383 } else {
buzbee02031b12012-11-23 09:41:35 -08002384 cg->LoadValueDirect(cu, rl_src, rl_result.low_reg);
buzbee101305f2012-06-28 18:00:56 -07002385 }
buzbeefa57c472012-11-21 12:06:18 -08002386 if (is_signed) {
buzbee02031b12012-11-23 09:41:35 -08002387 cg->OpRegRegImm(cu, kOpAsr, rl_result.high_reg, rl_result.low_reg, 31);
buzbee101305f2012-06-28 18:00:56 -07002388 } else {
buzbee02031b12012-11-23 09:41:35 -08002389 cg->LoadConstant(cu, rl_result.high_reg, 0);
buzbee101305f2012-06-28 18:00:56 -07002390 }
buzbee02031b12012-11-23 09:41:35 -08002391 cg->StoreValueWide(cu, rl_dest, rl_result);
buzbee101305f2012-06-28 18:00:56 -07002392}
2393
buzbeefa57c472012-11-21 12:06:18 -08002394static void CvtBinOp(CompilationUnit* cu, OpKind op, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002395{
buzbee02031b12012-11-23 09:41:35 -08002396 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002397 RegLocation rl_dest = GetLoc(cu, inst);
buzbee2cfc6392012-05-07 14:51:40 -07002398 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002399 // Special-case RSUB/NEG
buzbeefa57c472012-11-21 12:06:18 -08002400 llvm::ConstantInt* lhs_imm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2401 if ((op == kOpSub) && (lhs_imm != NULL)) {
2402 RegLocation rl_src1 = GetLoc(cu, inst->getOperand(1));
2403 if (rl_src1.wide) {
2404 DCHECK_EQ(lhs_imm->getSExtValue(), 0);
buzbee02031b12012-11-23 09:41:35 -08002405 cg->GenArithOpLong(cu, Instruction::NEG_LONG, rl_dest, rl_src1, rl_src1);
buzbeef58c12c2012-07-03 15:06:29 -07002406 } else {
buzbee02031b12012-11-23 09:41:35 -08002407 cg->GenArithOpIntLit(cu, Instruction::RSUB_INT, rl_dest, rl_src1,
buzbeefa57c472012-11-21 12:06:18 -08002408 lhs_imm->getSExtValue());
buzbeef58c12c2012-07-03 15:06:29 -07002409 }
buzbee4f1181f2012-06-22 13:52:12 -07002410 return;
2411 }
buzbeefa57c472012-11-21 12:06:18 -08002412 DCHECK(lhs_imm == NULL);
2413 RegLocation rl_src1 = GetLoc(cu, inst->getOperand(0));
buzbee2cfc6392012-05-07 14:51:40 -07002414 llvm::Value* rhs = inst->getOperand(1);
buzbeefa57c472012-11-21 12:06:18 -08002415 llvm::ConstantInt* const_rhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2416 if (!rl_dest.wide && (const_rhs != NULL)) {
2417 Instruction::Code dalvik_op = GetDalvikOpcode(op, true, false);
buzbee02031b12012-11-23 09:41:35 -08002418 cg->GenArithOpIntLit(cu, dalvik_op, rl_dest, rl_src1, const_rhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002419 } else {
buzbeefa57c472012-11-21 12:06:18 -08002420 Instruction::Code dalvik_op = GetDalvikOpcode(op, false, rl_dest.wide);
2421 RegLocation rl_src2;
2422 if (const_rhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002423 // ir_builder converts NOT_LONG to xor src, -1. Restore
buzbeefa57c472012-11-21 12:06:18 -08002424 DCHECK_EQ(dalvik_op, Instruction::XOR_LONG);
2425 DCHECK_EQ(-1L, const_rhs->getSExtValue());
2426 dalvik_op = Instruction::NOT_LONG;
2427 rl_src2 = rl_src1;
buzbee9a2487f2012-07-26 14:01:13 -07002428 } else {
buzbeefa57c472012-11-21 12:06:18 -08002429 rl_src2 = GetLoc(cu, rhs);
buzbee9a2487f2012-07-26 14:01:13 -07002430 }
buzbeefa57c472012-11-21 12:06:18 -08002431 if (rl_dest.wide) {
buzbee02031b12012-11-23 09:41:35 -08002432 cg->GenArithOpLong(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
buzbee2cfc6392012-05-07 14:51:40 -07002433 } else {
buzbee02031b12012-11-23 09:41:35 -08002434 cg->GenArithOpInt(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
buzbee2cfc6392012-05-07 14:51:40 -07002435 }
2436 }
2437}
2438
buzbeefa57c472012-11-21 12:06:18 -08002439static void CvtShiftOp(CompilationUnit* cu, Instruction::Code opcode, llvm::CallInst* call_inst)
buzbee101305f2012-06-28 18:00:56 -07002440{
buzbee02031b12012-11-23 09:41:35 -08002441 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002442 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2443 RegLocation rl_dest = GetLoc(cu, call_inst);
2444 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(0));
2445 llvm::Value* rhs = call_inst->getArgOperand(1);
buzbee2a83e8f2012-07-13 16:42:30 -07002446 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
buzbeefa57c472012-11-21 12:06:18 -08002447 DCHECK(!rl_dest.wide);
buzbee02031b12012-11-23 09:41:35 -08002448 cg->GenArithOpIntLit(cu, opcode, rl_dest, rl_src, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002449 } else {
buzbeefa57c472012-11-21 12:06:18 -08002450 RegLocation rl_shift = GetLoc(cu, rhs);
2451 if (call_inst->getType() == cu->irb->getInt64Ty()) {
buzbee02031b12012-11-23 09:41:35 -08002452 cg->GenShiftOpLong(cu, opcode, rl_dest, rl_src, rl_shift);
buzbee2a83e8f2012-07-13 16:42:30 -07002453 } else {
buzbee02031b12012-11-23 09:41:35 -08002454 cg->GenArithOpInt(cu, opcode, rl_dest, rl_src, rl_shift);
buzbee2a83e8f2012-07-13 16:42:30 -07002455 }
buzbee101305f2012-06-28 18:00:56 -07002456 }
2457}
2458
buzbeefa57c472012-11-21 12:06:18 -08002459static void CvtBr(CompilationUnit* cu, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002460{
buzbee02031b12012-11-23 09:41:35 -08002461 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002462 llvm::BranchInst* br_inst = llvm::dyn_cast<llvm::BranchInst>(inst);
2463 DCHECK(br_inst != NULL);
2464 DCHECK(br_inst->isUnconditional()); // May change - but this is all we use now
2465 llvm::BasicBlock* target_bb = br_inst->getSuccessor(0);
buzbee02031b12012-11-23 09:41:35 -08002466 cg->OpUnconditionalBranch(cu, cu->block_to_label_map.Get(target_bb));
buzbee2cfc6392012-05-07 14:51:40 -07002467}
2468
buzbeefa57c472012-11-21 12:06:18 -08002469static void CvtPhi(CompilationUnit* cu, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002470{
2471 // Nop - these have already been processed
2472}
2473
buzbeefa57c472012-11-21 12:06:18 -08002474static void CvtRet(CompilationUnit* cu, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002475{
buzbee02031b12012-11-23 09:41:35 -08002476 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002477 llvm::ReturnInst* ret_inst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2478 llvm::Value* ret_val = ret_inst->getReturnValue();
2479 if (ret_val != NULL) {
2480 RegLocation rl_src = GetLoc(cu, ret_val);
2481 if (rl_src.wide) {
buzbee02031b12012-11-23 09:41:35 -08002482 cg->StoreValueWide(cu, GetReturnWide(cu, rl_src.fp), rl_src);
buzbee2cfc6392012-05-07 14:51:40 -07002483 } else {
buzbee02031b12012-11-23 09:41:35 -08002484 cg->StoreValue(cu, GetReturn(cu, rl_src.fp), rl_src);
buzbee2cfc6392012-05-07 14:51:40 -07002485 }
2486 }
buzbee02031b12012-11-23 09:41:35 -08002487 cg->GenExitSequence(cu);
buzbee2cfc6392012-05-07 14:51:40 -07002488}
2489
buzbeefa57c472012-11-21 12:06:18 -08002490static ConditionCode GetCond(llvm::ICmpInst::Predicate llvm_cond)
buzbee2cfc6392012-05-07 14:51:40 -07002491{
2492 ConditionCode res = kCondAl;
buzbeefa57c472012-11-21 12:06:18 -08002493 switch(llvm_cond) {
buzbee6969d502012-06-15 16:40:31 -07002494 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002495 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2496 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2497 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002498 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002499 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002500 default: LOG(FATAL) << "Unexpected llvm condition";
2501 }
2502 return res;
2503}
2504
buzbeefa57c472012-11-21 12:06:18 -08002505static void CvtICmp(CompilationUnit* cu, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002506{
buzbee02031b12012-11-23 09:41:35 -08002507 // cg->GenCmpLong(cu, rl_dest, rl_src1, rl_src2)
buzbee2cfc6392012-05-07 14:51:40 -07002508 UNIMPLEMENTED(FATAL);
2509}
2510
buzbeefa57c472012-11-21 12:06:18 -08002511static void CvtICmpBr(CompilationUnit* cu, llvm::Instruction* inst,
2512 llvm::BranchInst* br_inst)
buzbee2cfc6392012-05-07 14:51:40 -07002513{
buzbee02031b12012-11-23 09:41:35 -08002514 Codegen* cg = cu->cg.get();
buzbee2cfc6392012-05-07 14:51:40 -07002515 // Get targets
buzbeefa57c472012-11-21 12:06:18 -08002516 llvm::BasicBlock* taken_bb = br_inst->getSuccessor(0);
2517 LIR* taken = cu->block_to_label_map.Get(taken_bb);
2518 llvm::BasicBlock* fallthrough_bb = br_inst->getSuccessor(1);
2519 LIR* fall_through = cu->block_to_label_map.Get(fallthrough_bb);
buzbee2cfc6392012-05-07 14:51:40 -07002520 // Get comparison operands
buzbeefa57c472012-11-21 12:06:18 -08002521 llvm::ICmpInst* i_cmp_inst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2522 ConditionCode cond = GetCond(i_cmp_inst->getPredicate());
2523 llvm::Value* lhs = i_cmp_inst->getOperand(0);
buzbee2cfc6392012-05-07 14:51:40 -07002524 // Not expecting a constant as 1st operand
2525 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
buzbeefa57c472012-11-21 12:06:18 -08002526 RegLocation rl_src1 = GetLoc(cu, inst->getOperand(0));
buzbee02031b12012-11-23 09:41:35 -08002527 rl_src1 = cg->LoadValue(cu, rl_src1, kCoreReg);
buzbee2cfc6392012-05-07 14:51:40 -07002528 llvm::Value* rhs = inst->getOperand(1);
buzbeefa57c472012-11-21 12:06:18 -08002529 if (cu->instruction_set == kMips) {
buzbeeb046e162012-10-30 15:48:42 -07002530 // Compare and branch in one shot
2531 UNIMPLEMENTED(FATAL);
2532 }
buzbee2cfc6392012-05-07 14:51:40 -07002533 //Compare, then branch
2534 // TODO: handle fused CMP_LONG/IF_xxZ case
2535 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
buzbee02031b12012-11-23 09:41:35 -08002536 cg->OpRegImm(cu, kOpCmp, rl_src1.low_reg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002537 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
buzbee02031b12012-11-23 09:41:35 -08002538 cg->OpRegImm(cu, kOpCmp, rl_src1.low_reg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002539 } else {
buzbeefa57c472012-11-21 12:06:18 -08002540 RegLocation rl_src2 = GetLoc(cu, rhs);
buzbee02031b12012-11-23 09:41:35 -08002541 rl_src2 = cg->LoadValue(cu, rl_src2, kCoreReg);
2542 cg->OpRegReg(cu, kOpCmp, rl_src1.low_reg, rl_src2.low_reg);
buzbee2cfc6392012-05-07 14:51:40 -07002543 }
buzbee02031b12012-11-23 09:41:35 -08002544 cg->OpCondBranch(cu, cond, taken);
buzbee2cfc6392012-05-07 14:51:40 -07002545 // Fallthrough
buzbee02031b12012-11-23 09:41:35 -08002546 cg->OpUnconditionalBranch(cu, fall_through);
buzbee2cfc6392012-05-07 14:51:40 -07002547}
2548
buzbeefa57c472012-11-21 12:06:18 -08002549static void CvtCopy(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee2cfc6392012-05-07 14:51:40 -07002550{
buzbee02031b12012-11-23 09:41:35 -08002551 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002552 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2553 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(0));
2554 RegLocation rl_dest = GetLoc(cu, call_inst);
2555 DCHECK_EQ(rl_src.wide, rl_dest.wide);
2556 DCHECK_EQ(rl_src.fp, rl_dest.fp);
2557 if (rl_src.wide) {
buzbee02031b12012-11-23 09:41:35 -08002558 cg->StoreValueWide(cu, rl_dest, rl_src);
buzbee2cfc6392012-05-07 14:51:40 -07002559 } else {
buzbee02031b12012-11-23 09:41:35 -08002560 cg->StoreValue(cu, rl_dest, rl_src);
buzbee2cfc6392012-05-07 14:51:40 -07002561 }
2562}
2563
2564// Note: Immediate arg is a ConstantInt regardless of result type
buzbeefa57c472012-11-21 12:06:18 -08002565static void CvtConst(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee2cfc6392012-05-07 14:51:40 -07002566{
buzbee02031b12012-11-23 09:41:35 -08002567 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002568 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002569 llvm::ConstantInt* src =
buzbeefa57c472012-11-21 12:06:18 -08002570 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
buzbee2cfc6392012-05-07 14:51:40 -07002571 uint64_t immval = src->getZExtValue();
buzbeefa57c472012-11-21 12:06:18 -08002572 RegLocation rl_dest = GetLoc(cu, call_inst);
2573 RegLocation rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
2574 if (rl_dest.wide) {
buzbee4ef3e452012-12-14 13:35:28 -08002575 cg->LoadConstantWide(cu, rl_result.low_reg, rl_result.high_reg, immval);
buzbee02031b12012-11-23 09:41:35 -08002576 cg->StoreValueWide(cu, rl_dest, rl_result);
buzbee2cfc6392012-05-07 14:51:40 -07002577 } else {
buzbee7da142f2012-11-29 16:33:42 -08002578 int immediate = immval & 0xffffffff;
2579 cg->LoadConstantNoClobber(cu, rl_result.low_reg, immediate);
buzbee02031b12012-11-23 09:41:35 -08002580 cg->StoreValue(cu, rl_dest, rl_result);
buzbee7da142f2012-11-29 16:33:42 -08002581 if (immediate == 0) {
2582 cg->Workaround7250540(cu, rl_dest, rl_result.low_reg);
2583 }
buzbee2cfc6392012-05-07 14:51:40 -07002584 }
2585}
2586
buzbeefa57c472012-11-21 12:06:18 -08002587static void CvtConstObject(CompilationUnit* cu, llvm::CallInst* call_inst, bool is_string)
buzbee6969d502012-06-15 16:40:31 -07002588{
buzbee02031b12012-11-23 09:41:35 -08002589 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002590 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2591 llvm::ConstantInt* idx_val =
2592 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2593 uint32_t index = idx_val->getZExtValue();
2594 RegLocation rl_dest = GetLoc(cu, call_inst);
2595 if (is_string) {
buzbee02031b12012-11-23 09:41:35 -08002596 cg->GenConstString(cu, index, rl_dest);
buzbee101305f2012-06-28 18:00:56 -07002597 } else {
buzbee02031b12012-11-23 09:41:35 -08002598 cg->GenConstClass(cu, index, rl_dest);
buzbee101305f2012-06-28 18:00:56 -07002599 }
2600}
2601
buzbeefa57c472012-11-21 12:06:18 -08002602static void CvtFillArrayData(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee101305f2012-06-28 18:00:56 -07002603{
buzbee02031b12012-11-23 09:41:35 -08002604 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002605 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2606 llvm::ConstantInt* offset_val =
2607 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2608 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
buzbee02031b12012-11-23 09:41:35 -08002609 cg->GenFillArrayData(cu, offset_val->getSExtValue(), rl_src);
buzbee6969d502012-06-15 16:40:31 -07002610}
2611
buzbeefa57c472012-11-21 12:06:18 -08002612static void CvtNewInstance(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee4f1181f2012-06-22 13:52:12 -07002613{
buzbee02031b12012-11-23 09:41:35 -08002614 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002615 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2616 llvm::ConstantInt* type_idx_val =
2617 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2618 uint32_t type_idx = type_idx_val->getZExtValue();
2619 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002620 cg->GenNewInstance(cu, type_idx, rl_dest);
buzbee4f1181f2012-06-22 13:52:12 -07002621}
2622
buzbeefa57c472012-11-21 12:06:18 -08002623static void CvtNewArray(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee8fa0fda2012-06-27 15:44:52 -07002624{
buzbee02031b12012-11-23 09:41:35 -08002625 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002626 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2627 llvm::ConstantInt* type_idx_val =
2628 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2629 uint32_t type_idx = type_idx_val->getZExtValue();
2630 llvm::Value* len = call_inst->getArgOperand(1);
2631 RegLocation rl_len = GetLoc(cu, len);
2632 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002633 cg->GenNewArray(cu, type_idx, rl_dest, rl_len);
buzbee8fa0fda2012-06-27 15:44:52 -07002634}
2635
buzbeefa57c472012-11-21 12:06:18 -08002636static void CvtInstanceOf(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee8fa0fda2012-06-27 15:44:52 -07002637{
buzbee02031b12012-11-23 09:41:35 -08002638 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002639 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2640 llvm::ConstantInt* type_idx_val =
2641 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2642 uint32_t type_idx = type_idx_val->getZExtValue();
2643 llvm::Value* src = call_inst->getArgOperand(1);
2644 RegLocation rl_src = GetLoc(cu, src);
2645 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002646 cg->GenInstanceof(cu, type_idx, rl_dest, rl_src);
buzbee8fa0fda2012-06-27 15:44:52 -07002647}
2648
buzbeefa57c472012-11-21 12:06:18 -08002649static void CvtThrow(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee32412962012-06-26 16:27:56 -07002650{
buzbee02031b12012-11-23 09:41:35 -08002651 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002652 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2653 llvm::Value* src = call_inst->getArgOperand(0);
2654 RegLocation rl_src = GetLoc(cu, src);
buzbee02031b12012-11-23 09:41:35 -08002655 cg->GenThrow(cu, rl_src);
buzbee32412962012-06-26 16:27:56 -07002656}
2657
buzbeefa57c472012-11-21 12:06:18 -08002658static void CvtMonitorEnterExit(CompilationUnit* cu, bool is_enter,
2659 llvm::CallInst* call_inst)
buzbee8fa0fda2012-06-27 15:44:52 -07002660{
buzbee02031b12012-11-23 09:41:35 -08002661 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002662 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2663 llvm::ConstantInt* opt_flags =
2664 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2665 llvm::Value* src = call_inst->getArgOperand(1);
2666 RegLocation rl_src = GetLoc(cu, src);
2667 if (is_enter) {
buzbee02031b12012-11-23 09:41:35 -08002668 cg->GenMonitorEnter(cu, opt_flags->getZExtValue(), rl_src);
buzbee8fa0fda2012-06-27 15:44:52 -07002669 } else {
buzbee02031b12012-11-23 09:41:35 -08002670 cg->GenMonitorExit(cu, opt_flags->getZExtValue(), rl_src);
buzbee8fa0fda2012-06-27 15:44:52 -07002671 }
2672}
2673
buzbeefa57c472012-11-21 12:06:18 -08002674static void CvtArrayLength(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee8fa0fda2012-06-27 15:44:52 -07002675{
buzbee02031b12012-11-23 09:41:35 -08002676 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002677 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2678 llvm::ConstantInt* opt_flags =
2679 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2680 llvm::Value* src = call_inst->getArgOperand(1);
2681 RegLocation rl_src = GetLoc(cu, src);
buzbee02031b12012-11-23 09:41:35 -08002682 rl_src = cg->LoadValue(cu, rl_src, kCoreReg);
2683 cg->GenNullCheck(cu, rl_src.s_reg_low, rl_src.low_reg, opt_flags->getZExtValue());
buzbeefa57c472012-11-21 12:06:18 -08002684 RegLocation rl_dest = GetLoc(cu, call_inst);
2685 RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08002686 int len_offset = mirror::Array::LengthOffset().Int32Value();
buzbee02031b12012-11-23 09:41:35 -08002687 cg->LoadWordDisp(cu, rl_src.low_reg, len_offset, rl_result.low_reg);
2688 cg->StoreValue(cu, rl_dest, rl_result);
buzbee8fa0fda2012-06-27 15:44:52 -07002689}
2690
buzbeefa57c472012-11-21 12:06:18 -08002691static void CvtMoveException(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee32412962012-06-26 16:27:56 -07002692{
buzbee02031b12012-11-23 09:41:35 -08002693 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002694 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002695 cg->GenMoveException(cu, rl_dest);
buzbee32412962012-06-26 16:27:56 -07002696}
2697
buzbeefa57c472012-11-21 12:06:18 -08002698static void CvtSget(CompilationUnit* cu, llvm::CallInst* call_inst, bool is_wide, bool is_object)
buzbee4f1181f2012-06-22 13:52:12 -07002699{
buzbee02031b12012-11-23 09:41:35 -08002700 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002701 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2702 llvm::ConstantInt* type_idx_val =
2703 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2704 uint32_t type_idx = type_idx_val->getZExtValue();
2705 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002706 cg->GenSget(cu, type_idx, rl_dest, is_wide, is_object);
buzbee4f1181f2012-06-22 13:52:12 -07002707}
2708
buzbeefa57c472012-11-21 12:06:18 -08002709static void CvtSput(CompilationUnit* cu, llvm::CallInst* call_inst, bool is_wide, bool is_object)
buzbee8fa0fda2012-06-27 15:44:52 -07002710{
buzbee02031b12012-11-23 09:41:35 -08002711 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002712 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2713 llvm::ConstantInt* type_idx_val =
2714 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2715 uint32_t type_idx = type_idx_val->getZExtValue();
2716 llvm::Value* src = call_inst->getArgOperand(1);
2717 RegLocation rl_src = GetLoc(cu, src);
buzbee02031b12012-11-23 09:41:35 -08002718 cg->GenSput(cu, type_idx, rl_src, is_wide, is_object);
buzbee8fa0fda2012-06-27 15:44:52 -07002719}
2720
buzbeefa57c472012-11-21 12:06:18 -08002721static void CvtAget(CompilationUnit* cu, llvm::CallInst* call_inst, OpSize size, int scale)
buzbee8fa0fda2012-06-27 15:44:52 -07002722{
buzbee02031b12012-11-23 09:41:35 -08002723 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002724 DCHECK_EQ(call_inst->getNumArgOperands(), 3U);
2725 llvm::ConstantInt* opt_flags =
2726 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2727 RegLocation rl_array = GetLoc(cu, call_inst->getArgOperand(1));
2728 RegLocation rl_index = GetLoc(cu, call_inst->getArgOperand(2));
2729 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002730 cg->GenArrayGet(cu, opt_flags->getZExtValue(), size, rl_array, rl_index,
buzbeefa57c472012-11-21 12:06:18 -08002731 rl_dest, scale);
buzbee8fa0fda2012-06-27 15:44:52 -07002732}
2733
buzbeefa57c472012-11-21 12:06:18 -08002734static void CvtAput(CompilationUnit* cu, llvm::CallInst* call_inst, OpSize size,
2735 int scale, bool is_object)
buzbee8fa0fda2012-06-27 15:44:52 -07002736{
buzbee02031b12012-11-23 09:41:35 -08002737 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002738 DCHECK_EQ(call_inst->getNumArgOperands(), 4U);
2739 llvm::ConstantInt* opt_flags =
2740 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2741 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
2742 RegLocation rl_array = GetLoc(cu, call_inst->getArgOperand(2));
2743 RegLocation rl_index = GetLoc(cu, call_inst->getArgOperand(3));
2744 if (is_object) {
buzbee02031b12012-11-23 09:41:35 -08002745 cg->GenArrayObjPut(cu, opt_flags->getZExtValue(), rl_array, rl_index,
buzbeefa57c472012-11-21 12:06:18 -08002746 rl_src, scale);
buzbeef1f86362012-07-10 15:18:31 -07002747 } else {
buzbee02031b12012-11-23 09:41:35 -08002748 cg->GenArrayPut(cu, opt_flags->getZExtValue(), size, rl_array, rl_index,
buzbeefa57c472012-11-21 12:06:18 -08002749 rl_src, scale);
buzbeef1f86362012-07-10 15:18:31 -07002750 }
2751}
2752
buzbeefa57c472012-11-21 12:06:18 -08002753static void CvtAputObj(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbeef1f86362012-07-10 15:18:31 -07002754{
buzbeefa57c472012-11-21 12:06:18 -08002755 CvtAput(cu, call_inst, kWord, 2, true /* is_object */);
buzbeef1f86362012-07-10 15:18:31 -07002756}
2757
buzbeefa57c472012-11-21 12:06:18 -08002758static void CvtAputPrimitive(CompilationUnit* cu, llvm::CallInst* call_inst,
buzbeef1f86362012-07-10 15:18:31 -07002759 OpSize size, int scale)
2760{
buzbeefa57c472012-11-21 12:06:18 -08002761 CvtAput(cu, call_inst, size, scale, false /* is_object */);
buzbee8fa0fda2012-06-27 15:44:52 -07002762}
2763
buzbeefa57c472012-11-21 12:06:18 -08002764static void CvtIget(CompilationUnit* cu, llvm::CallInst* call_inst, OpSize size,
2765 bool is_wide, bool is_obj)
buzbee101305f2012-06-28 18:00:56 -07002766{
buzbee02031b12012-11-23 09:41:35 -08002767 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002768 DCHECK_EQ(call_inst->getNumArgOperands(), 3U);
2769 llvm::ConstantInt* opt_flags =
2770 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2771 RegLocation rl_obj = GetLoc(cu, call_inst->getArgOperand(1));
2772 llvm::ConstantInt* field_idx =
2773 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(2));
2774 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002775 cg->GenIGet(cu, field_idx->getZExtValue(), opt_flags->getZExtValue(),
buzbeefa57c472012-11-21 12:06:18 -08002776 size, rl_dest, rl_obj, is_wide, is_obj);
buzbee101305f2012-06-28 18:00:56 -07002777}
2778
buzbeefa57c472012-11-21 12:06:18 -08002779static void CvtIput(CompilationUnit* cu, llvm::CallInst* call_inst, OpSize size,
2780 bool is_wide, bool is_obj)
buzbee101305f2012-06-28 18:00:56 -07002781{
buzbee02031b12012-11-23 09:41:35 -08002782 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002783 DCHECK_EQ(call_inst->getNumArgOperands(), 4U);
2784 llvm::ConstantInt* opt_flags =
2785 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2786 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
2787 RegLocation rl_obj = GetLoc(cu, call_inst->getArgOperand(2));
2788 llvm::ConstantInt* field_idx =
2789 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(3));
buzbee02031b12012-11-23 09:41:35 -08002790 cg->GenIPut(cu, field_idx->getZExtValue(), opt_flags->getZExtValue(),
buzbeefa57c472012-11-21 12:06:18 -08002791 size, rl_src, rl_obj, is_wide, is_obj);
buzbee101305f2012-06-28 18:00:56 -07002792}
2793
buzbeefa57c472012-11-21 12:06:18 -08002794static void CvtCheckCast(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee101305f2012-06-28 18:00:56 -07002795{
buzbee02031b12012-11-23 09:41:35 -08002796 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002797 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2798 llvm::ConstantInt* type_idx =
2799 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2800 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
buzbee02031b12012-11-23 09:41:35 -08002801 cg->GenCheckCast(cu, type_idx->getZExtValue(), rl_src);
buzbee101305f2012-06-28 18:00:56 -07002802}
2803
buzbeefa57c472012-11-21 12:06:18 -08002804static void CvtFPCompare(CompilationUnit* cu, llvm::CallInst* call_inst,
buzbeeaad94382012-11-21 07:40:50 -08002805 Instruction::Code opcode)
buzbee76592632012-06-29 15:18:35 -07002806{
buzbee02031b12012-11-23 09:41:35 -08002807 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002808 RegLocation rl_src1 = GetLoc(cu, call_inst->getArgOperand(0));
2809 RegLocation rl_src2 = GetLoc(cu, call_inst->getArgOperand(1));
2810 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002811 cg->GenCmpFP(cu, opcode, rl_dest, rl_src1, rl_src2);
buzbee76592632012-06-29 15:18:35 -07002812}
2813
buzbeefa57c472012-11-21 12:06:18 -08002814static void CvtLongCompare(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002815{
buzbee02031b12012-11-23 09:41:35 -08002816 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002817 RegLocation rl_src1 = GetLoc(cu, call_inst->getArgOperand(0));
2818 RegLocation rl_src2 = GetLoc(cu, call_inst->getArgOperand(1));
2819 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002820 cg->GenCmpLong(cu, rl_dest, rl_src1, rl_src2);
buzbee76592632012-06-29 15:18:35 -07002821}
2822
buzbeefa57c472012-11-21 12:06:18 -08002823static void CvtSwitch(CompilationUnit* cu, llvm::Instruction* inst)
buzbeef58c12c2012-07-03 15:06:29 -07002824{
buzbee02031b12012-11-23 09:41:35 -08002825 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002826 llvm::SwitchInst* sw_inst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2827 DCHECK(sw_inst != NULL);
2828 llvm::Value* test_val = sw_inst->getCondition();
2829 llvm::MDNode* table_offset_node = sw_inst->getMetadata("SwitchTable");
2830 DCHECK(table_offset_node != NULL);
2831 llvm::ConstantInt* table_offset_value =
2832 static_cast<llvm::ConstantInt*>(table_offset_node->getOperand(0));
2833 int32_t table_offset = table_offset_value->getSExtValue();
2834 RegLocation rl_src = GetLoc(cu, test_val);
2835 const uint16_t* table = cu->insns + cu->current_dalvik_offset + table_offset;
2836 uint16_t table_magic = *table;
2837 if (table_magic == 0x100) {
buzbee02031b12012-11-23 09:41:35 -08002838 cg->GenPackedSwitch(cu, table_offset, rl_src);
buzbeea1da8a52012-07-09 14:00:21 -07002839 } else {
buzbeefa57c472012-11-21 12:06:18 -08002840 DCHECK_EQ(table_magic, 0x200);
buzbee02031b12012-11-23 09:41:35 -08002841 cg->GenSparseSwitch(cu, table_offset, rl_src);
buzbeea1da8a52012-07-09 14:00:21 -07002842 }
buzbeef58c12c2012-07-03 15:06:29 -07002843}
2844
buzbeefa57c472012-11-21 12:06:18 -08002845static void CvtInvoke(CompilationUnit* cu, llvm::CallInst* call_inst, bool is_void,
2846 bool is_filled_new_array)
buzbee6969d502012-06-15 16:40:31 -07002847{
buzbee02031b12012-11-23 09:41:35 -08002848 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002849 CallInfo* info = static_cast<CallInfo*>(NewMem(cu, sizeof(CallInfo), true, kAllocMisc));
2850 if (is_void) {
buzbee6969d502012-06-15 16:40:31 -07002851 info->result.location = kLocInvalid;
2852 } else {
buzbeefa57c472012-11-21 12:06:18 -08002853 info->result = GetLoc(cu, call_inst);
buzbee6969d502012-06-15 16:40:31 -07002854 }
buzbeefa57c472012-11-21 12:06:18 -08002855 llvm::ConstantInt* invoke_type_val =
2856 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2857 llvm::ConstantInt* method_index_val =
2858 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(1));
2859 llvm::ConstantInt* opt_flags_val =
2860 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(2));
2861 info->type = static_cast<InvokeType>(invoke_type_val->getZExtValue());
2862 info->index = method_index_val->getZExtValue();
2863 info->opt_flags = opt_flags_val->getZExtValue();
2864 info->offset = cu->current_dalvik_offset;
buzbee6969d502012-06-15 16:40:31 -07002865
buzbee6969d502012-06-15 16:40:31 -07002866 // Count the argument words, and then build argument array.
buzbeefa57c472012-11-21 12:06:18 -08002867 info->num_arg_words = 0;
2868 for (unsigned int i = 3; i < call_inst->getNumArgOperands(); i++) {
2869 RegLocation t_loc = GetLoc(cu, call_inst->getArgOperand(i));
2870 info->num_arg_words += t_loc.wide ? 2 : 1;
buzbee6969d502012-06-15 16:40:31 -07002871 }
buzbeefa57c472012-11-21 12:06:18 -08002872 info->args = (info->num_arg_words == 0) ? NULL : static_cast<RegLocation*>
2873 (NewMem(cu, sizeof(RegLocation) * info->num_arg_words, false, kAllocMisc));
buzbee6969d502012-06-15 16:40:31 -07002874 // Now, fill in the location records, synthesizing high loc of wide vals
buzbeefa57c472012-11-21 12:06:18 -08002875 for (int i = 3, next = 0; next < info->num_arg_words;) {
2876 info->args[next] = GetLoc(cu, call_inst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002877 if (info->args[next].wide) {
2878 next++;
2879 // TODO: Might make sense to mark this as an invalid loc
buzbeefa57c472012-11-21 12:06:18 -08002880 info->args[next].orig_sreg = info->args[next-1].orig_sreg+1;
2881 info->args[next].s_reg_low = info->args[next-1].s_reg_low+1;
buzbee6969d502012-06-15 16:40:31 -07002882 }
2883 next++;
2884 }
buzbeefa57c472012-11-21 12:06:18 -08002885 // TODO - rework such that we no longer need is_range
2886 info->is_range = (info->num_arg_words > 5);
buzbee4f4dfc72012-07-02 14:54:44 -07002887
buzbeefa57c472012-11-21 12:06:18 -08002888 if (is_filled_new_array) {
buzbee02031b12012-11-23 09:41:35 -08002889 cg->GenFilledNewArray(cu, info);
buzbee101305f2012-06-28 18:00:56 -07002890 } else {
buzbee02031b12012-11-23 09:41:35 -08002891 cg->GenInvoke(cu, info);
buzbee101305f2012-06-28 18:00:56 -07002892 }
buzbee6969d502012-06-15 16:40:31 -07002893}
2894
buzbeead8f15e2012-06-18 14:49:45 -07002895/* Look up the RegLocation associated with a Value. Must already be defined */
buzbeefa57c472012-11-21 12:06:18 -08002896static RegLocation ValToLoc(CompilationUnit* cu, llvm::Value* val)
buzbeead8f15e2012-06-18 14:49:45 -07002897{
buzbeefa57c472012-11-21 12:06:18 -08002898 SafeMap<llvm::Value*, RegLocation>::iterator it = cu->loc_map.find(val);
2899 DCHECK(it != cu->loc_map.end()) << "Missing definition";
buzbeead8f15e2012-06-18 14:49:45 -07002900 return it->second;
2901}
2902
buzbeefa57c472012-11-21 12:06:18 -08002903static bool BitcodeBlockCodeGen(CompilationUnit* cu, llvm::BasicBlock* bb)
buzbee2cfc6392012-05-07 14:51:40 -07002904{
buzbee02031b12012-11-23 09:41:35 -08002905 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002906 while (cu->llvm_blocks.find(bb) == cu->llvm_blocks.end()) {
2907 llvm::BasicBlock* next_bb = NULL;
2908 cu->llvm_blocks.insert(bb);
2909 bool is_entry = (bb == &cu->func->getEntryBlock());
buzbee0967a252012-09-14 10:43:54 -07002910 // Define the starting label
buzbeefa57c472012-11-21 12:06:18 -08002911 LIR* block_label = cu->block_to_label_map.Get(bb);
buzbee0967a252012-09-14 10:43:54 -07002912 // Extract the type and starting offset from the block's name
buzbeefa57c472012-11-21 12:06:18 -08002913 char block_type = kInvalidBlock;
2914 if (is_entry) {
2915 block_type = kNormalBlock;
2916 block_label->operands[0] = 0;
buzbee951c0a12012-10-03 16:31:39 -07002917 } else if (!bb->hasName()) {
buzbeefa57c472012-11-21 12:06:18 -08002918 block_type = kNormalBlock;
2919 block_label->operands[0] = DexFile::kDexNoIndex;
buzbee0967a252012-09-14 10:43:54 -07002920 } else {
buzbeefa57c472012-11-21 12:06:18 -08002921 std::string block_name = bb->getName().str();
buzbee951c0a12012-10-03 16:31:39 -07002922 int dummy;
buzbeefa57c472012-11-21 12:06:18 -08002923 sscanf(block_name.c_str(), kLabelFormat, &block_type, &block_label->operands[0], &dummy);
2924 cu->current_dalvik_offset = block_label->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002925 }
buzbeefa57c472012-11-21 12:06:18 -08002926 DCHECK((block_type == kNormalBlock) || (block_type == kCatchBlock));
2927 cu->current_dalvik_offset = block_label->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002928 // Set the label kind
buzbeefa57c472012-11-21 12:06:18 -08002929 block_label->opcode = kPseudoNormalBlockLabel;
buzbee0967a252012-09-14 10:43:54 -07002930 // Insert the label
buzbeefa57c472012-11-21 12:06:18 -08002931 AppendLIR(cu, block_label);
buzbee2cfc6392012-05-07 14:51:40 -07002932
buzbeefa57c472012-11-21 12:06:18 -08002933 LIR* head_lir = NULL;
buzbee8320f382012-09-11 16:29:42 -07002934
buzbeefa57c472012-11-21 12:06:18 -08002935 if (block_type == kCatchBlock) {
2936 head_lir = NewLIR0(cu, kPseudoExportedPC);
buzbee0967a252012-09-14 10:43:54 -07002937 }
buzbee8320f382012-09-11 16:29:42 -07002938
buzbee0967a252012-09-14 10:43:54 -07002939 // Free temp registers and reset redundant store tracking */
buzbeefa57c472012-11-21 12:06:18 -08002940 ResetRegPool(cu);
2941 ResetDefTracking(cu);
buzbee2cfc6392012-05-07 14:51:40 -07002942
buzbee0967a252012-09-14 10:43:54 -07002943 //TODO: restore oat incoming liveness optimization
buzbeefa57c472012-11-21 12:06:18 -08002944 ClobberAllRegs(cu);
buzbee2cfc6392012-05-07 14:51:40 -07002945
buzbeefa57c472012-11-21 12:06:18 -08002946 if (is_entry) {
buzbee52a77fc2012-11-20 19:50:46 -08002947 RegLocation* ArgLocs = static_cast<RegLocation*>
buzbeefa57c472012-11-21 12:06:18 -08002948 (NewMem(cu, sizeof(RegLocation) * cu->num_ins, true, kAllocMisc));
2949 llvm::Function::arg_iterator it(cu->func->arg_begin());
2950 llvm::Function::arg_iterator it_end(cu->func->arg_end());
buzbee0967a252012-09-14 10:43:54 -07002951 // Skip past Method*
2952 it++;
2953 for (unsigned i = 0; it != it_end; ++it) {
2954 llvm::Value* val = it;
buzbeefa57c472012-11-21 12:06:18 -08002955 ArgLocs[i++] = ValToLoc(cu, val);
buzbee0967a252012-09-14 10:43:54 -07002956 llvm::Type* ty = val->getType();
buzbeefa57c472012-11-21 12:06:18 -08002957 if ((ty == cu->irb->getInt64Ty()) || (ty == cu->irb->getDoubleTy())) {
buzbee52a77fc2012-11-20 19:50:46 -08002958 ArgLocs[i] = ArgLocs[i-1];
buzbeefa57c472012-11-21 12:06:18 -08002959 ArgLocs[i].low_reg = ArgLocs[i].high_reg;
2960 ArgLocs[i].orig_sreg++;
2961 ArgLocs[i].s_reg_low = INVALID_SREG;
2962 ArgLocs[i].high_word = true;
buzbee0967a252012-09-14 10:43:54 -07002963 i++;
2964 }
2965 }
buzbee02031b12012-11-23 09:41:35 -08002966 cg->GenEntrySequence(cu, ArgLocs, cu->method_loc);
buzbee0967a252012-09-14 10:43:54 -07002967 }
2968
2969 // Visit all of the instructions in the block
2970 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2971 llvm::Instruction* inst = it;
buzbeefa57c472012-11-21 12:06:18 -08002972 llvm::BasicBlock::iterator next_it = ++it;
buzbee0967a252012-09-14 10:43:54 -07002973 // Extract the Dalvik offset from the instruction
2974 uint32_t opcode = inst->getOpcode();
buzbeefa57c472012-11-21 12:06:18 -08002975 llvm::MDNode* dex_offset_node = inst->getMetadata("DexOff");
2976 if (dex_offset_node != NULL) {
2977 llvm::ConstantInt* dex_offset_value =
2978 static_cast<llvm::ConstantInt*>(dex_offset_node->getOperand(0));
2979 cu->current_dalvik_offset = dex_offset_value->getZExtValue();
buzbee0967a252012-09-14 10:43:54 -07002980 }
2981
buzbeefa57c472012-11-21 12:06:18 -08002982 ResetRegPool(cu);
2983 if (cu->disable_opt & (1 << kTrackLiveTemps)) {
2984 ClobberAllRegs(cu);
buzbee0967a252012-09-14 10:43:54 -07002985 }
2986
buzbeefa57c472012-11-21 12:06:18 -08002987 if (cu->disable_opt & (1 << kSuppressLoads)) {
2988 ResetDefTracking(cu);
buzbee0967a252012-09-14 10:43:54 -07002989 }
2990
2991 #ifndef NDEBUG
2992 /* Reset temp tracking sanity check */
buzbeefa57c472012-11-21 12:06:18 -08002993 cu->live_sreg = INVALID_SREG;
buzbee0967a252012-09-14 10:43:54 -07002994 #endif
2995
2996 // TODO: use llvm opcode name here instead of "boundary" if verbose
buzbeefa57c472012-11-21 12:06:18 -08002997 LIR* boundary_lir = MarkBoundary(cu, cu->current_dalvik_offset, "boundary");
buzbee0967a252012-09-14 10:43:54 -07002998
2999 /* Remember the first LIR for thisl block*/
buzbeefa57c472012-11-21 12:06:18 -08003000 if (head_lir == NULL) {
3001 head_lir = boundary_lir;
3002 head_lir->def_mask = ENCODE_ALL;
buzbee0967a252012-09-14 10:43:54 -07003003 }
3004
3005 switch(opcode) {
3006
3007 case llvm::Instruction::ICmp: {
buzbeefa57c472012-11-21 12:06:18 -08003008 llvm::Instruction* next_inst = next_it;
3009 llvm::BranchInst* br_inst = llvm::dyn_cast<llvm::BranchInst>(next_inst);
3010 if (br_inst != NULL /* and... */) {
3011 CvtICmpBr(cu, inst, br_inst);
buzbee0967a252012-09-14 10:43:54 -07003012 ++it;
3013 } else {
buzbeefa57c472012-11-21 12:06:18 -08003014 CvtICmp(cu, inst);
buzbee0967a252012-09-14 10:43:54 -07003015 }
3016 }
3017 break;
3018
3019 case llvm::Instruction::Call: {
buzbeefa57c472012-11-21 12:06:18 -08003020 llvm::CallInst* call_inst = llvm::dyn_cast<llvm::CallInst>(inst);
3021 llvm::Function* callee = call_inst->getCalledFunction();
buzbee0967a252012-09-14 10:43:54 -07003022 greenland::IntrinsicHelper::IntrinsicId id =
buzbeefa57c472012-11-21 12:06:18 -08003023 cu->intrinsic_helper->GetIntrinsicId(callee);
buzbee0967a252012-09-14 10:43:54 -07003024 switch (id) {
3025 case greenland::IntrinsicHelper::AllocaShadowFrame:
buzbee0967a252012-09-14 10:43:54 -07003026 case greenland::IntrinsicHelper::PopShadowFrame:
TDYa1278e950c12012-11-02 09:58:19 -07003027 case greenland::IntrinsicHelper::SetVReg:
buzbee0967a252012-09-14 10:43:54 -07003028 // Ignore shadow frame stuff for quick compiler
3029 break;
3030 case greenland::IntrinsicHelper::CopyInt:
3031 case greenland::IntrinsicHelper::CopyObj:
3032 case greenland::IntrinsicHelper::CopyFloat:
3033 case greenland::IntrinsicHelper::CopyLong:
3034 case greenland::IntrinsicHelper::CopyDouble:
buzbeefa57c472012-11-21 12:06:18 -08003035 CvtCopy(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003036 break;
3037 case greenland::IntrinsicHelper::ConstInt:
3038 case greenland::IntrinsicHelper::ConstObj:
3039 case greenland::IntrinsicHelper::ConstLong:
3040 case greenland::IntrinsicHelper::ConstFloat:
3041 case greenland::IntrinsicHelper::ConstDouble:
buzbeefa57c472012-11-21 12:06:18 -08003042 CvtConst(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003043 break;
3044 case greenland::IntrinsicHelper::DivInt:
3045 case greenland::IntrinsicHelper::DivLong:
buzbeefa57c472012-11-21 12:06:18 -08003046 CvtBinOp(cu, kOpDiv, inst);
buzbee0967a252012-09-14 10:43:54 -07003047 break;
3048 case greenland::IntrinsicHelper::RemInt:
3049 case greenland::IntrinsicHelper::RemLong:
buzbeefa57c472012-11-21 12:06:18 -08003050 CvtBinOp(cu, kOpRem, inst);
buzbee0967a252012-09-14 10:43:54 -07003051 break;
3052 case greenland::IntrinsicHelper::MethodInfo:
3053 // Already dealt with - just ignore it here.
3054 break;
3055 case greenland::IntrinsicHelper::CheckSuspend:
buzbee02031b12012-11-23 09:41:35 -08003056 cg->GenSuspendTest(cu, 0 /* opt_flags already applied */);
buzbee0967a252012-09-14 10:43:54 -07003057 break;
3058 case greenland::IntrinsicHelper::HLInvokeObj:
3059 case greenland::IntrinsicHelper::HLInvokeFloat:
3060 case greenland::IntrinsicHelper::HLInvokeDouble:
3061 case greenland::IntrinsicHelper::HLInvokeLong:
3062 case greenland::IntrinsicHelper::HLInvokeInt:
buzbeefa57c472012-11-21 12:06:18 -08003063 CvtInvoke(cu, call_inst, false /* is_void */, false /* new_array */);
buzbee0967a252012-09-14 10:43:54 -07003064 break;
3065 case greenland::IntrinsicHelper::HLInvokeVoid:
buzbeefa57c472012-11-21 12:06:18 -08003066 CvtInvoke(cu, call_inst, true /* is_void */, false /* new_array */);
buzbee0967a252012-09-14 10:43:54 -07003067 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003068 case greenland::IntrinsicHelper::HLFilledNewArray:
buzbeefa57c472012-11-21 12:06:18 -08003069 CvtInvoke(cu, call_inst, false /* is_void */, true /* new_array */);
buzbee0967a252012-09-14 10:43:54 -07003070 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003071 case greenland::IntrinsicHelper::HLFillArrayData:
buzbeefa57c472012-11-21 12:06:18 -08003072 CvtFillArrayData(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003073 break;
3074 case greenland::IntrinsicHelper::ConstString:
buzbeefa57c472012-11-21 12:06:18 -08003075 CvtConstObject(cu, call_inst, true /* is_string */);
buzbee0967a252012-09-14 10:43:54 -07003076 break;
3077 case greenland::IntrinsicHelper::ConstClass:
buzbeefa57c472012-11-21 12:06:18 -08003078 CvtConstObject(cu, call_inst, false /* is_string */);
buzbee0967a252012-09-14 10:43:54 -07003079 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003080 case greenland::IntrinsicHelper::HLCheckCast:
buzbeefa57c472012-11-21 12:06:18 -08003081 CvtCheckCast(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003082 break;
3083 case greenland::IntrinsicHelper::NewInstance:
buzbeefa57c472012-11-21 12:06:18 -08003084 CvtNewInstance(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003085 break;
3086 case greenland::IntrinsicHelper::HLSgetObject:
buzbeefa57c472012-11-21 12:06:18 -08003087 CvtSget(cu, call_inst, false /* wide */, true /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003088 break;
3089 case greenland::IntrinsicHelper::HLSget:
3090 case greenland::IntrinsicHelper::HLSgetFloat:
3091 case greenland::IntrinsicHelper::HLSgetBoolean:
3092 case greenland::IntrinsicHelper::HLSgetByte:
3093 case greenland::IntrinsicHelper::HLSgetChar:
3094 case greenland::IntrinsicHelper::HLSgetShort:
buzbeefa57c472012-11-21 12:06:18 -08003095 CvtSget(cu, call_inst, false /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003096 break;
3097 case greenland::IntrinsicHelper::HLSgetWide:
3098 case greenland::IntrinsicHelper::HLSgetDouble:
buzbeefa57c472012-11-21 12:06:18 -08003099 CvtSget(cu, call_inst, true /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003100 break;
3101 case greenland::IntrinsicHelper::HLSput:
3102 case greenland::IntrinsicHelper::HLSputFloat:
3103 case greenland::IntrinsicHelper::HLSputBoolean:
3104 case greenland::IntrinsicHelper::HLSputByte:
3105 case greenland::IntrinsicHelper::HLSputChar:
3106 case greenland::IntrinsicHelper::HLSputShort:
buzbeefa57c472012-11-21 12:06:18 -08003107 CvtSput(cu, call_inst, false /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003108 break;
3109 case greenland::IntrinsicHelper::HLSputWide:
3110 case greenland::IntrinsicHelper::HLSputDouble:
buzbeefa57c472012-11-21 12:06:18 -08003111 CvtSput(cu, call_inst, true /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003112 break;
3113 case greenland::IntrinsicHelper::HLSputObject:
buzbeefa57c472012-11-21 12:06:18 -08003114 CvtSput(cu, call_inst, false /* wide */, true /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003115 break;
3116 case greenland::IntrinsicHelper::GetException:
buzbeefa57c472012-11-21 12:06:18 -08003117 CvtMoveException(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003118 break;
TDYa127f71bf5a2012-07-29 20:09:52 -07003119 case greenland::IntrinsicHelper::HLThrowException:
buzbeefa57c472012-11-21 12:06:18 -08003120 CvtThrow(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003121 break;
3122 case greenland::IntrinsicHelper::MonitorEnter:
buzbeefa57c472012-11-21 12:06:18 -08003123 CvtMonitorEnterExit(cu, true /* is_enter */, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003124 break;
3125 case greenland::IntrinsicHelper::MonitorExit:
buzbeefa57c472012-11-21 12:06:18 -08003126 CvtMonitorEnterExit(cu, false /* is_enter */, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003127 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003128 case greenland::IntrinsicHelper::OptArrayLength:
buzbeefa57c472012-11-21 12:06:18 -08003129 CvtArrayLength(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003130 break;
3131 case greenland::IntrinsicHelper::NewArray:
buzbeefa57c472012-11-21 12:06:18 -08003132 CvtNewArray(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003133 break;
3134 case greenland::IntrinsicHelper::InstanceOf:
buzbeefa57c472012-11-21 12:06:18 -08003135 CvtInstanceOf(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003136 break;
3137
3138 case greenland::IntrinsicHelper::HLArrayGet:
3139 case greenland::IntrinsicHelper::HLArrayGetObject:
3140 case greenland::IntrinsicHelper::HLArrayGetFloat:
buzbeefa57c472012-11-21 12:06:18 -08003141 CvtAget(cu, call_inst, kWord, 2);
buzbee0967a252012-09-14 10:43:54 -07003142 break;
3143 case greenland::IntrinsicHelper::HLArrayGetWide:
3144 case greenland::IntrinsicHelper::HLArrayGetDouble:
buzbeefa57c472012-11-21 12:06:18 -08003145 CvtAget(cu, call_inst, kLong, 3);
buzbee0967a252012-09-14 10:43:54 -07003146 break;
3147 case greenland::IntrinsicHelper::HLArrayGetBoolean:
buzbeefa57c472012-11-21 12:06:18 -08003148 CvtAget(cu, call_inst, kUnsignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003149 break;
3150 case greenland::IntrinsicHelper::HLArrayGetByte:
buzbeefa57c472012-11-21 12:06:18 -08003151 CvtAget(cu, call_inst, kSignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003152 break;
3153 case greenland::IntrinsicHelper::HLArrayGetChar:
buzbeefa57c472012-11-21 12:06:18 -08003154 CvtAget(cu, call_inst, kUnsignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003155 break;
3156 case greenland::IntrinsicHelper::HLArrayGetShort:
buzbeefa57c472012-11-21 12:06:18 -08003157 CvtAget(cu, call_inst, kSignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003158 break;
3159
3160 case greenland::IntrinsicHelper::HLArrayPut:
3161 case greenland::IntrinsicHelper::HLArrayPutFloat:
buzbeefa57c472012-11-21 12:06:18 -08003162 CvtAputPrimitive(cu, call_inst, kWord, 2);
buzbee0967a252012-09-14 10:43:54 -07003163 break;
3164 case greenland::IntrinsicHelper::HLArrayPutObject:
buzbeefa57c472012-11-21 12:06:18 -08003165 CvtAputObj(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003166 break;
3167 case greenland::IntrinsicHelper::HLArrayPutWide:
3168 case greenland::IntrinsicHelper::HLArrayPutDouble:
buzbeefa57c472012-11-21 12:06:18 -08003169 CvtAputPrimitive(cu, call_inst, kLong, 3);
buzbee0967a252012-09-14 10:43:54 -07003170 break;
3171 case greenland::IntrinsicHelper::HLArrayPutBoolean:
buzbeefa57c472012-11-21 12:06:18 -08003172 CvtAputPrimitive(cu, call_inst, kUnsignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003173 break;
3174 case greenland::IntrinsicHelper::HLArrayPutByte:
buzbeefa57c472012-11-21 12:06:18 -08003175 CvtAputPrimitive(cu, call_inst, kSignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003176 break;
3177 case greenland::IntrinsicHelper::HLArrayPutChar:
buzbeefa57c472012-11-21 12:06:18 -08003178 CvtAputPrimitive(cu, call_inst, kUnsignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003179 break;
3180 case greenland::IntrinsicHelper::HLArrayPutShort:
buzbeefa57c472012-11-21 12:06:18 -08003181 CvtAputPrimitive(cu, call_inst, kSignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003182 break;
3183
3184 case greenland::IntrinsicHelper::HLIGet:
3185 case greenland::IntrinsicHelper::HLIGetFloat:
buzbeefa57c472012-11-21 12:06:18 -08003186 CvtIget(cu, call_inst, kWord, false /* is_wide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003187 break;
3188 case greenland::IntrinsicHelper::HLIGetObject:
buzbeefa57c472012-11-21 12:06:18 -08003189 CvtIget(cu, call_inst, kWord, false /* is_wide */, true /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003190 break;
3191 case greenland::IntrinsicHelper::HLIGetWide:
3192 case greenland::IntrinsicHelper::HLIGetDouble:
buzbeefa57c472012-11-21 12:06:18 -08003193 CvtIget(cu, call_inst, kLong, true /* is_wide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003194 break;
3195 case greenland::IntrinsicHelper::HLIGetBoolean:
buzbeefa57c472012-11-21 12:06:18 -08003196 CvtIget(cu, call_inst, kUnsignedByte, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003197 false /* obj */);
3198 break;
3199 case greenland::IntrinsicHelper::HLIGetByte:
buzbeefa57c472012-11-21 12:06:18 -08003200 CvtIget(cu, call_inst, kSignedByte, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003201 false /* obj */);
3202 break;
3203 case greenland::IntrinsicHelper::HLIGetChar:
buzbeefa57c472012-11-21 12:06:18 -08003204 CvtIget(cu, call_inst, kUnsignedHalf, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003205 false /* obj */);
3206 break;
3207 case greenland::IntrinsicHelper::HLIGetShort:
buzbeefa57c472012-11-21 12:06:18 -08003208 CvtIget(cu, call_inst, kSignedHalf, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003209 false /* obj */);
3210 break;
3211
3212 case greenland::IntrinsicHelper::HLIPut:
3213 case greenland::IntrinsicHelper::HLIPutFloat:
buzbeefa57c472012-11-21 12:06:18 -08003214 CvtIput(cu, call_inst, kWord, false /* is_wide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003215 break;
3216 case greenland::IntrinsicHelper::HLIPutObject:
buzbeefa57c472012-11-21 12:06:18 -08003217 CvtIput(cu, call_inst, kWord, false /* is_wide */, true /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003218 break;
3219 case greenland::IntrinsicHelper::HLIPutWide:
3220 case greenland::IntrinsicHelper::HLIPutDouble:
buzbeefa57c472012-11-21 12:06:18 -08003221 CvtIput(cu, call_inst, kLong, true /* is_wide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003222 break;
3223 case greenland::IntrinsicHelper::HLIPutBoolean:
buzbeefa57c472012-11-21 12:06:18 -08003224 CvtIput(cu, call_inst, kUnsignedByte, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003225 false /* obj */);
3226 break;
3227 case greenland::IntrinsicHelper::HLIPutByte:
buzbeefa57c472012-11-21 12:06:18 -08003228 CvtIput(cu, call_inst, kSignedByte, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003229 false /* obj */);
3230 break;
3231 case greenland::IntrinsicHelper::HLIPutChar:
buzbeefa57c472012-11-21 12:06:18 -08003232 CvtIput(cu, call_inst, kUnsignedHalf, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003233 false /* obj */);
3234 break;
3235 case greenland::IntrinsicHelper::HLIPutShort:
buzbeefa57c472012-11-21 12:06:18 -08003236 CvtIput(cu, call_inst, kSignedHalf, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003237 false /* obj */);
3238 break;
3239
3240 case greenland::IntrinsicHelper::IntToChar:
buzbeefa57c472012-11-21 12:06:18 -08003241 CvtIntNarrowing(cu, call_inst, Instruction::INT_TO_CHAR);
buzbee0967a252012-09-14 10:43:54 -07003242 break;
3243 case greenland::IntrinsicHelper::IntToShort:
buzbeefa57c472012-11-21 12:06:18 -08003244 CvtIntNarrowing(cu, call_inst, Instruction::INT_TO_SHORT);
buzbee0967a252012-09-14 10:43:54 -07003245 break;
3246 case greenland::IntrinsicHelper::IntToByte:
buzbeefa57c472012-11-21 12:06:18 -08003247 CvtIntNarrowing(cu, call_inst, Instruction::INT_TO_BYTE);
buzbee0967a252012-09-14 10:43:54 -07003248 break;
3249
TDYa1274ec8ccd2012-08-11 07:04:57 -07003250 case greenland::IntrinsicHelper::F2I:
3251 case greenland::IntrinsicHelper::D2I:
3252 case greenland::IntrinsicHelper::F2L:
3253 case greenland::IntrinsicHelper::D2L:
buzbeefa57c472012-11-21 12:06:18 -08003254 CvtFPToInt(cu, call_inst);
TDYa1274ec8ccd2012-08-11 07:04:57 -07003255 break;
3256
buzbee0967a252012-09-14 10:43:54 -07003257 case greenland::IntrinsicHelper::CmplFloat:
buzbeefa57c472012-11-21 12:06:18 -08003258 CvtFPCompare(cu, call_inst, Instruction::CMPL_FLOAT);
buzbee0967a252012-09-14 10:43:54 -07003259 break;
3260 case greenland::IntrinsicHelper::CmpgFloat:
buzbeefa57c472012-11-21 12:06:18 -08003261 CvtFPCompare(cu, call_inst, Instruction::CMPG_FLOAT);
buzbee0967a252012-09-14 10:43:54 -07003262 break;
3263 case greenland::IntrinsicHelper::CmplDouble:
buzbeefa57c472012-11-21 12:06:18 -08003264 CvtFPCompare(cu, call_inst, Instruction::CMPL_DOUBLE);
buzbee0967a252012-09-14 10:43:54 -07003265 break;
3266 case greenland::IntrinsicHelper::CmpgDouble:
buzbeefa57c472012-11-21 12:06:18 -08003267 CvtFPCompare(cu, call_inst, Instruction::CMPG_DOUBLE);
buzbee0967a252012-09-14 10:43:54 -07003268 break;
3269
3270 case greenland::IntrinsicHelper::CmpLong:
buzbeefa57c472012-11-21 12:06:18 -08003271 CvtLongCompare(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003272 break;
3273
3274 case greenland::IntrinsicHelper::SHLLong:
buzbeefa57c472012-11-21 12:06:18 -08003275 CvtShiftOp(cu, Instruction::SHL_LONG, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003276 break;
3277 case greenland::IntrinsicHelper::SHRLong:
buzbeefa57c472012-11-21 12:06:18 -08003278 CvtShiftOp(cu, Instruction::SHR_LONG, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003279 break;
3280 case greenland::IntrinsicHelper::USHRLong:
buzbeefa57c472012-11-21 12:06:18 -08003281 CvtShiftOp(cu, Instruction::USHR_LONG, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003282 break;
3283 case greenland::IntrinsicHelper::SHLInt:
buzbeefa57c472012-11-21 12:06:18 -08003284 CvtShiftOp(cu, Instruction::SHL_INT, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003285 break;
3286 case greenland::IntrinsicHelper::SHRInt:
buzbeefa57c472012-11-21 12:06:18 -08003287 CvtShiftOp(cu, Instruction::SHR_INT, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003288 break;
3289 case greenland::IntrinsicHelper::USHRInt:
buzbeefa57c472012-11-21 12:06:18 -08003290 CvtShiftOp(cu, Instruction::USHR_INT, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003291 break;
3292
3293 case greenland::IntrinsicHelper::CatchTargets: {
buzbeefa57c472012-11-21 12:06:18 -08003294 llvm::SwitchInst* sw_inst =
3295 llvm::dyn_cast<llvm::SwitchInst>(next_it);
3296 DCHECK(sw_inst != NULL);
buzbee0967a252012-09-14 10:43:54 -07003297 /*
3298 * Discard the edges and the following conditional branch.
3299 * Do a direct branch to the default target (which is the
3300 * "work" portion of the pair.
3301 * TODO: awful code layout - rework
3302 */
buzbeefa57c472012-11-21 12:06:18 -08003303 llvm::BasicBlock* target_bb = sw_inst->getDefaultDest();
3304 DCHECK(target_bb != NULL);
buzbee02031b12012-11-23 09:41:35 -08003305 cg->OpUnconditionalBranch(cu, cu->block_to_label_map.Get(target_bb));
buzbee0967a252012-09-14 10:43:54 -07003306 ++it;
3307 // Set next bb to default target - improves code layout
buzbeefa57c472012-11-21 12:06:18 -08003308 next_bb = target_bb;
buzbee0967a252012-09-14 10:43:54 -07003309 }
3310 break;
3311
3312 default:
buzbeefa57c472012-11-21 12:06:18 -08003313 LOG(FATAL) << "Unexpected intrinsic " << cu->intrinsic_helper->GetName(id);
buzbee0967a252012-09-14 10:43:54 -07003314 }
3315 }
3316 break;
3317
buzbeefa57c472012-11-21 12:06:18 -08003318 case llvm::Instruction::Br: CvtBr(cu, inst); break;
3319 case llvm::Instruction::Add: CvtBinOp(cu, kOpAdd, inst); break;
3320 case llvm::Instruction::Sub: CvtBinOp(cu, kOpSub, inst); break;
3321 case llvm::Instruction::Mul: CvtBinOp(cu, kOpMul, inst); break;
3322 case llvm::Instruction::SDiv: CvtBinOp(cu, kOpDiv, inst); break;
3323 case llvm::Instruction::SRem: CvtBinOp(cu, kOpRem, inst); break;
3324 case llvm::Instruction::And: CvtBinOp(cu, kOpAnd, inst); break;
3325 case llvm::Instruction::Or: CvtBinOp(cu, kOpOr, inst); break;
3326 case llvm::Instruction::Xor: CvtBinOp(cu, kOpXor, inst); break;
3327 case llvm::Instruction::PHI: CvtPhi(cu, inst); break;
3328 case llvm::Instruction::Ret: CvtRet(cu, inst); break;
3329 case llvm::Instruction::FAdd: CvtBinFPOp(cu, kOpAdd, inst); break;
3330 case llvm::Instruction::FSub: CvtBinFPOp(cu, kOpSub, inst); break;
3331 case llvm::Instruction::FMul: CvtBinFPOp(cu, kOpMul, inst); break;
3332 case llvm::Instruction::FDiv: CvtBinFPOp(cu, kOpDiv, inst); break;
3333 case llvm::Instruction::FRem: CvtBinFPOp(cu, kOpRem, inst); break;
3334 case llvm::Instruction::SIToFP: CvtIntToFP(cu, inst); break;
3335 case llvm::Instruction::FPTrunc: CvtDoubleToFloat(cu, inst); break;
3336 case llvm::Instruction::FPExt: CvtFloatToDouble(cu, inst); break;
3337 case llvm::Instruction::Trunc: CvtTrunc(cu, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003338
buzbeefa57c472012-11-21 12:06:18 -08003339 case llvm::Instruction::ZExt: CvtIntExt(cu, inst, false /* signed */);
buzbee0967a252012-09-14 10:43:54 -07003340 break;
buzbeefa57c472012-11-21 12:06:18 -08003341 case llvm::Instruction::SExt: CvtIntExt(cu, inst, true /* signed */);
buzbee0967a252012-09-14 10:43:54 -07003342 break;
3343
buzbeefa57c472012-11-21 12:06:18 -08003344 case llvm::Instruction::Switch: CvtSwitch(cu, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003345
3346 case llvm::Instruction::Unreachable:
3347 break; // FIXME: can we really ignore these?
3348
3349 case llvm::Instruction::Shl:
3350 case llvm::Instruction::LShr:
3351 case llvm::Instruction::AShr:
3352 case llvm::Instruction::Invoke:
3353 case llvm::Instruction::FPToUI:
TDYa1274ec8ccd2012-08-11 07:04:57 -07003354 case llvm::Instruction::FPToSI:
buzbee0967a252012-09-14 10:43:54 -07003355 case llvm::Instruction::UIToFP:
3356 case llvm::Instruction::PtrToInt:
3357 case llvm::Instruction::IntToPtr:
3358 case llvm::Instruction::FCmp:
3359 case llvm::Instruction::URem:
3360 case llvm::Instruction::UDiv:
3361 case llvm::Instruction::Resume:
3362 case llvm::Instruction::Alloca:
3363 case llvm::Instruction::GetElementPtr:
3364 case llvm::Instruction::Fence:
3365 case llvm::Instruction::AtomicCmpXchg:
3366 case llvm::Instruction::AtomicRMW:
3367 case llvm::Instruction::BitCast:
3368 case llvm::Instruction::VAArg:
3369 case llvm::Instruction::Select:
3370 case llvm::Instruction::UserOp1:
3371 case llvm::Instruction::UserOp2:
3372 case llvm::Instruction::ExtractElement:
3373 case llvm::Instruction::InsertElement:
3374 case llvm::Instruction::ShuffleVector:
3375 case llvm::Instruction::ExtractValue:
3376 case llvm::Instruction::InsertValue:
3377 case llvm::Instruction::LandingPad:
3378 case llvm::Instruction::IndirectBr:
3379 case llvm::Instruction::Load:
3380 case llvm::Instruction::Store:
3381 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3382
3383 default:
3384 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3385 break;
buzbeead8f15e2012-06-18 14:49:45 -07003386 }
3387 }
buzbee2cfc6392012-05-07 14:51:40 -07003388
buzbeefa57c472012-11-21 12:06:18 -08003389 if (head_lir != NULL) {
3390 ApplyLocalOptimizations(cu, head_lir, cu->last_lir_insn);
buzbee2cfc6392012-05-07 14:51:40 -07003391 }
buzbeefa57c472012-11-21 12:06:18 -08003392 if (next_bb != NULL) {
3393 bb = next_bb;
3394 next_bb = NULL;
buzbee6969d502012-06-15 16:40:31 -07003395 }
buzbee6969d502012-06-15 16:40:31 -07003396 }
buzbee2cfc6392012-05-07 14:51:40 -07003397 return false;
3398}
3399
3400/*
3401 * Convert LLVM_IR to MIR:
3402 * o Iterate through the LLVM_IR and construct a graph using
3403 * standard MIR building blocks.
3404 * o Perform a basic-block optimization pass to remove unnecessary
3405 * store/load sequences.
3406 * o Convert the LLVM Value operands into RegLocations where applicable.
buzbeefa57c472012-11-21 12:06:18 -08003407 * o Create ssa_rep def/use operand arrays for each converted LLVM opcode
buzbee2cfc6392012-05-07 14:51:40 -07003408 * o Perform register promotion
3409 * o Iterate through the graph a basic block at a time, generating
3410 * LIR.
3411 * o Assemble LIR as usual.
3412 * o Profit.
3413 */
buzbeefa57c472012-11-21 12:06:18 -08003414void MethodBitcode2LIR(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -07003415{
buzbee02031b12012-11-23 09:41:35 -08003416 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08003417 llvm::Function* func = cu->func;
3418 int num_basic_blocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003419 // Allocate a list for LIR basic block labels
buzbeefa57c472012-11-21 12:06:18 -08003420 cu->block_label_list =
3421 static_cast<LIR*>(NewMem(cu, sizeof(LIR) * num_basic_blocks, true, kAllocLIR));
3422 LIR* label_list = cu->block_label_list;
3423 int next_label = 0;
buzbee28c9a832012-11-21 15:39:13 -08003424 for (llvm::Function::iterator i = func->begin(), e = func->end(); i != e; ++i) {
buzbeefa57c472012-11-21 12:06:18 -08003425 cu->block_to_label_map.Put(static_cast<llvm::BasicBlock*>(i),
3426 &label_list[next_label++]);
buzbee2cfc6392012-05-07 14:51:40 -07003427 }
buzbeead8f15e2012-06-18 14:49:45 -07003428
3429 /*
buzbeefa57c472012-11-21 12:06:18 -08003430 * Keep honest - clear reg_locations, Value => RegLocation,
buzbeead8f15e2012-06-18 14:49:45 -07003431 * promotion map and VmapTables.
3432 */
buzbeefa57c472012-11-21 12:06:18 -08003433 cu->loc_map.clear(); // Start fresh
3434 cu->reg_location = NULL;
buzbee28c9a832012-11-21 15:39:13 -08003435 for (int i = 0; i < cu->num_dalvik_registers + cu->num_compiler_temps + 1; i++) {
buzbeefa57c472012-11-21 12:06:18 -08003436 cu->promotion_map[i].core_location = kLocDalvikFrame;
3437 cu->promotion_map[i].fp_location = kLocDalvikFrame;
buzbeead8f15e2012-06-18 14:49:45 -07003438 }
buzbeefa57c472012-11-21 12:06:18 -08003439 cu->core_spill_mask = 0;
3440 cu->num_core_spills = 0;
3441 cu->fp_spill_mask = 0;
3442 cu->num_fp_spills = 0;
3443 cu->core_vmap_table.clear();
3444 cu->fp_vmap_table.clear();
buzbeead8f15e2012-06-18 14:49:45 -07003445
3446 /*
3447 * At this point, we've lost all knowledge of register promotion.
3448 * Rebuild that info from the MethodInfo intrinsic (if it
buzbeeca7a5e42012-08-20 11:12:18 -07003449 * exists - not required for correctness). Normally, this will
3450 * be the first instruction we encounter, so we won't have to iterate
3451 * through everything.
buzbeead8f15e2012-06-18 14:49:45 -07003452 */
buzbee28c9a832012-11-21 15:39:13 -08003453 for (llvm::inst_iterator i = llvm::inst_begin(func), e = llvm::inst_end(func); i != e; ++i) {
buzbeefa57c472012-11-21 12:06:18 -08003454 llvm::CallInst* call_inst = llvm::dyn_cast<llvm::CallInst>(&*i);
3455 if (call_inst != NULL) {
3456 llvm::Function* callee = call_inst->getCalledFunction();
buzbeeca7a5e42012-08-20 11:12:18 -07003457 greenland::IntrinsicHelper::IntrinsicId id =
buzbeefa57c472012-11-21 12:06:18 -08003458 cu->intrinsic_helper->GetIntrinsicId(callee);
buzbeeca7a5e42012-08-20 11:12:18 -07003459 if (id == greenland::IntrinsicHelper::MethodInfo) {
buzbeefa57c472012-11-21 12:06:18 -08003460 if (cu->verbose) {
buzbeeca7a5e42012-08-20 11:12:18 -07003461 LOG(INFO) << "Found MethodInfo";
3462 }
buzbeefa57c472012-11-21 12:06:18 -08003463 llvm::MDNode* reg_info_node = call_inst->getMetadata("RegInfo");
3464 if (reg_info_node != NULL) {
3465 llvm::ConstantInt* num_ins_value =
3466 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(0));
3467 llvm::ConstantInt* num_regs_value =
3468 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(1));
3469 llvm::ConstantInt* num_outs_value =
3470 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(2));
3471 llvm::ConstantInt* num_compiler_temps_value =
3472 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(3));
3473 llvm::ConstantInt* num_ssa_regs_value =
3474 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(4));
3475 if (cu->verbose) {
3476 LOG(INFO) << "RegInfo - Ins:" << num_ins_value->getZExtValue()
3477 << ", Regs:" << num_regs_value->getZExtValue()
3478 << ", Outs:" << num_outs_value->getZExtValue()
3479 << ", CTemps:" << num_compiler_temps_value->getZExtValue()
3480 << ", SSARegs:" << num_ssa_regs_value->getZExtValue();
buzbeeca7a5e42012-08-20 11:12:18 -07003481 }
3482 }
buzbeefa57c472012-11-21 12:06:18 -08003483 llvm::MDNode* pmap_info_node = call_inst->getMetadata("PromotionMap");
3484 if (pmap_info_node != NULL) {
3485 int elems = pmap_info_node->getNumOperands();
3486 if (cu->verbose) {
buzbeeca7a5e42012-08-20 11:12:18 -07003487 LOG(INFO) << "PMap size: " << elems;
3488 }
3489 for (int i = 0; i < elems; i++) {
buzbeefa57c472012-11-21 12:06:18 -08003490 llvm::ConstantInt* raw_map_data =
3491 static_cast<llvm::ConstantInt*>(pmap_info_node->getOperand(i));
3492 uint32_t map_data = raw_map_data->getZExtValue();
3493 PromotionMap* p = &cu->promotion_map[i];
3494 p->first_in_pair = (map_data >> 24) & 0xff;
3495 p->FpReg = (map_data >> 16) & 0xff;
3496 p->core_reg = (map_data >> 8) & 0xff;
3497 p->fp_location = static_cast<RegLocationType>((map_data >> 4) & 0xf);
3498 if (p->fp_location == kLocPhysReg) {
3499 RecordFpPromotion(cu, p->FpReg, i);
buzbeeca7a5e42012-08-20 11:12:18 -07003500 }
buzbeefa57c472012-11-21 12:06:18 -08003501 p->core_location = static_cast<RegLocationType>(map_data & 0xf);
3502 if (p->core_location == kLocPhysReg) {
3503 RecordCorePromotion(cu, p->core_reg, i);
buzbeeca7a5e42012-08-20 11:12:18 -07003504 }
3505 }
buzbeefa57c472012-11-21 12:06:18 -08003506 if (cu->verbose) {
3507 DumpPromotionMap(cu);
buzbeeca7a5e42012-08-20 11:12:18 -07003508 }
3509 }
3510 break;
3511 }
3512 }
3513 }
buzbee02031b12012-11-23 09:41:35 -08003514 cg->AdjustSpillMask(cu);
buzbeefa57c472012-11-21 12:06:18 -08003515 cu->frame_size = ComputeFrameSize(cu);
buzbeead8f15e2012-06-18 14:49:45 -07003516
3517 // Create RegLocations for arguments
buzbeefa57c472012-11-21 12:06:18 -08003518 llvm::Function::arg_iterator it(cu->func->arg_begin());
3519 llvm::Function::arg_iterator it_end(cu->func->arg_end());
buzbeead8f15e2012-06-18 14:49:45 -07003520 for (; it != it_end; ++it) {
3521 llvm::Value* val = it;
buzbeefa57c472012-11-21 12:06:18 -08003522 CreateLocFromValue(cu, val);
buzbeead8f15e2012-06-18 14:49:45 -07003523 }
3524 // Create RegLocations for all non-argument defintions
buzbee28c9a832012-11-21 15:39:13 -08003525 for (llvm::inst_iterator i = llvm::inst_begin(func), e = llvm::inst_end(func); i != e; ++i) {
buzbeead8f15e2012-06-18 14:49:45 -07003526 llvm::Value* val = &*i;
3527 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
buzbeefa57c472012-11-21 12:06:18 -08003528 CreateLocFromValue(cu, val);
buzbeead8f15e2012-06-18 14:49:45 -07003529 }
3530 }
3531
buzbee2cfc6392012-05-07 14:51:40 -07003532 // Walk the blocks, generating code.
buzbee28c9a832012-11-21 15:39:13 -08003533 for (llvm::Function::iterator i = cu->func->begin(), e = cu->func->end(); i != e; ++i) {
buzbeefa57c472012-11-21 12:06:18 -08003534 BitcodeBlockCodeGen(cu, static_cast<llvm::BasicBlock*>(i));
buzbee2cfc6392012-05-07 14:51:40 -07003535 }
3536
buzbee02031b12012-11-23 09:41:35 -08003537 cg->HandleSuspendLaunchPads(cu);
buzbee2cfc6392012-05-07 14:51:40 -07003538
buzbee02031b12012-11-23 09:41:35 -08003539 cg->HandleThrowLaunchPads(cu);
buzbee2cfc6392012-05-07 14:51:40 -07003540
buzbee02031b12012-11-23 09:41:35 -08003541 cg->HandleIntrinsicLaunchPads(cu);
buzbee2cfc6392012-05-07 14:51:40 -07003542
buzbeefa57c472012-11-21 12:06:18 -08003543 cu->func->eraseFromParent();
3544 cu->func = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07003545}
3546
3547
3548} // namespace art