blob: 19b069c40dda75bd28b81f629a6955f0417792ed [file] [log] [blame]
buzbee2cfc6392012-05-07 14:51:40 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
buzbee2cfc6392012-05-07 14:51:40 -070017#include "object_utils.h"
18
19#include <llvm/Support/ToolOutputFile.h>
20#include <llvm/Bitcode/ReaderWriter.h>
21#include <llvm/Analysis/Verifier.h>
22#include <llvm/Metadata.h>
23#include <llvm/ADT/DepthFirstIterator.h>
24#include <llvm/Instruction.h>
25#include <llvm/Type.h>
26#include <llvm/Instructions.h>
27#include <llvm/Support/Casting.h>
buzbeead8f15e2012-06-18 14:49:45 -070028#include <llvm/Support/InstIterator.h>
buzbee2cfc6392012-05-07 14:51:40 -070029
buzbee1bc37c62012-11-20 13:35:41 -080030#include "../compiler_internals.h"
buzbeeeaf09bc2012-11-15 14:51:41 -080031#include "local_optimizations.h"
buzbee1bc37c62012-11-20 13:35:41 -080032#include "codegen_util.h"
33#include "ralloc_util.h"
buzbeeeaf09bc2012-11-15 14:51:41 -080034
buzbee8320f382012-09-11 16:29:42 -070035static const char* kLabelFormat = "%c0x%x_%d";
buzbee951c0a12012-10-03 16:31:39 -070036static const char kInvalidBlock = 0xff;
buzbee8320f382012-09-11 16:29:42 -070037static const char kNormalBlock = 'L';
38static const char kCatchBlock = 'C';
buzbee2cfc6392012-05-07 14:51:40 -070039
40namespace art {
buzbeefa57c472012-11-21 12:06:18 -080041static RegLocation GetLoc(CompilationUnit* cu, llvm::Value* val);
buzbee2cfc6392012-05-07 14:51:40 -070042
buzbeefa57c472012-11-21 12:06:18 -080043static llvm::BasicBlock* GetLLVMBlock(CompilationUnit* cu, int id)
buzbee2cfc6392012-05-07 14:51:40 -070044{
buzbeefa57c472012-11-21 12:06:18 -080045 return cu->id_to_block_map.Get(id);
buzbee2cfc6392012-05-07 14:51:40 -070046}
47
buzbeefa57c472012-11-21 12:06:18 -080048static llvm::Value* GetLLVMValue(CompilationUnit* cu, int s_reg)
buzbee2cfc6392012-05-07 14:51:40 -070049{
buzbeefa57c472012-11-21 12:06:18 -080050 return reinterpret_cast<llvm::Value*>(GrowableListGetElement(&cu->llvm_values, s_reg));
buzbee2cfc6392012-05-07 14:51:40 -070051}
52
53// Replace the placeholder value with the real definition
buzbeefa57c472012-11-21 12:06:18 -080054static void DefineValue(CompilationUnit* cu, llvm::Value* val, int s_reg)
buzbee2cfc6392012-05-07 14:51:40 -070055{
buzbeefa57c472012-11-21 12:06:18 -080056 llvm::Value* placeholder = GetLLVMValue(cu, s_reg);
buzbee9a2487f2012-07-26 14:01:13 -070057 if (placeholder == NULL) {
58 // This can happen on instruction rewrite on verification failure
Bill Buzbeec9f40dd2012-08-15 11:35:25 -070059 LOG(WARNING) << "Null placeholder";
buzbee9a2487f2012-07-26 14:01:13 -070060 return;
61 }
buzbee2cfc6392012-05-07 14:51:40 -070062 placeholder->replaceAllUsesWith(val);
63 val->takeName(placeholder);
buzbeefa57c472012-11-21 12:06:18 -080064 cu->llvm_values.elem_list[s_reg] = reinterpret_cast<uintptr_t>(val);
buzbee4be777b2012-07-12 14:38:18 -070065 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(placeholder);
66 DCHECK(inst != NULL);
67 inst->eraseFromParent();
TDYa1278e950c12012-11-02 09:58:19 -070068
69 // Set vreg for debugging
buzbeefa57c472012-11-21 12:06:18 -080070 if (!cu->compiler->IsDebuggingSupported()) {
TDYa1278e950c12012-11-02 09:58:19 -070071 greenland::IntrinsicHelper::IntrinsicId id =
72 greenland::IntrinsicHelper::SetVReg;
buzbeefa57c472012-11-21 12:06:18 -080073 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id);
74 int v_reg = SRegToVReg(cu, s_reg);
75 llvm::Value* table_slot = cu->irb->getInt32(v_reg);
76 llvm::Value* args[] = { table_slot, val };
77 cu->irb->CreateCall(func, args);
TDYa1278e950c12012-11-02 09:58:19 -070078 }
buzbee2cfc6392012-05-07 14:51:40 -070079}
80
buzbeefa57c472012-11-21 12:06:18 -080081static llvm::Type* LlvmTypeFromLocRec(CompilationUnit* cu, RegLocation loc)
buzbee2cfc6392012-05-07 14:51:40 -070082{
83 llvm::Type* res = NULL;
84 if (loc.wide) {
85 if (loc.fp)
buzbeefa57c472012-11-21 12:06:18 -080086 res = cu->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070087 else
buzbeefa57c472012-11-21 12:06:18 -080088 res = cu->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070089 } else {
90 if (loc.fp) {
buzbeefa57c472012-11-21 12:06:18 -080091 res = cu->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -070092 } else {
93 if (loc.ref)
buzbeefa57c472012-11-21 12:06:18 -080094 res = cu->irb->GetJObjectTy();
buzbee2cfc6392012-05-07 14:51:40 -070095 else
buzbeefa57c472012-11-21 12:06:18 -080096 res = cu->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -070097 }
98 }
99 return res;
100}
101
buzbeead8f15e2012-06-18 14:49:45 -0700102/* Create an in-memory RegLocation from an llvm Value. */
buzbeefa57c472012-11-21 12:06:18 -0800103static void CreateLocFromValue(CompilationUnit* cu, llvm::Value* val)
buzbeead8f15e2012-06-18 14:49:45 -0700104{
105 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
106 std::string s(val->getName().str());
buzbeefa57c472012-11-21 12:06:18 -0800107 const char* val_name = s.c_str();
108 SafeMap<llvm::Value*, RegLocation>::iterator it = cu->loc_map.find(val);
109 DCHECK(it == cu->loc_map.end()) << " - already defined: " << val_name;
110 int base_sreg = INVALID_SREG;
buzbeead8f15e2012-06-18 14:49:45 -0700111 int subscript = -1;
buzbeefa57c472012-11-21 12:06:18 -0800112 sscanf(val_name, "v%d_%d", &base_sreg, &subscript);
113 if ((base_sreg == INVALID_SREG) && (!strcmp(val_name, "method"))) {
114 base_sreg = SSA_METHOD_BASEREG;
buzbeead8f15e2012-06-18 14:49:45 -0700115 subscript = 0;
116 }
buzbeefa57c472012-11-21 12:06:18 -0800117 DCHECK_NE(base_sreg, INVALID_SREG);
buzbeead8f15e2012-06-18 14:49:45 -0700118 DCHECK_NE(subscript, -1);
119 // TODO: redo during C++'ification
120 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
121 INVALID_REG, INVALID_SREG, INVALID_SREG};
122 llvm::Type* ty = val->getType();
buzbeefa57c472012-11-21 12:06:18 -0800123 loc.wide = ((ty == cu->irb->getInt64Ty()) ||
124 (ty == cu->irb->getDoubleTy()));
buzbeead8f15e2012-06-18 14:49:45 -0700125 loc.defined = true;
buzbeeca7a5e42012-08-20 11:12:18 -0700126 loc.home = false; // May change during promotion
buzbeefa57c472012-11-21 12:06:18 -0800127 loc.s_reg_low = base_sreg;
128 loc.orig_sreg = cu->loc_map.size();
129 PromotionMap p_map = cu->promotion_map[base_sreg];
130 if (ty == cu->irb->getFloatTy()) {
buzbeeca7a5e42012-08-20 11:12:18 -0700131 loc.fp = true;
buzbeefa57c472012-11-21 12:06:18 -0800132 if (p_map.fp_location == kLocPhysReg) {
133 loc.low_reg = p_map.FpReg;
buzbeeca7a5e42012-08-20 11:12:18 -0700134 loc.location = kLocPhysReg;
135 loc.home = true;
136 }
buzbeefa57c472012-11-21 12:06:18 -0800137 } else if (ty == cu->irb->getDoubleTy()) {
buzbeeca7a5e42012-08-20 11:12:18 -0700138 loc.fp = true;
buzbeefa57c472012-11-21 12:06:18 -0800139 PromotionMap p_map_high = cu->promotion_map[base_sreg + 1];
140 if ((p_map.fp_location == kLocPhysReg) &&
141 (p_map_high.fp_location == kLocPhysReg) &&
142 ((p_map.FpReg & 0x1) == 0) &&
143 (p_map.FpReg + 1 == p_map_high.FpReg)) {
144 loc.low_reg = p_map.FpReg;
145 loc.high_reg = p_map_high.FpReg;
buzbeeca7a5e42012-08-20 11:12:18 -0700146 loc.location = kLocPhysReg;
147 loc.home = true;
148 }
buzbeefa57c472012-11-21 12:06:18 -0800149 } else if (ty == cu->irb->GetJObjectTy()) {
buzbeeca7a5e42012-08-20 11:12:18 -0700150 loc.ref = true;
buzbeefa57c472012-11-21 12:06:18 -0800151 if (p_map.core_location == kLocPhysReg) {
152 loc.low_reg = p_map.core_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700153 loc.location = kLocPhysReg;
154 loc.home = true;
155 }
buzbeefa57c472012-11-21 12:06:18 -0800156 } else if (ty == cu->irb->getInt64Ty()) {
buzbeeca7a5e42012-08-20 11:12:18 -0700157 loc.core = true;
buzbeefa57c472012-11-21 12:06:18 -0800158 PromotionMap p_map_high = cu->promotion_map[base_sreg + 1];
159 if ((p_map.core_location == kLocPhysReg) &&
160 (p_map_high.core_location == kLocPhysReg)) {
161 loc.low_reg = p_map.core_reg;
162 loc.high_reg = p_map_high.core_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700163 loc.location = kLocPhysReg;
164 loc.home = true;
165 }
166 } else {
167 loc.core = true;
buzbeefa57c472012-11-21 12:06:18 -0800168 if (p_map.core_location == kLocPhysReg) {
169 loc.low_reg = p_map.core_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700170 loc.location = kLocPhysReg;
171 loc.home = true;
172 }
173 }
174
buzbeefa57c472012-11-21 12:06:18 -0800175 if (cu->verbose && loc.home) {
buzbeeca7a5e42012-08-20 11:12:18 -0700176 if (loc.wide) {
buzbeefa57c472012-11-21 12:06:18 -0800177 LOG(INFO) << "Promoted wide " << s << " to regs " << loc.low_reg << "/" << loc.high_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700178 } else {
buzbeefa57c472012-11-21 12:06:18 -0800179 LOG(INFO) << "Promoted " << s << " to reg " << loc.low_reg;
buzbeeca7a5e42012-08-20 11:12:18 -0700180 }
181 }
buzbeefa57c472012-11-21 12:06:18 -0800182 cu->loc_map.Put(val, loc);
buzbeead8f15e2012-06-18 14:49:45 -0700183}
buzbeeaad94382012-11-21 07:40:50 -0800184
buzbeefa57c472012-11-21 12:06:18 -0800185static void InitIR(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -0700186{
buzbeefa57c472012-11-21 12:06:18 -0800187 LLVMInfo* llvm_info = cu->llvm_info;
188 if (llvm_info == NULL) {
189 CompilerTls* tls = cu->compiler->GetTls();
buzbee4df2bbd2012-10-11 14:46:06 -0700190 CHECK(tls != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800191 llvm_info = static_cast<LLVMInfo*>(tls->GetLLVMInfo());
192 if (llvm_info == NULL) {
193 llvm_info = new LLVMInfo();
194 tls->SetLLVMInfo(llvm_info);
buzbee4df2bbd2012-10-11 14:46:06 -0700195 }
196 }
buzbeefa57c472012-11-21 12:06:18 -0800197 cu->context = llvm_info->GetLLVMContext();
198 cu->module = llvm_info->GetLLVMModule();
199 cu->intrinsic_helper = llvm_info->GetIntrinsicHelper();
200 cu->irb = llvm_info->GetIRBuilder();
buzbee2cfc6392012-05-07 14:51:40 -0700201}
202
buzbeefa57c472012-11-21 12:06:18 -0800203static const char* LlvmSSAName(CompilationUnit* cu, int ssa_reg) {
204 return GET_ELEM_N(cu->ssa_strings, char*, ssa_reg);
buzbee2cfc6392012-05-07 14:51:40 -0700205}
206
buzbeefa57c472012-11-21 12:06:18 -0800207llvm::BasicBlock* FindCaseTarget(CompilationUnit* cu, uint32_t vaddr)
buzbeef58c12c2012-07-03 15:06:29 -0700208{
buzbeefa57c472012-11-21 12:06:18 -0800209 BasicBlock* bb = FindBlock(cu, vaddr);
buzbeef58c12c2012-07-03 15:06:29 -0700210 DCHECK(bb != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800211 return GetLLVMBlock(cu, bb->id);
buzbeef58c12c2012-07-03 15:06:29 -0700212}
213
buzbeefa57c472012-11-21 12:06:18 -0800214static void ConvertPackedSwitch(CompilationUnit* cu, BasicBlock* bb,
215 int32_t table_offset, RegLocation rl_src)
buzbeef58c12c2012-07-03 15:06:29 -0700216{
217 const Instruction::PackedSwitchPayload* payload =
218 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
buzbeefa57c472012-11-21 12:06:18 -0800219 cu->insns + cu->current_dalvik_offset + table_offset);
buzbeef58c12c2012-07-03 15:06:29 -0700220
buzbeefa57c472012-11-21 12:06:18 -0800221 llvm::Value* value = GetLLVMValue(cu, rl_src.orig_sreg);
buzbeef58c12c2012-07-03 15:06:29 -0700222
223 llvm::SwitchInst* sw =
buzbeefa57c472012-11-21 12:06:18 -0800224 cu->irb->CreateSwitch(value, GetLLVMBlock(cu, bb->fall_through->id),
buzbeef58c12c2012-07-03 15:06:29 -0700225 payload->case_count);
226
227 for (uint16_t i = 0; i < payload->case_count; ++i) {
buzbeefa57c472012-11-21 12:06:18 -0800228 llvm::BasicBlock* llvm_bb =
229 FindCaseTarget(cu, cu->current_dalvik_offset + payload->targets[i]);
230 sw->addCase(cu->irb->getInt32(payload->first_key + i), llvm_bb);
buzbeef58c12c2012-07-03 15:06:29 -0700231 }
buzbeefa57c472012-11-21 12:06:18 -0800232 llvm::MDNode* switch_node =
233 llvm::MDNode::get(*cu->context, cu->irb->getInt32(table_offset));
234 sw->setMetadata("SwitchTable", switch_node);
buzbeef58c12c2012-07-03 15:06:29 -0700235 bb->taken = NULL;
buzbeefa57c472012-11-21 12:06:18 -0800236 bb->fall_through = NULL;
buzbeef58c12c2012-07-03 15:06:29 -0700237}
238
buzbeefa57c472012-11-21 12:06:18 -0800239static void ConvertSparseSwitch(CompilationUnit* cu, BasicBlock* bb,
240 int32_t table_offset, RegLocation rl_src)
buzbeea1da8a52012-07-09 14:00:21 -0700241{
242 const Instruction::SparseSwitchPayload* payload =
243 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
buzbeefa57c472012-11-21 12:06:18 -0800244 cu->insns + cu->current_dalvik_offset + table_offset);
buzbeea1da8a52012-07-09 14:00:21 -0700245
246 const int32_t* keys = payload->GetKeys();
247 const int32_t* targets = payload->GetTargets();
248
buzbeefa57c472012-11-21 12:06:18 -0800249 llvm::Value* value = GetLLVMValue(cu, rl_src.orig_sreg);
buzbeea1da8a52012-07-09 14:00:21 -0700250
251 llvm::SwitchInst* sw =
buzbeefa57c472012-11-21 12:06:18 -0800252 cu->irb->CreateSwitch(value, GetLLVMBlock(cu, bb->fall_through->id),
buzbeea1da8a52012-07-09 14:00:21 -0700253 payload->case_count);
254
255 for (size_t i = 0; i < payload->case_count; ++i) {
buzbeefa57c472012-11-21 12:06:18 -0800256 llvm::BasicBlock* llvm_bb =
257 FindCaseTarget(cu, cu->current_dalvik_offset + targets[i]);
258 sw->addCase(cu->irb->getInt32(keys[i]), llvm_bb);
buzbeea1da8a52012-07-09 14:00:21 -0700259 }
buzbeefa57c472012-11-21 12:06:18 -0800260 llvm::MDNode* switch_node =
261 llvm::MDNode::get(*cu->context, cu->irb->getInt32(table_offset));
262 sw->setMetadata("SwitchTable", switch_node);
buzbeea1da8a52012-07-09 14:00:21 -0700263 bb->taken = NULL;
buzbeefa57c472012-11-21 12:06:18 -0800264 bb->fall_through = NULL;
buzbeea1da8a52012-07-09 14:00:21 -0700265}
266
buzbeefa57c472012-11-21 12:06:18 -0800267static void ConvertSget(CompilationUnit* cu, int32_t field_index,
268 greenland::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest)
buzbee4f1181f2012-06-22 13:52:12 -0700269{
buzbeefa57c472012-11-21 12:06:18 -0800270 llvm::Constant* field_idx = cu->irb->getInt32(field_index);
271 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
272 llvm::Value* res = cu->irb->CreateCall(intr, field_idx);
273 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700274}
275
buzbeefa57c472012-11-21 12:06:18 -0800276static void ConvertSput(CompilationUnit* cu, int32_t field_index,
277 greenland::IntrinsicHelper::IntrinsicId id, RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700278{
279 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800280 args.push_back(cu->irb->getInt32(field_index));
281 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
282 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
283 cu->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700284}
285
buzbeefa57c472012-11-21 12:06:18 -0800286static void ConvertFillArrayData(CompilationUnit* cu, int32_t offset, RegLocation rl_array)
buzbee101305f2012-06-28 18:00:56 -0700287{
288 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700289 id = greenland::IntrinsicHelper::HLFillArrayData;
buzbee101305f2012-06-28 18:00:56 -0700290 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800291 args.push_back(cu->irb->getInt32(offset));
292 args.push_back(GetLLVMValue(cu, rl_array.orig_sreg));
293 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
294 cu->irb->CreateCall(intr, args);
buzbee101305f2012-06-28 18:00:56 -0700295}
296
buzbeefa57c472012-11-21 12:06:18 -0800297static llvm::Value* EmitConst(CompilationUnit* cu, llvm::ArrayRef<llvm::Value*> src,
buzbeeaad94382012-11-21 07:40:50 -0800298 RegLocation loc)
buzbee2cfc6392012-05-07 14:51:40 -0700299{
300 greenland::IntrinsicHelper::IntrinsicId id;
301 if (loc.wide) {
302 if (loc.fp) {
303 id = greenland::IntrinsicHelper::ConstDouble;
304 } else {
305 id = greenland::IntrinsicHelper::ConstLong;
306 }
307 } else {
308 if (loc.fp) {
309 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700310 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700311 id = greenland::IntrinsicHelper::ConstObj;
312 } else {
313 id = greenland::IntrinsicHelper::ConstInt;
314 }
315 }
buzbeefa57c472012-11-21 12:06:18 -0800316 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
317 return cu->irb->CreateCall(intr, src);
buzbee2cfc6392012-05-07 14:51:40 -0700318}
buzbeeb03f4872012-06-11 15:22:11 -0700319
buzbeefa57c472012-11-21 12:06:18 -0800320static void EmitPopShadowFrame(CompilationUnit* cu)
buzbeeb03f4872012-06-11 15:22:11 -0700321{
buzbeefa57c472012-11-21 12:06:18 -0800322 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(
buzbeeb03f4872012-06-11 15:22:11 -0700323 greenland::IntrinsicHelper::PopShadowFrame);
buzbeefa57c472012-11-21 12:06:18 -0800324 cu->irb->CreateCall(intr);
buzbeeb03f4872012-06-11 15:22:11 -0700325}
326
buzbeefa57c472012-11-21 12:06:18 -0800327static llvm::Value* EmitCopy(CompilationUnit* cu, llvm::ArrayRef<llvm::Value*> src,
buzbeeaad94382012-11-21 07:40:50 -0800328 RegLocation loc)
buzbee2cfc6392012-05-07 14:51:40 -0700329{
330 greenland::IntrinsicHelper::IntrinsicId id;
331 if (loc.wide) {
332 if (loc.fp) {
333 id = greenland::IntrinsicHelper::CopyDouble;
334 } else {
335 id = greenland::IntrinsicHelper::CopyLong;
336 }
337 } else {
338 if (loc.fp) {
339 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700340 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700341 id = greenland::IntrinsicHelper::CopyObj;
342 } else {
343 id = greenland::IntrinsicHelper::CopyInt;
344 }
345 }
buzbeefa57c472012-11-21 12:06:18 -0800346 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
347 return cu->irb->CreateCall(intr, src);
buzbee2cfc6392012-05-07 14:51:40 -0700348}
349
buzbeefa57c472012-11-21 12:06:18 -0800350static void ConvertMoveException(CompilationUnit* cu, RegLocation rl_dest)
buzbee32412962012-06-26 16:27:56 -0700351{
buzbeefa57c472012-11-21 12:06:18 -0800352 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(
buzbee32412962012-06-26 16:27:56 -0700353 greenland::IntrinsicHelper::GetException);
buzbeefa57c472012-11-21 12:06:18 -0800354 llvm::Value* res = cu->irb->CreateCall(func);
355 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee32412962012-06-26 16:27:56 -0700356}
357
buzbeefa57c472012-11-21 12:06:18 -0800358static void ConvertThrow(CompilationUnit* cu, RegLocation rl_src)
buzbee32412962012-06-26 16:27:56 -0700359{
buzbeefa57c472012-11-21 12:06:18 -0800360 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
361 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(
TDYa127f71bf5a2012-07-29 20:09:52 -0700362 greenland::IntrinsicHelper::HLThrowException);
buzbeefa57c472012-11-21 12:06:18 -0800363 cu->irb->CreateCall(func, src);
buzbee32412962012-06-26 16:27:56 -0700364}
365
buzbeefa57c472012-11-21 12:06:18 -0800366static void ConvertMonitorEnterExit(CompilationUnit* cu, int opt_flags,
buzbeeaad94382012-11-21 07:40:50 -0800367 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800368 RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700369{
370 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800371 args.push_back(cu->irb->getInt32(opt_flags));
372 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
373 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id);
374 cu->irb->CreateCall(func, args);
buzbee8fa0fda2012-06-27 15:44:52 -0700375}
376
buzbeefa57c472012-11-21 12:06:18 -0800377static void ConvertArrayLength(CompilationUnit* cu, int opt_flags,
378 RegLocation rl_dest, RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700379{
380 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800381 args.push_back(cu->irb->getInt32(opt_flags));
382 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
383 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700384 greenland::IntrinsicHelper::OptArrayLength);
buzbeefa57c472012-11-21 12:06:18 -0800385 llvm::Value* res = cu->irb->CreateCall(func, args);
386 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700387}
388
buzbeefa57c472012-11-21 12:06:18 -0800389static void EmitSuspendCheck(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -0700390{
391 greenland::IntrinsicHelper::IntrinsicId id =
392 greenland::IntrinsicHelper::CheckSuspend;
buzbeefa57c472012-11-21 12:06:18 -0800393 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
394 cu->irb->CreateCall(intr);
buzbee2cfc6392012-05-07 14:51:40 -0700395}
396
buzbeefa57c472012-11-21 12:06:18 -0800397static llvm::Value* ConvertCompare(CompilationUnit* cu, ConditionCode cc,
buzbeeaad94382012-11-21 07:40:50 -0800398 llvm::Value* src1, llvm::Value* src2)
buzbee2cfc6392012-05-07 14:51:40 -0700399{
400 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700401 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700402 switch(cc) {
buzbeefa57c472012-11-21 12:06:18 -0800403 case kCondEq: res = cu->irb->CreateICmpEQ(src1, src2); break;
404 case kCondNe: res = cu->irb->CreateICmpNE(src1, src2); break;
405 case kCondLt: res = cu->irb->CreateICmpSLT(src1, src2); break;
406 case kCondGe: res = cu->irb->CreateICmpSGE(src1, src2); break;
407 case kCondGt: res = cu->irb->CreateICmpSGT(src1, src2); break;
408 case kCondLe: res = cu->irb->CreateICmpSLE(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700409 default: LOG(FATAL) << "Unexpected cc value " << cc;
410 }
411 return res;
412}
413
buzbeefa57c472012-11-21 12:06:18 -0800414static void ConvertCompareAndBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
415 ConditionCode cc, RegLocation rl_src1, RegLocation rl_src2)
buzbee2cfc6392012-05-07 14:51:40 -0700416{
buzbeefa57c472012-11-21 12:06:18 -0800417 if (bb->taken->start_offset <= mir->offset) {
418 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -0700419 }
buzbeefa57c472012-11-21 12:06:18 -0800420 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
421 llvm::Value* src2 = GetLLVMValue(cu, rl_src2.orig_sreg);
422 llvm::Value* cond_value = ConvertCompare(cu, cc, src1, src2);
423 cond_value->setName(StringPrintf("t%d", cu->temp_name++));
424 cu->irb->CreateCondBr(cond_value, GetLLVMBlock(cu, bb->taken->id),
425 GetLLVMBlock(cu, bb->fall_through->id));
buzbee6969d502012-06-15 16:40:31 -0700426 // Don't redo the fallthrough branch in the BB driver
buzbeefa57c472012-11-21 12:06:18 -0800427 bb->fall_through = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700428}
429
buzbeefa57c472012-11-21 12:06:18 -0800430static void ConvertCompareZeroAndBranch(CompilationUnit* cu, BasicBlock* bb,
431 MIR* mir, ConditionCode cc, RegLocation rl_src1)
buzbee2cfc6392012-05-07 14:51:40 -0700432{
buzbeefa57c472012-11-21 12:06:18 -0800433 if (bb->taken->start_offset <= mir->offset) {
434 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -0700435 }
buzbeefa57c472012-11-21 12:06:18 -0800436 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700437 llvm::Value* src2;
buzbeefa57c472012-11-21 12:06:18 -0800438 if (rl_src1.ref) {
439 src2 = cu->irb->GetJNull();
buzbee2cfc6392012-05-07 14:51:40 -0700440 } else {
buzbeefa57c472012-11-21 12:06:18 -0800441 src2 = cu->irb->getInt32(0);
buzbee2cfc6392012-05-07 14:51:40 -0700442 }
buzbeefa57c472012-11-21 12:06:18 -0800443 llvm::Value* cond_value = ConvertCompare(cu, cc, src1, src2);
444 cu->irb->CreateCondBr(cond_value, GetLLVMBlock(cu, bb->taken->id),
445 GetLLVMBlock(cu, bb->fall_through->id));
buzbee6969d502012-06-15 16:40:31 -0700446 // Don't redo the fallthrough branch in the BB driver
buzbeefa57c472012-11-21 12:06:18 -0800447 bb->fall_through = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700448}
449
buzbeefa57c472012-11-21 12:06:18 -0800450static llvm::Value* GenDivModOp(CompilationUnit* cu, bool is_div, bool is_long,
buzbeeaad94382012-11-21 07:40:50 -0800451 llvm::Value* src1, llvm::Value* src2)
buzbee2cfc6392012-05-07 14:51:40 -0700452{
453 greenland::IntrinsicHelper::IntrinsicId id;
buzbeefa57c472012-11-21 12:06:18 -0800454 if (is_long) {
455 if (is_div) {
buzbee2cfc6392012-05-07 14:51:40 -0700456 id = greenland::IntrinsicHelper::DivLong;
457 } else {
458 id = greenland::IntrinsicHelper::RemLong;
459 }
Logan Chien554e6072012-07-23 20:00:01 -0700460 } else {
buzbeefa57c472012-11-21 12:06:18 -0800461 if (is_div) {
buzbee2cfc6392012-05-07 14:51:40 -0700462 id = greenland::IntrinsicHelper::DivInt;
463 } else {
464 id = greenland::IntrinsicHelper::RemInt;
Logan Chien554e6072012-07-23 20:00:01 -0700465 }
buzbee2cfc6392012-05-07 14:51:40 -0700466 }
buzbeefa57c472012-11-21 12:06:18 -0800467 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee2cfc6392012-05-07 14:51:40 -0700468 llvm::SmallVector<llvm::Value*, 2>args;
469 args.push_back(src1);
470 args.push_back(src2);
buzbeefa57c472012-11-21 12:06:18 -0800471 return cu->irb->CreateCall(intr, args);
buzbee2cfc6392012-05-07 14:51:40 -0700472}
473
buzbeefa57c472012-11-21 12:06:18 -0800474static llvm::Value* GenArithOp(CompilationUnit* cu, OpKind op, bool is_long,
buzbeeaad94382012-11-21 07:40:50 -0800475 llvm::Value* src1, llvm::Value* src2)
buzbee2cfc6392012-05-07 14:51:40 -0700476{
477 llvm::Value* res = NULL;
478 switch(op) {
buzbeefa57c472012-11-21 12:06:18 -0800479 case kOpAdd: res = cu->irb->CreateAdd(src1, src2); break;
480 case kOpSub: res = cu->irb->CreateSub(src1, src2); break;
481 case kOpRsub: res = cu->irb->CreateSub(src2, src1); break;
482 case kOpMul: res = cu->irb->CreateMul(src1, src2); break;
483 case kOpOr: res = cu->irb->CreateOr(src1, src2); break;
484 case kOpAnd: res = cu->irb->CreateAnd(src1, src2); break;
485 case kOpXor: res = cu->irb->CreateXor(src1, src2); break;
486 case kOpDiv: res = GenDivModOp(cu, true, is_long, src1, src2); break;
487 case kOpRem: res = GenDivModOp(cu, false, is_long, src1, src2); break;
488 case kOpLsl: res = cu->irb->CreateShl(src1, src2); break;
489 case kOpLsr: res = cu->irb->CreateLShr(src1, src2); break;
490 case kOpAsr: res = cu->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700491 default:
492 LOG(FATAL) << "Invalid op " << op;
493 }
494 return res;
495}
496
buzbeefa57c472012-11-21 12:06:18 -0800497static void ConvertFPArithOp(CompilationUnit* cu, OpKind op, RegLocation rl_dest,
498 RegLocation rl_src1, RegLocation rl_src2)
buzbee2cfc6392012-05-07 14:51:40 -0700499{
buzbeefa57c472012-11-21 12:06:18 -0800500 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
501 llvm::Value* src2 = GetLLVMValue(cu, rl_src2.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700502 llvm::Value* res = NULL;
503 switch(op) {
buzbeefa57c472012-11-21 12:06:18 -0800504 case kOpAdd: res = cu->irb->CreateFAdd(src1, src2); break;
505 case kOpSub: res = cu->irb->CreateFSub(src1, src2); break;
506 case kOpMul: res = cu->irb->CreateFMul(src1, src2); break;
507 case kOpDiv: res = cu->irb->CreateFDiv(src1, src2); break;
508 case kOpRem: res = cu->irb->CreateFRem(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700509 default:
510 LOG(FATAL) << "Invalid op " << op;
511 }
buzbeefa57c472012-11-21 12:06:18 -0800512 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700513}
514
buzbeefa57c472012-11-21 12:06:18 -0800515static void ConvertShift(CompilationUnit* cu, greenland::IntrinsicHelper::IntrinsicId id,
516 RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2)
buzbee4f1181f2012-06-22 13:52:12 -0700517{
buzbeefa57c472012-11-21 12:06:18 -0800518 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee2a83e8f2012-07-13 16:42:30 -0700519 llvm::SmallVector<llvm::Value*, 2>args;
buzbeefa57c472012-11-21 12:06:18 -0800520 args.push_back(GetLLVMValue(cu, rl_src1.orig_sreg));
521 args.push_back(GetLLVMValue(cu, rl_src2.orig_sreg));
522 llvm::Value* res = cu->irb->CreateCall(intr, args);
523 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2a83e8f2012-07-13 16:42:30 -0700524}
525
buzbeefa57c472012-11-21 12:06:18 -0800526static void ConvertShiftLit(CompilationUnit* cu, greenland::IntrinsicHelper::IntrinsicId id,
527 RegLocation rl_dest, RegLocation rl_src, int shift_amount)
buzbee2a83e8f2012-07-13 16:42:30 -0700528{
buzbeefa57c472012-11-21 12:06:18 -0800529 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee2a83e8f2012-07-13 16:42:30 -0700530 llvm::SmallVector<llvm::Value*, 2>args;
buzbeefa57c472012-11-21 12:06:18 -0800531 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
532 args.push_back(cu->irb->getInt32(shift_amount));
533 llvm::Value* res = cu->irb->CreateCall(intr, args);
534 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee4f1181f2012-06-22 13:52:12 -0700535}
536
buzbeefa57c472012-11-21 12:06:18 -0800537static void ConvertArithOp(CompilationUnit* cu, OpKind op, RegLocation rl_dest,
538 RegLocation rl_src1, RegLocation rl_src2)
buzbee2cfc6392012-05-07 14:51:40 -0700539{
buzbeefa57c472012-11-21 12:06:18 -0800540 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
541 llvm::Value* src2 = GetLLVMValue(cu, rl_src2.orig_sreg);
buzbee4f4dfc72012-07-02 14:54:44 -0700542 DCHECK_EQ(src1->getType(), src2->getType());
buzbeefa57c472012-11-21 12:06:18 -0800543 llvm::Value* res = GenArithOp(cu, op, rl_dest.wide, src1, src2);
544 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700545}
546
buzbeefa57c472012-11-21 12:06:18 -0800547static void SetShadowFrameEntry(CompilationUnit* cu, llvm::Value* new_val)
buzbeeb03f4872012-06-11 15:22:11 -0700548{
549 int index = -1;
buzbeefa57c472012-11-21 12:06:18 -0800550 DCHECK(new_val != NULL);
551 int v_reg = SRegToVReg(cu, GetLoc(cu, new_val).orig_sreg);
552 for (int i = 0; i < cu->num_shadow_frame_entries; i++) {
553 if (cu->shadow_map[i] == v_reg) {
buzbeeb03f4872012-06-11 15:22:11 -0700554 index = i;
555 break;
556 }
557 }
TDYa127347166a2012-08-23 12:23:44 -0700558 if (index == -1) {
559 return;
560 }
buzbeefa57c472012-11-21 12:06:18 -0800561 llvm::Type* ty = new_val->getType();
buzbeeb03f4872012-06-11 15:22:11 -0700562 greenland::IntrinsicHelper::IntrinsicId id =
563 greenland::IntrinsicHelper::SetShadowFrameEntry;
buzbeefa57c472012-11-21 12:06:18 -0800564 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id);
565 llvm::Value* table_slot = cu->irb->getInt32(index);
566 // If new_val is a Null pointer, we'll see it here as a const int. Replace
buzbee6459e7c2012-10-02 14:42:41 -0700567 if (!ty->isPointerTy()) {
buzbeefa57c472012-11-21 12:06:18 -0800568 // TODO: assert new_val created w/ dex_lang_const_int(0) or dex_lang_const_float(0)
569 new_val = cu->irb->GetJNull();
buzbee6459e7c2012-10-02 14:42:41 -0700570 }
buzbeefa57c472012-11-21 12:06:18 -0800571 llvm::Value* args[] = { new_val, table_slot };
572 cu->irb->CreateCall(func, args);
buzbeeb03f4872012-06-11 15:22:11 -0700573}
574
buzbeefa57c472012-11-21 12:06:18 -0800575static void ConvertArithOpLit(CompilationUnit* cu, OpKind op, RegLocation rl_dest,
576 RegLocation rl_src1, int32_t imm)
buzbee2cfc6392012-05-07 14:51:40 -0700577{
buzbeefa57c472012-11-21 12:06:18 -0800578 llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
579 llvm::Value* src2 = cu->irb->getInt32(imm);
580 llvm::Value* res = GenArithOp(cu, op, rl_dest.wide, src1, src2);
581 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700582}
583
buzbee101305f2012-06-28 18:00:56 -0700584/*
585 * Process arguments for invoke. Note: this code is also used to
586 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
587 * The requirements are similar.
588 */
buzbeefa57c472012-11-21 12:06:18 -0800589static void ConvertInvoke(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
590 InvokeType invoke_type, bool is_range, bool is_filled_new_array)
buzbee6969d502012-06-15 16:40:31 -0700591{
buzbee02031b12012-11-23 09:41:35 -0800592 Codegen* cg = cu->cg.get();
593 CallInfo* info = cg->NewMemCallInfo(cu, bb, mir, invoke_type, is_range);
buzbee6969d502012-06-15 16:40:31 -0700594 llvm::SmallVector<llvm::Value*, 10> args;
buzbeefa57c472012-11-21 12:06:18 -0800595 // Insert the invoke_type
596 args.push_back(cu->irb->getInt32(static_cast<int>(invoke_type)));
buzbee6969d502012-06-15 16:40:31 -0700597 // Insert the method_idx
buzbeefa57c472012-11-21 12:06:18 -0800598 args.push_back(cu->irb->getInt32(info->index));
buzbee6969d502012-06-15 16:40:31 -0700599 // Insert the optimization flags
buzbeefa57c472012-11-21 12:06:18 -0800600 args.push_back(cu->irb->getInt32(info->opt_flags));
buzbee6969d502012-06-15 16:40:31 -0700601 // Now, insert the actual arguments
buzbeefa57c472012-11-21 12:06:18 -0800602 for (int i = 0; i < info->num_arg_words;) {
603 llvm::Value* val = GetLLVMValue(cu, info->args[i].orig_sreg);
buzbee6969d502012-06-15 16:40:31 -0700604 args.push_back(val);
605 i += info->args[i].wide ? 2 : 1;
606 }
607 /*
608 * Choose the invoke return type based on actual usage. Note: may
609 * be different than shorty. For example, if a function return value
610 * is not used, we'll treat this as a void invoke.
611 */
612 greenland::IntrinsicHelper::IntrinsicId id;
buzbeefa57c472012-11-21 12:06:18 -0800613 if (is_filled_new_array) {
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700614 id = greenland::IntrinsicHelper::HLFilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700615 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700616 id = greenland::IntrinsicHelper::HLInvokeVoid;
617 } else {
618 if (info->result.wide) {
619 if (info->result.fp) {
620 id = greenland::IntrinsicHelper::HLInvokeDouble;
621 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700622 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700623 }
624 } else if (info->result.ref) {
625 id = greenland::IntrinsicHelper::HLInvokeObj;
626 } else if (info->result.fp) {
627 id = greenland::IntrinsicHelper::HLInvokeFloat;
628 } else {
629 id = greenland::IntrinsicHelper::HLInvokeInt;
630 }
631 }
buzbeefa57c472012-11-21 12:06:18 -0800632 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
633 llvm::Value* res = cu->irb->CreateCall(intr, args);
buzbee6969d502012-06-15 16:40:31 -0700634 if (info->result.location != kLocInvalid) {
buzbeefa57c472012-11-21 12:06:18 -0800635 DefineValue(cu, res, info->result.orig_sreg);
TDYa127890ea892012-08-22 10:49:42 -0700636 if (info->result.ref) {
buzbeefa57c472012-11-21 12:06:18 -0800637 SetShadowFrameEntry(cu, reinterpret_cast<llvm::Value*>
638 (cu->llvm_values.elem_list[info->result.orig_sreg]));
TDYa127890ea892012-08-22 10:49:42 -0700639 }
buzbee6969d502012-06-15 16:40:31 -0700640 }
641}
642
buzbeefa57c472012-11-21 12:06:18 -0800643static void ConvertConstObject(CompilationUnit* cu, uint32_t idx,
644 greenland::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest)
buzbee6969d502012-06-15 16:40:31 -0700645{
buzbeefa57c472012-11-21 12:06:18 -0800646 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
647 llvm::Value* index = cu->irb->getInt32(idx);
648 llvm::Value* res = cu->irb->CreateCall(intr, index);
649 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee6969d502012-06-15 16:40:31 -0700650}
651
buzbeefa57c472012-11-21 12:06:18 -0800652static void ConvertCheckCast(CompilationUnit* cu, uint32_t type_idx, RegLocation rl_src)
buzbee101305f2012-06-28 18:00:56 -0700653{
654 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700655 id = greenland::IntrinsicHelper::HLCheckCast;
buzbeefa57c472012-11-21 12:06:18 -0800656 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700657 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800658 args.push_back(cu->irb->getInt32(type_idx));
659 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
660 cu->irb->CreateCall(intr, args);
buzbee101305f2012-06-28 18:00:56 -0700661}
662
buzbeefa57c472012-11-21 12:06:18 -0800663static void ConvertNewInstance(CompilationUnit* cu, uint32_t type_idx, RegLocation rl_dest)
buzbee4f1181f2012-06-22 13:52:12 -0700664{
665 greenland::IntrinsicHelper::IntrinsicId id;
666 id = greenland::IntrinsicHelper::NewInstance;
buzbeefa57c472012-11-21 12:06:18 -0800667 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
668 llvm::Value* index = cu->irb->getInt32(type_idx);
669 llvm::Value* res = cu->irb->CreateCall(intr, index);
670 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee4f1181f2012-06-22 13:52:12 -0700671}
672
buzbeefa57c472012-11-21 12:06:18 -0800673static void ConvertNewArray(CompilationUnit* cu, uint32_t type_idx,
674 RegLocation rl_dest, RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700675{
676 greenland::IntrinsicHelper::IntrinsicId id;
677 id = greenland::IntrinsicHelper::NewArray;
buzbeefa57c472012-11-21 12:06:18 -0800678 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700679 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800680 args.push_back(cu->irb->getInt32(type_idx));
681 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
682 llvm::Value* res = cu->irb->CreateCall(intr, args);
683 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700684}
685
buzbeefa57c472012-11-21 12:06:18 -0800686static void ConvertAget(CompilationUnit* cu, int opt_flags,
buzbeeaad94382012-11-21 07:40:50 -0800687 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800688 RegLocation rl_dest, RegLocation rl_array, RegLocation rl_index)
buzbee8fa0fda2012-06-27 15:44:52 -0700689{
690 llvm::SmallVector<llvm::Value*, 3> args;
buzbeefa57c472012-11-21 12:06:18 -0800691 args.push_back(cu->irb->getInt32(opt_flags));
692 args.push_back(GetLLVMValue(cu, rl_array.orig_sreg));
693 args.push_back(GetLLVMValue(cu, rl_index.orig_sreg));
694 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
695 llvm::Value* res = cu->irb->CreateCall(intr, args);
696 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700697}
698
buzbeefa57c472012-11-21 12:06:18 -0800699static void ConvertAput(CompilationUnit* cu, int opt_flags,
buzbeeaad94382012-11-21 07:40:50 -0800700 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800701 RegLocation rl_src, RegLocation rl_array, RegLocation rl_index)
buzbee8fa0fda2012-06-27 15:44:52 -0700702{
703 llvm::SmallVector<llvm::Value*, 4> args;
buzbeefa57c472012-11-21 12:06:18 -0800704 args.push_back(cu->irb->getInt32(opt_flags));
705 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
706 args.push_back(GetLLVMValue(cu, rl_array.orig_sreg));
707 args.push_back(GetLLVMValue(cu, rl_index.orig_sreg));
708 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
709 cu->irb->CreateCall(intr, args);
buzbee8fa0fda2012-06-27 15:44:52 -0700710}
711
buzbeefa57c472012-11-21 12:06:18 -0800712static void ConvertIget(CompilationUnit* cu, int opt_flags,
buzbeeaad94382012-11-21 07:40:50 -0800713 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800714 RegLocation rl_dest, RegLocation rl_obj, int field_index)
buzbee101305f2012-06-28 18:00:56 -0700715{
716 llvm::SmallVector<llvm::Value*, 3> args;
buzbeefa57c472012-11-21 12:06:18 -0800717 args.push_back(cu->irb->getInt32(opt_flags));
718 args.push_back(GetLLVMValue(cu, rl_obj.orig_sreg));
719 args.push_back(cu->irb->getInt32(field_index));
720 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
721 llvm::Value* res = cu->irb->CreateCall(intr, args);
722 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee101305f2012-06-28 18:00:56 -0700723}
724
buzbeefa57c472012-11-21 12:06:18 -0800725static void ConvertIput(CompilationUnit* cu, int opt_flags,
buzbeeaad94382012-11-21 07:40:50 -0800726 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800727 RegLocation rl_src, RegLocation rl_obj, int field_index)
buzbee101305f2012-06-28 18:00:56 -0700728{
729 llvm::SmallVector<llvm::Value*, 4> args;
buzbeefa57c472012-11-21 12:06:18 -0800730 args.push_back(cu->irb->getInt32(opt_flags));
731 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
732 args.push_back(GetLLVMValue(cu, rl_obj.orig_sreg));
733 args.push_back(cu->irb->getInt32(field_index));
734 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
735 cu->irb->CreateCall(intr, args);
buzbee101305f2012-06-28 18:00:56 -0700736}
737
buzbeefa57c472012-11-21 12:06:18 -0800738static void ConvertInstanceOf(CompilationUnit* cu, uint32_t type_idx,
739 RegLocation rl_dest, RegLocation rl_src)
buzbee8fa0fda2012-06-27 15:44:52 -0700740{
741 greenland::IntrinsicHelper::IntrinsicId id;
742 id = greenland::IntrinsicHelper::InstanceOf;
buzbeefa57c472012-11-21 12:06:18 -0800743 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700744 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800745 args.push_back(cu->irb->getInt32(type_idx));
746 args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
747 llvm::Value* res = cu->irb->CreateCall(intr, args);
748 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee8fa0fda2012-06-27 15:44:52 -0700749}
750
buzbeefa57c472012-11-21 12:06:18 -0800751static void ConvertIntToLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee101305f2012-06-28 18:00:56 -0700752{
buzbeefa57c472012-11-21 12:06:18 -0800753 llvm::Value* res = cu->irb->CreateSExt(GetLLVMValue(cu, rl_src.orig_sreg),
754 cu->irb->getInt64Ty());
755 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee101305f2012-06-28 18:00:56 -0700756}
757
buzbeefa57c472012-11-21 12:06:18 -0800758static void ConvertLongToInt(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700759{
buzbeefa57c472012-11-21 12:06:18 -0800760 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
761 llvm::Value* res = cu->irb->CreateTrunc(src, cu->irb->getInt32Ty());
762 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700763}
764
buzbeefa57c472012-11-21 12:06:18 -0800765static void ConvertFloatToDouble(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700766{
buzbeefa57c472012-11-21 12:06:18 -0800767 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
768 llvm::Value* res = cu->irb->CreateFPExt(src, cu->irb->getDoubleTy());
769 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700770}
771
buzbeefa57c472012-11-21 12:06:18 -0800772static void ConvertDoubleToFloat(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700773{
buzbeefa57c472012-11-21 12:06:18 -0800774 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
775 llvm::Value* res = cu->irb->CreateFPTrunc(src, cu->irb->getFloatTy());
776 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700777}
778
buzbeefa57c472012-11-21 12:06:18 -0800779static void ConvertWideComparison(CompilationUnit* cu,
buzbeeaad94382012-11-21 07:40:50 -0800780 greenland::IntrinsicHelper::IntrinsicId id,
buzbeefa57c472012-11-21 12:06:18 -0800781 RegLocation rl_dest, RegLocation rl_src1,
782 RegLocation rl_src2)
buzbee76592632012-06-29 15:18:35 -0700783{
buzbeefa57c472012-11-21 12:06:18 -0800784 DCHECK_EQ(rl_src1.fp, rl_src2.fp);
785 DCHECK_EQ(rl_src1.wide, rl_src2.wide);
786 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700787 llvm::SmallVector<llvm::Value*, 2> args;
buzbeefa57c472012-11-21 12:06:18 -0800788 args.push_back(GetLLVMValue(cu, rl_src1.orig_sreg));
789 args.push_back(GetLLVMValue(cu, rl_src2.orig_sreg));
790 llvm::Value* res = cu->irb->CreateCall(intr, args);
791 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700792}
793
buzbeefa57c472012-11-21 12:06:18 -0800794static void ConvertIntNarrowing(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src,
buzbeeaad94382012-11-21 07:40:50 -0800795 greenland::IntrinsicHelper::IntrinsicId id)
buzbee101305f2012-06-28 18:00:56 -0700796{
buzbeefa57c472012-11-21 12:06:18 -0800797 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700798 llvm::Value* res =
buzbeefa57c472012-11-21 12:06:18 -0800799 cu->irb->CreateCall(intr, GetLLVMValue(cu, rl_src.orig_sreg));
800 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700801}
802
buzbeefa57c472012-11-21 12:06:18 -0800803static void ConvertNeg(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700804{
buzbeefa57c472012-11-21 12:06:18 -0800805 llvm::Value* res = cu->irb->CreateNeg(GetLLVMValue(cu, rl_src.orig_sreg));
806 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700807}
808
buzbeefa57c472012-11-21 12:06:18 -0800809static void ConvertIntToFP(CompilationUnit* cu, llvm::Type* ty, RegLocation rl_dest,
810 RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700811{
812 llvm::Value* res =
buzbeefa57c472012-11-21 12:06:18 -0800813 cu->irb->CreateSIToFP(GetLLVMValue(cu, rl_src.orig_sreg), ty);
814 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700815}
816
buzbeefa57c472012-11-21 12:06:18 -0800817static void ConvertFPToInt(CompilationUnit* cu, greenland::IntrinsicHelper::IntrinsicId id,
818 RegLocation rl_dest,
819 RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700820{
buzbeefa57c472012-11-21 12:06:18 -0800821 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
822 llvm::Value* res = cu->irb->CreateCall(intr, GetLLVMValue(cu, rl_src.orig_sreg));
823 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700824}
825
826
buzbeefa57c472012-11-21 12:06:18 -0800827static void ConvertNegFP(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700828{
829 llvm::Value* res =
buzbeefa57c472012-11-21 12:06:18 -0800830 cu->irb->CreateFNeg(GetLLVMValue(cu, rl_src.orig_sreg));
831 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee76592632012-06-29 15:18:35 -0700832}
833
buzbeefa57c472012-11-21 12:06:18 -0800834static void ConvertNot(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
buzbee76592632012-06-29 15:18:35 -0700835{
buzbeefa57c472012-11-21 12:06:18 -0800836 llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
837 llvm::Value* res = cu->irb->CreateXor(src, static_cast<uint64_t>(-1));
838 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee101305f2012-06-28 18:00:56 -0700839}
840
buzbee2cfc6392012-05-07 14:51:40 -0700841/*
842 * Target-independent code generation. Use only high-level
843 * load/store utilities here, or target-dependent genXX() handlers
844 * when necessary.
845 */
buzbeefa57c472012-11-21 12:06:18 -0800846static bool ConvertMIRNode(CompilationUnit* cu, MIR* mir, BasicBlock* bb,
847 llvm::BasicBlock* llvm_bb, LIR* label_list)
buzbee2cfc6392012-05-07 14:51:40 -0700848{
849 bool res = false; // Assume success
buzbeefa57c472012-11-21 12:06:18 -0800850 RegLocation rl_src[3];
buzbee02031b12012-11-23 09:41:35 -0800851 RegLocation rl_dest = GetBadLoc();
buzbee2cfc6392012-05-07 14:51:40 -0700852 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -0800853 int op_val = opcode;
buzbee6969d502012-06-15 16:40:31 -0700854 uint32_t vB = mir->dalvikInsn.vB;
855 uint32_t vC = mir->dalvikInsn.vC;
buzbeefa57c472012-11-21 12:06:18 -0800856 int opt_flags = mir->optimization_flags;
buzbee6969d502012-06-15 16:40:31 -0700857
buzbeefa57c472012-11-21 12:06:18 -0800858 bool object_definition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700859
buzbeefa57c472012-11-21 12:06:18 -0800860 if (cu->verbose) {
861 if (op_val < kMirOpFirst) {
862 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x" << std::hex << op_val;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700863 } else {
buzbeefa57c472012-11-21 12:06:18 -0800864 LOG(INFO) << extended_mir_op_names[op_val - kMirOpFirst] << " 0x" << std::hex << op_val;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700865 }
866 }
867
buzbee2cfc6392012-05-07 14:51:40 -0700868 /* Prep Src and Dest locations */
buzbeefa57c472012-11-21 12:06:18 -0800869 int next_sreg = 0;
870 int next_loc = 0;
871 int attrs = oat_data_flow_attributes[opcode];
buzbee02031b12012-11-23 09:41:35 -0800872 rl_src[0] = rl_src[1] = rl_src[2] = GetBadLoc();
buzbee2cfc6392012-05-07 14:51:40 -0700873 if (attrs & DF_UA) {
874 if (attrs & DF_A_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -0800875 rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
876 next_sreg+= 2;
buzbee2cfc6392012-05-07 14:51:40 -0700877 } else {
buzbeefa57c472012-11-21 12:06:18 -0800878 rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
879 next_sreg++;
buzbee2cfc6392012-05-07 14:51:40 -0700880 }
881 }
882 if (attrs & DF_UB) {
883 if (attrs & DF_B_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -0800884 rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
885 next_sreg+= 2;
buzbee2cfc6392012-05-07 14:51:40 -0700886 } else {
buzbeefa57c472012-11-21 12:06:18 -0800887 rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
888 next_sreg++;
buzbee2cfc6392012-05-07 14:51:40 -0700889 }
890 }
891 if (attrs & DF_UC) {
892 if (attrs & DF_C_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -0800893 rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700894 } else {
buzbeefa57c472012-11-21 12:06:18 -0800895 rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700896 }
897 }
898 if (attrs & DF_DA) {
899 if (attrs & DF_A_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -0800900 rl_dest = GetDestWide(cu, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700901 } else {
buzbeefa57c472012-11-21 12:06:18 -0800902 rl_dest = GetDest(cu, mir);
903 if (rl_dest.ref) {
904 object_definition = true;
buzbeeb03f4872012-06-11 15:22:11 -0700905 }
buzbee2cfc6392012-05-07 14:51:40 -0700906 }
907 }
908
909 switch (opcode) {
910 case Instruction::NOP:
911 break;
912
913 case Instruction::MOVE:
914 case Instruction::MOVE_OBJECT:
915 case Instruction::MOVE_16:
916 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700917 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700918 case Instruction::MOVE_FROM16:
919 case Instruction::MOVE_WIDE:
920 case Instruction::MOVE_WIDE_16:
921 case Instruction::MOVE_WIDE_FROM16: {
922 /*
923 * Moves/copies are meaningless in pure SSA register form,
924 * but we need to preserve them for the conversion back into
925 * MIR (at least until we stop using the Dalvik register maps).
926 * Insert a dummy intrinsic copy call, which will be recognized
927 * by the quick path and removed by the portable path.
928 */
buzbeefa57c472012-11-21 12:06:18 -0800929 llvm::Value* src = GetLLVMValue(cu, rl_src[0].orig_sreg);
930 llvm::Value* res = EmitCopy(cu, src, rl_dest);
931 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700932 }
933 break;
934
935 case Instruction::CONST:
936 case Instruction::CONST_4:
937 case Instruction::CONST_16: {
TDYa127347166a2012-08-23 12:23:44 -0700938 if (vB == 0) {
buzbeefa57c472012-11-21 12:06:18 -0800939 object_definition = true;
TDYa127347166a2012-08-23 12:23:44 -0700940 }
buzbeefa57c472012-11-21 12:06:18 -0800941 llvm::Constant* imm_value = cu->irb->GetJInt(vB);
942 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
943 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700944 }
945 break;
946
947 case Instruction::CONST_WIDE_16:
948 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700949 // Sign extend to 64 bits
950 int64_t imm = static_cast<int32_t>(vB);
buzbeefa57c472012-11-21 12:06:18 -0800951 llvm::Constant* imm_value = cu->irb->GetJLong(imm);
952 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
953 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700954 }
955 break;
956
957 case Instruction::CONST_HIGH16: {
buzbeefa57c472012-11-21 12:06:18 -0800958 llvm::Constant* imm_value = cu->irb->GetJInt(vB << 16);
959 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
960 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -0700961 }
962 break;
963
964 case Instruction::CONST_WIDE: {
buzbeefa57c472012-11-21 12:06:18 -0800965 llvm::Constant* imm_value =
966 cu->irb->GetJLong(mir->dalvikInsn.vB_wide);
967 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
968 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee4f1181f2012-06-22 13:52:12 -0700969 }
970 break;
buzbee2cfc6392012-05-07 14:51:40 -0700971 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700972 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbeefa57c472012-11-21 12:06:18 -0800973 llvm::Constant* imm_value = cu->irb->GetJLong(imm);
974 llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
975 DefineValue(cu, res, rl_dest.orig_sreg);
buzbee4f1181f2012-06-22 13:52:12 -0700976 }
977 break;
978
buzbee8fa0fda2012-06-27 15:44:52 -0700979 case Instruction::SPUT_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -0800980 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputObject,
981 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700982 break;
983 case Instruction::SPUT:
buzbeefa57c472012-11-21 12:06:18 -0800984 if (rl_src[0].fp) {
985 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputFloat,
986 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700987 } else {
buzbeefa57c472012-11-21 12:06:18 -0800988 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSput, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700989 }
990 break;
991 case Instruction::SPUT_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -0800992 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputBoolean,
993 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700994 break;
995 case Instruction::SPUT_BYTE:
buzbeefa57c472012-11-21 12:06:18 -0800996 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputByte, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700997 break;
998 case Instruction::SPUT_CHAR:
buzbeefa57c472012-11-21 12:06:18 -0800999 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputChar, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001000 break;
1001 case Instruction::SPUT_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001002 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputShort, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001003 break;
1004 case Instruction::SPUT_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001005 if (rl_src[0].fp) {
1006 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputDouble,
1007 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001008 } else {
buzbeefa57c472012-11-21 12:06:18 -08001009 ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputWide,
1010 rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001011 }
1012 break;
1013
1014 case Instruction::SGET_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -08001015 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetObject, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001016 break;
1017 case Instruction::SGET:
buzbeefa57c472012-11-21 12:06:18 -08001018 if (rl_dest.fp) {
1019 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetFloat, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001020 } else {
buzbeefa57c472012-11-21 12:06:18 -08001021 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSget, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001022 }
1023 break;
1024 case Instruction::SGET_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -08001025 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetBoolean, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001026 break;
1027 case Instruction::SGET_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001028 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetByte, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001029 break;
1030 case Instruction::SGET_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001031 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetChar, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001032 break;
1033 case Instruction::SGET_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001034 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetShort, rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001035 break;
1036 case Instruction::SGET_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001037 if (rl_dest.fp) {
1038 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetDouble,
1039 rl_dest);
buzbee8fa0fda2012-06-27 15:44:52 -07001040 } else {
buzbeefa57c472012-11-21 12:06:18 -08001041 ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetWide, rl_dest);
buzbee4f1181f2012-06-22 13:52:12 -07001042 }
1043 break;
buzbee2cfc6392012-05-07 14:51:40 -07001044
1045 case Instruction::RETURN_WIDE:
1046 case Instruction::RETURN:
1047 case Instruction::RETURN_OBJECT: {
buzbeefa57c472012-11-21 12:06:18 -08001048 if (!(cu->attrs & METHOD_IS_LEAF)) {
1049 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -07001050 }
buzbeefa57c472012-11-21 12:06:18 -08001051 EmitPopShadowFrame(cu);
1052 cu->irb->CreateRet(GetLLVMValue(cu, rl_src[0].orig_sreg));
1053 bb->has_return = true;
buzbee2cfc6392012-05-07 14:51:40 -07001054 }
1055 break;
1056
1057 case Instruction::RETURN_VOID: {
buzbeefa57c472012-11-21 12:06:18 -08001058 if (!(cu->attrs & METHOD_IS_LEAF)) {
1059 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -07001060 }
buzbeefa57c472012-11-21 12:06:18 -08001061 EmitPopShadowFrame(cu);
1062 cu->irb->CreateRetVoid();
1063 bb->has_return = true;
buzbee2cfc6392012-05-07 14:51:40 -07001064 }
1065 break;
1066
1067 case Instruction::IF_EQ:
buzbeefa57c472012-11-21 12:06:18 -08001068 ConvertCompareAndBranch(cu, bb, mir, kCondEq, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001069 break;
1070 case Instruction::IF_NE:
buzbeefa57c472012-11-21 12:06:18 -08001071 ConvertCompareAndBranch(cu, bb, mir, kCondNe, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001072 break;
1073 case Instruction::IF_LT:
buzbeefa57c472012-11-21 12:06:18 -08001074 ConvertCompareAndBranch(cu, bb, mir, kCondLt, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001075 break;
1076 case Instruction::IF_GE:
buzbeefa57c472012-11-21 12:06:18 -08001077 ConvertCompareAndBranch(cu, bb, mir, kCondGe, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001078 break;
1079 case Instruction::IF_GT:
buzbeefa57c472012-11-21 12:06:18 -08001080 ConvertCompareAndBranch(cu, bb, mir, kCondGt, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001081 break;
1082 case Instruction::IF_LE:
buzbeefa57c472012-11-21 12:06:18 -08001083 ConvertCompareAndBranch(cu, bb, mir, kCondLe, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001084 break;
1085 case Instruction::IF_EQZ:
buzbeefa57c472012-11-21 12:06:18 -08001086 ConvertCompareZeroAndBranch(cu, bb, mir, kCondEq, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001087 break;
1088 case Instruction::IF_NEZ:
buzbeefa57c472012-11-21 12:06:18 -08001089 ConvertCompareZeroAndBranch(cu, bb, mir, kCondNe, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001090 break;
1091 case Instruction::IF_LTZ:
buzbeefa57c472012-11-21 12:06:18 -08001092 ConvertCompareZeroAndBranch(cu, bb, mir, kCondLt, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001093 break;
1094 case Instruction::IF_GEZ:
buzbeefa57c472012-11-21 12:06:18 -08001095 ConvertCompareZeroAndBranch(cu, bb, mir, kCondGe, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001096 break;
1097 case Instruction::IF_GTZ:
buzbeefa57c472012-11-21 12:06:18 -08001098 ConvertCompareZeroAndBranch(cu, bb, mir, kCondGt, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001099 break;
1100 case Instruction::IF_LEZ:
buzbeefa57c472012-11-21 12:06:18 -08001101 ConvertCompareZeroAndBranch(cu, bb, mir, kCondLe, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001102 break;
1103
1104 case Instruction::GOTO:
1105 case Instruction::GOTO_16:
1106 case Instruction::GOTO_32: {
buzbeefa57c472012-11-21 12:06:18 -08001107 if (bb->taken->start_offset <= bb->start_offset) {
1108 EmitSuspendCheck(cu);
buzbee2cfc6392012-05-07 14:51:40 -07001109 }
buzbeefa57c472012-11-21 12:06:18 -08001110 cu->irb->CreateBr(GetLLVMBlock(cu, bb->taken->id));
buzbee2cfc6392012-05-07 14:51:40 -07001111 }
1112 break;
1113
1114 case Instruction::ADD_LONG:
1115 case Instruction::ADD_LONG_2ADDR:
1116 case Instruction::ADD_INT:
1117 case Instruction::ADD_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001118 ConvertArithOp(cu, kOpAdd, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001119 break;
1120 case Instruction::SUB_LONG:
1121 case Instruction::SUB_LONG_2ADDR:
1122 case Instruction::SUB_INT:
1123 case Instruction::SUB_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001124 ConvertArithOp(cu, kOpSub, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001125 break;
1126 case Instruction::MUL_LONG:
1127 case Instruction::MUL_LONG_2ADDR:
1128 case Instruction::MUL_INT:
1129 case Instruction::MUL_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001130 ConvertArithOp(cu, kOpMul, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001131 break;
1132 case Instruction::DIV_LONG:
1133 case Instruction::DIV_LONG_2ADDR:
1134 case Instruction::DIV_INT:
1135 case Instruction::DIV_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001136 ConvertArithOp(cu, kOpDiv, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001137 break;
1138 case Instruction::REM_LONG:
1139 case Instruction::REM_LONG_2ADDR:
1140 case Instruction::REM_INT:
1141 case Instruction::REM_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001142 ConvertArithOp(cu, kOpRem, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001143 break;
1144 case Instruction::AND_LONG:
1145 case Instruction::AND_LONG_2ADDR:
1146 case Instruction::AND_INT:
1147 case Instruction::AND_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001148 ConvertArithOp(cu, kOpAnd, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001149 break;
1150 case Instruction::OR_LONG:
1151 case Instruction::OR_LONG_2ADDR:
1152 case Instruction::OR_INT:
1153 case Instruction::OR_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001154 ConvertArithOp(cu, kOpOr, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001155 break;
1156 case Instruction::XOR_LONG:
1157 case Instruction::XOR_LONG_2ADDR:
1158 case Instruction::XOR_INT:
1159 case Instruction::XOR_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001160 ConvertArithOp(cu, kOpXor, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001161 break;
1162 case Instruction::SHL_LONG:
1163 case Instruction::SHL_LONG_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001164 ConvertShift(cu, greenland::IntrinsicHelper::SHLLong,
1165 rl_dest, rl_src[0], rl_src[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001166 break;
buzbee2cfc6392012-05-07 14:51:40 -07001167 case Instruction::SHL_INT:
1168 case Instruction::SHL_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001169 ConvertShift(cu, greenland::IntrinsicHelper::SHLInt,
1170 rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001171 break;
1172 case Instruction::SHR_LONG:
1173 case Instruction::SHR_LONG_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001174 ConvertShift(cu, greenland::IntrinsicHelper::SHRLong,
1175 rl_dest, rl_src[0], rl_src[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001176 break;
buzbee2cfc6392012-05-07 14:51:40 -07001177 case Instruction::SHR_INT:
1178 case Instruction::SHR_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001179 ConvertShift(cu, greenland::IntrinsicHelper::SHRInt,
1180 rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001181 break;
1182 case Instruction::USHR_LONG:
1183 case Instruction::USHR_LONG_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001184 ConvertShift(cu, greenland::IntrinsicHelper::USHRLong,
1185 rl_dest, rl_src[0], rl_src[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001186 break;
buzbee2cfc6392012-05-07 14:51:40 -07001187 case Instruction::USHR_INT:
1188 case Instruction::USHR_INT_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001189 ConvertShift(cu, greenland::IntrinsicHelper::USHRInt,
1190 rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001191 break;
1192
1193 case Instruction::ADD_INT_LIT16:
1194 case Instruction::ADD_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001195 ConvertArithOpLit(cu, kOpAdd, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001196 break;
1197 case Instruction::RSUB_INT:
1198 case Instruction::RSUB_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001199 ConvertArithOpLit(cu, kOpRsub, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001200 break;
1201 case Instruction::MUL_INT_LIT16:
1202 case Instruction::MUL_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001203 ConvertArithOpLit(cu, kOpMul, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001204 break;
1205 case Instruction::DIV_INT_LIT16:
1206 case Instruction::DIV_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001207 ConvertArithOpLit(cu, kOpDiv, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001208 break;
1209 case Instruction::REM_INT_LIT16:
1210 case Instruction::REM_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001211 ConvertArithOpLit(cu, kOpRem, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001212 break;
1213 case Instruction::AND_INT_LIT16:
1214 case Instruction::AND_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001215 ConvertArithOpLit(cu, kOpAnd, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001216 break;
1217 case Instruction::OR_INT_LIT16:
1218 case Instruction::OR_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001219 ConvertArithOpLit(cu, kOpOr, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001220 break;
1221 case Instruction::XOR_INT_LIT16:
1222 case Instruction::XOR_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001223 ConvertArithOpLit(cu, kOpXor, rl_dest, rl_src[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001224 break;
1225 case Instruction::SHL_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001226 ConvertShiftLit(cu, greenland::IntrinsicHelper::SHLInt,
1227 rl_dest, rl_src[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001228 break;
1229 case Instruction::SHR_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001230 ConvertShiftLit(cu, greenland::IntrinsicHelper::SHRInt,
1231 rl_dest, rl_src[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001232 break;
1233 case Instruction::USHR_INT_LIT8:
buzbeefa57c472012-11-21 12:06:18 -08001234 ConvertShiftLit(cu, greenland::IntrinsicHelper::USHRInt,
1235 rl_dest, rl_src[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001236 break;
1237
1238 case Instruction::ADD_FLOAT:
1239 case Instruction::ADD_FLOAT_2ADDR:
1240 case Instruction::ADD_DOUBLE:
1241 case Instruction::ADD_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001242 ConvertFPArithOp(cu, kOpAdd, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001243 break;
1244
1245 case Instruction::SUB_FLOAT:
1246 case Instruction::SUB_FLOAT_2ADDR:
1247 case Instruction::SUB_DOUBLE:
1248 case Instruction::SUB_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001249 ConvertFPArithOp(cu, kOpSub, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001250 break;
1251
1252 case Instruction::MUL_FLOAT:
1253 case Instruction::MUL_FLOAT_2ADDR:
1254 case Instruction::MUL_DOUBLE:
1255 case Instruction::MUL_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001256 ConvertFPArithOp(cu, kOpMul, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001257 break;
1258
1259 case Instruction::DIV_FLOAT:
1260 case Instruction::DIV_FLOAT_2ADDR:
1261 case Instruction::DIV_DOUBLE:
1262 case Instruction::DIV_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001263 ConvertFPArithOp(cu, kOpDiv, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001264 break;
1265
1266 case Instruction::REM_FLOAT:
1267 case Instruction::REM_FLOAT_2ADDR:
1268 case Instruction::REM_DOUBLE:
1269 case Instruction::REM_DOUBLE_2ADDR:
buzbeefa57c472012-11-21 12:06:18 -08001270 ConvertFPArithOp(cu, kOpRem, rl_dest, rl_src[0], rl_src[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001271 break;
1272
buzbee6969d502012-06-15 16:40:31 -07001273 case Instruction::INVOKE_STATIC:
buzbeefa57c472012-11-21 12:06:18 -08001274 ConvertInvoke(cu, bb, mir, kStatic, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001275 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001276 break;
1277 case Instruction::INVOKE_STATIC_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001278 ConvertInvoke(cu, bb, mir, kStatic, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001279 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001280 break;
1281
1282 case Instruction::INVOKE_DIRECT:
buzbeefa57c472012-11-21 12:06:18 -08001283 ConvertInvoke(cu, bb, mir, kDirect, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001284 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001285 break;
1286 case Instruction::INVOKE_DIRECT_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001287 ConvertInvoke(cu, bb, mir, kDirect, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001288 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001289 break;
1290
1291 case Instruction::INVOKE_VIRTUAL:
buzbeefa57c472012-11-21 12:06:18 -08001292 ConvertInvoke(cu, bb, mir, kVirtual, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001293 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001294 break;
1295 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001296 ConvertInvoke(cu, bb, mir, kVirtual, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001297 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001298 break;
1299
1300 case Instruction::INVOKE_SUPER:
buzbeefa57c472012-11-21 12:06:18 -08001301 ConvertInvoke(cu, bb, mir, kSuper, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001302 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001303 break;
1304 case Instruction::INVOKE_SUPER_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001305 ConvertInvoke(cu, bb, mir, kSuper, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001306 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001307 break;
1308
1309 case Instruction::INVOKE_INTERFACE:
buzbeefa57c472012-11-21 12:06:18 -08001310 ConvertInvoke(cu, bb, mir, kInterface, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001311 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001312 break;
1313 case Instruction::INVOKE_INTERFACE_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001314 ConvertInvoke(cu, bb, mir, kInterface, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001315 false /* NewFilledArray */);
1316 break;
1317 case Instruction::FILLED_NEW_ARRAY:
buzbeefa57c472012-11-21 12:06:18 -08001318 ConvertInvoke(cu, bb, mir, kInterface, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001319 true /* NewFilledArray */);
1320 break;
1321 case Instruction::FILLED_NEW_ARRAY_RANGE:
buzbeefa57c472012-11-21 12:06:18 -08001322 ConvertInvoke(cu, bb, mir, kInterface, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001323 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001324 break;
1325
1326 case Instruction::CONST_STRING:
1327 case Instruction::CONST_STRING_JUMBO:
buzbeefa57c472012-11-21 12:06:18 -08001328 ConvertConstObject(cu, vB, greenland::IntrinsicHelper::ConstString,
1329 rl_dest);
buzbee101305f2012-06-28 18:00:56 -07001330 break;
1331
1332 case Instruction::CONST_CLASS:
buzbeefa57c472012-11-21 12:06:18 -08001333 ConvertConstObject(cu, vB, greenland::IntrinsicHelper::ConstClass,
1334 rl_dest);
buzbee101305f2012-06-28 18:00:56 -07001335 break;
1336
1337 case Instruction::CHECK_CAST:
buzbeefa57c472012-11-21 12:06:18 -08001338 ConvertCheckCast(cu, vB, rl_src[0]);
buzbee6969d502012-06-15 16:40:31 -07001339 break;
1340
buzbee4f1181f2012-06-22 13:52:12 -07001341 case Instruction::NEW_INSTANCE:
buzbeefa57c472012-11-21 12:06:18 -08001342 ConvertNewInstance(cu, vB, rl_dest);
buzbee4f1181f2012-06-22 13:52:12 -07001343 break;
1344
buzbee32412962012-06-26 16:27:56 -07001345 case Instruction::MOVE_EXCEPTION:
buzbeefa57c472012-11-21 12:06:18 -08001346 ConvertMoveException(cu, rl_dest);
buzbee32412962012-06-26 16:27:56 -07001347 break;
1348
1349 case Instruction::THROW:
buzbeefa57c472012-11-21 12:06:18 -08001350 ConvertThrow(cu, rl_src[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001351 /*
1352 * If this throw is standalone, terminate.
1353 * If it might rethrow, force termination
1354 * of the following block.
1355 */
buzbeefa57c472012-11-21 12:06:18 -08001356 if (bb->fall_through == NULL) {
1357 cu->irb->CreateUnreachable();
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001358 } else {
buzbeefa57c472012-11-21 12:06:18 -08001359 bb->fall_through->fall_through = NULL;
1360 bb->fall_through->taken = NULL;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001361 }
buzbee32412962012-06-26 16:27:56 -07001362 break;
1363
buzbee2cfc6392012-05-07 14:51:40 -07001364 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001365 case Instruction::MOVE_RESULT:
1366 case Instruction::MOVE_RESULT_OBJECT:
buzbee9a2487f2012-07-26 14:01:13 -07001367 /*
jeffhao9a4f0032012-08-30 16:17:40 -07001368 * All move_results should have been folded into the preceeding invoke.
buzbee9a2487f2012-07-26 14:01:13 -07001369 */
jeffhao9a4f0032012-08-30 16:17:40 -07001370 LOG(FATAL) << "Unexpected move_result";
buzbee2cfc6392012-05-07 14:51:40 -07001371 break;
1372
1373 case Instruction::MONITOR_ENTER:
buzbeefa57c472012-11-21 12:06:18 -08001374 ConvertMonitorEnterExit(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001375 greenland::IntrinsicHelper::MonitorEnter,
buzbeefa57c472012-11-21 12:06:18 -08001376 rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001377 break;
1378
1379 case Instruction::MONITOR_EXIT:
buzbeefa57c472012-11-21 12:06:18 -08001380 ConvertMonitorEnterExit(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001381 greenland::IntrinsicHelper::MonitorExit,
buzbeefa57c472012-11-21 12:06:18 -08001382 rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001383 break;
1384
1385 case Instruction::ARRAY_LENGTH:
buzbeefa57c472012-11-21 12:06:18 -08001386 ConvertArrayLength(cu, opt_flags, rl_dest, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001387 break;
1388
1389 case Instruction::NEW_ARRAY:
buzbeefa57c472012-11-21 12:06:18 -08001390 ConvertNewArray(cu, vC, rl_dest, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001391 break;
1392
1393 case Instruction::INSTANCE_OF:
buzbeefa57c472012-11-21 12:06:18 -08001394 ConvertInstanceOf(cu, vC, rl_dest, rl_src[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001395 break;
1396
1397 case Instruction::AGET:
buzbeefa57c472012-11-21 12:06:18 -08001398 if (rl_dest.fp) {
1399 ConvertAget(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001400 greenland::IntrinsicHelper::HLArrayGetFloat,
buzbeefa57c472012-11-21 12:06:18 -08001401 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001402 } else {
buzbeefa57c472012-11-21 12:06:18 -08001403 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGet,
1404 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001405 }
1406 break;
1407 case Instruction::AGET_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -08001408 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetObject,
1409 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001410 break;
1411 case Instruction::AGET_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -08001412 ConvertAget(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001413 greenland::IntrinsicHelper::HLArrayGetBoolean,
buzbeefa57c472012-11-21 12:06:18 -08001414 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001415 break;
1416 case Instruction::AGET_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001417 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetByte,
1418 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001419 break;
1420 case Instruction::AGET_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001421 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetChar,
1422 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001423 break;
1424 case Instruction::AGET_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001425 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetShort,
1426 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001427 break;
1428 case Instruction::AGET_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001429 if (rl_dest.fp) {
1430 ConvertAget(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001431 greenland::IntrinsicHelper::HLArrayGetDouble,
buzbeefa57c472012-11-21 12:06:18 -08001432 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001433 } else {
buzbeefa57c472012-11-21 12:06:18 -08001434 ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetWide,
1435 rl_dest, rl_src[0], rl_src[1]);
buzbee8fa0fda2012-06-27 15:44:52 -07001436 }
1437 break;
1438
1439 case Instruction::APUT:
buzbeefa57c472012-11-21 12:06:18 -08001440 if (rl_src[0].fp) {
1441 ConvertAput(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001442 greenland::IntrinsicHelper::HLArrayPutFloat,
buzbeefa57c472012-11-21 12:06:18 -08001443 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001444 } else {
buzbeefa57c472012-11-21 12:06:18 -08001445 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPut,
1446 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001447 }
1448 break;
1449 case Instruction::APUT_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -08001450 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutObject,
1451 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001452 break;
1453 case Instruction::APUT_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -08001454 ConvertAput(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001455 greenland::IntrinsicHelper::HLArrayPutBoolean,
buzbeefa57c472012-11-21 12:06:18 -08001456 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001457 break;
1458 case Instruction::APUT_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001459 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutByte,
1460 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001461 break;
1462 case Instruction::APUT_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001463 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutChar,
1464 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001465 break;
1466 case Instruction::APUT_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001467 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutShort,
1468 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001469 break;
1470 case Instruction::APUT_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001471 if (rl_src[0].fp) {
1472 ConvertAput(cu, opt_flags,
buzbee8fa0fda2012-06-27 15:44:52 -07001473 greenland::IntrinsicHelper::HLArrayPutDouble,
buzbeefa57c472012-11-21 12:06:18 -08001474 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001475 } else {
buzbeefa57c472012-11-21 12:06:18 -08001476 ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutWide,
1477 rl_src[0], rl_src[1], rl_src[2]);
buzbee8fa0fda2012-06-27 15:44:52 -07001478 }
1479 break;
1480
buzbee101305f2012-06-28 18:00:56 -07001481 case Instruction::IGET:
buzbeefa57c472012-11-21 12:06:18 -08001482 if (rl_dest.fp) {
1483 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetFloat,
1484 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001485 } else {
buzbeefa57c472012-11-21 12:06:18 -08001486 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGet,
1487 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001488 }
buzbee2cfc6392012-05-07 14:51:40 -07001489 break;
buzbee101305f2012-06-28 18:00:56 -07001490 case Instruction::IGET_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -08001491 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetObject,
1492 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001493 break;
1494 case Instruction::IGET_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -08001495 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetBoolean,
1496 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001497 break;
1498 case Instruction::IGET_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001499 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetByte,
1500 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001501 break;
1502 case Instruction::IGET_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001503 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetChar,
1504 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001505 break;
1506 case Instruction::IGET_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001507 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetShort,
1508 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001509 break;
1510 case Instruction::IGET_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001511 if (rl_dest.fp) {
1512 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetDouble,
1513 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001514 } else {
buzbeefa57c472012-11-21 12:06:18 -08001515 ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetWide,
1516 rl_dest, rl_src[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001517 }
1518 break;
1519 case Instruction::IPUT:
buzbeefa57c472012-11-21 12:06:18 -08001520 if (rl_src[0].fp) {
1521 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutFloat,
1522 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001523 } else {
buzbeefa57c472012-11-21 12:06:18 -08001524 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPut,
1525 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001526 }
1527 break;
1528 case Instruction::IPUT_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -08001529 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutObject,
1530 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001531 break;
1532 case Instruction::IPUT_BOOLEAN:
buzbeefa57c472012-11-21 12:06:18 -08001533 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutBoolean,
1534 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001535 break;
1536 case Instruction::IPUT_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001537 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutByte,
1538 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001539 break;
1540 case Instruction::IPUT_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001541 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutChar,
1542 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001543 break;
1544 case Instruction::IPUT_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001545 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutShort,
1546 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001547 break;
1548 case Instruction::IPUT_WIDE:
buzbeefa57c472012-11-21 12:06:18 -08001549 if (rl_src[0].fp) {
1550 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutDouble,
1551 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001552 } else {
buzbeefa57c472012-11-21 12:06:18 -08001553 ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutWide,
1554 rl_src[0], rl_src[1], vC);
buzbee101305f2012-06-28 18:00:56 -07001555 }
buzbee2cfc6392012-05-07 14:51:40 -07001556 break;
1557
1558 case Instruction::FILL_ARRAY_DATA:
buzbeefa57c472012-11-21 12:06:18 -08001559 ConvertFillArrayData(cu, vB, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001560 break;
1561
buzbee76592632012-06-29 15:18:35 -07001562 case Instruction::LONG_TO_INT:
buzbeefa57c472012-11-21 12:06:18 -08001563 ConvertLongToInt(cu, rl_dest, rl_src[0]);
buzbee76592632012-06-29 15:18:35 -07001564 break;
1565
buzbee101305f2012-06-28 18:00:56 -07001566 case Instruction::INT_TO_LONG:
buzbeefa57c472012-11-21 12:06:18 -08001567 ConvertIntToLong(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001568 break;
1569
buzbee101305f2012-06-28 18:00:56 -07001570 case Instruction::INT_TO_CHAR:
buzbeefa57c472012-11-21 12:06:18 -08001571 ConvertIntNarrowing(cu, rl_dest, rl_src[0],
buzbee101305f2012-06-28 18:00:56 -07001572 greenland::IntrinsicHelper::IntToChar);
1573 break;
1574 case Instruction::INT_TO_BYTE:
buzbeefa57c472012-11-21 12:06:18 -08001575 ConvertIntNarrowing(cu, rl_dest, rl_src[0],
buzbee101305f2012-06-28 18:00:56 -07001576 greenland::IntrinsicHelper::IntToByte);
1577 break;
1578 case Instruction::INT_TO_SHORT:
buzbeefa57c472012-11-21 12:06:18 -08001579 ConvertIntNarrowing(cu, rl_dest, rl_src[0],
buzbee101305f2012-06-28 18:00:56 -07001580 greenland::IntrinsicHelper::IntToShort);
1581 break;
1582
buzbee76592632012-06-29 15:18:35 -07001583 case Instruction::INT_TO_FLOAT:
1584 case Instruction::LONG_TO_FLOAT:
buzbeefa57c472012-11-21 12:06:18 -08001585 ConvertIntToFP(cu, cu->irb->getFloatTy(), rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001586 break;
1587
buzbee76592632012-06-29 15:18:35 -07001588 case Instruction::INT_TO_DOUBLE:
1589 case Instruction::LONG_TO_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001590 ConvertIntToFP(cu, cu->irb->getDoubleTy(), rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001591 break;
1592
buzbee76592632012-06-29 15:18:35 -07001593 case Instruction::FLOAT_TO_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001594 ConvertFloatToDouble(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001595 break;
1596
buzbee76592632012-06-29 15:18:35 -07001597 case Instruction::DOUBLE_TO_FLOAT:
buzbeefa57c472012-11-21 12:06:18 -08001598 ConvertDoubleToFloat(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001599 break;
1600
1601 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001602 case Instruction::NEG_INT:
buzbeefa57c472012-11-21 12:06:18 -08001603 ConvertNeg(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001604 break;
1605
1606 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001607 case Instruction::NEG_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001608 ConvertNegFP(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001609 break;
1610
buzbee76592632012-06-29 15:18:35 -07001611 case Instruction::NOT_LONG:
1612 case Instruction::NOT_INT:
buzbeefa57c472012-11-21 12:06:18 -08001613 ConvertNot(cu, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001614 break;
1615
buzbee2cfc6392012-05-07 14:51:40 -07001616 case Instruction::FLOAT_TO_INT:
buzbeefa57c472012-11-21 12:06:18 -08001617 ConvertFPToInt(cu, greenland::IntrinsicHelper::F2I, rl_dest, rl_src[0]);
TDYa1274ec8ccd2012-08-11 07:04:57 -07001618 break;
1619
buzbee2cfc6392012-05-07 14:51:40 -07001620 case Instruction::DOUBLE_TO_INT:
buzbeefa57c472012-11-21 12:06:18 -08001621 ConvertFPToInt(cu, greenland::IntrinsicHelper::D2I, rl_dest, rl_src[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001622 break;
1623
buzbee76592632012-06-29 15:18:35 -07001624 case Instruction::FLOAT_TO_LONG:
buzbeefa57c472012-11-21 12:06:18 -08001625 ConvertFPToInt(cu, greenland::IntrinsicHelper::F2L, rl_dest, rl_src[0]);
TDYa1274ec8ccd2012-08-11 07:04:57 -07001626 break;
1627
buzbee76592632012-06-29 15:18:35 -07001628 case Instruction::DOUBLE_TO_LONG:
buzbeefa57c472012-11-21 12:06:18 -08001629 ConvertFPToInt(cu, greenland::IntrinsicHelper::D2L, rl_dest, rl_src[0]);
buzbee76592632012-06-29 15:18:35 -07001630 break;
1631
1632 case Instruction::CMPL_FLOAT:
buzbeefa57c472012-11-21 12:06:18 -08001633 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmplFloat,
1634 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001635 break;
1636 case Instruction::CMPG_FLOAT:
buzbeefa57c472012-11-21 12:06:18 -08001637 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmpgFloat,
1638 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001639 break;
1640 case Instruction::CMPL_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001641 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmplDouble,
1642 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001643 break;
1644 case Instruction::CMPG_DOUBLE:
buzbeefa57c472012-11-21 12:06:18 -08001645 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmpgDouble,
1646 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001647 break;
1648 case Instruction::CMP_LONG:
buzbeefa57c472012-11-21 12:06:18 -08001649 ConvertWideComparison(cu, greenland::IntrinsicHelper::CmpLong,
1650 rl_dest, rl_src[0], rl_src[1]);
buzbee76592632012-06-29 15:18:35 -07001651 break;
1652
buzbee76592632012-06-29 15:18:35 -07001653 case Instruction::PACKED_SWITCH:
buzbeefa57c472012-11-21 12:06:18 -08001654 ConvertPackedSwitch(cu, bb, vB, rl_src[0]);
buzbee76592632012-06-29 15:18:35 -07001655 break;
1656
1657 case Instruction::SPARSE_SWITCH:
buzbeefa57c472012-11-21 12:06:18 -08001658 ConvertSparseSwitch(cu, bb, vB, rl_src[0]);
buzbee76592632012-06-29 15:18:35 -07001659 break;
buzbee2cfc6392012-05-07 14:51:40 -07001660
1661 default:
buzbee32412962012-06-26 16:27:56 -07001662 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001663 res = true;
1664 }
buzbeefa57c472012-11-21 12:06:18 -08001665 if (object_definition) {
1666 SetShadowFrameEntry(cu, reinterpret_cast<llvm::Value*>
1667 (cu->llvm_values.elem_list[rl_dest.orig_sreg]));
buzbeeb03f4872012-06-11 15:22:11 -07001668 }
buzbee2cfc6392012-05-07 14:51:40 -07001669 return res;
1670}
1671
1672/* Extended MIR instructions like PHI */
buzbeefa57c472012-11-21 12:06:18 -08001673static void ConvertExtendedMIR(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
1674 llvm::BasicBlock* llvm_bb)
buzbee2cfc6392012-05-07 14:51:40 -07001675{
1676
buzbeecbd6d442012-11-17 14:11:25 -08001677 switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) {
buzbee2cfc6392012-05-07 14:51:40 -07001678 case kMirOpPhi: {
buzbeefa57c472012-11-21 12:06:18 -08001679 RegLocation rl_dest = cu->reg_location[mir->ssa_rep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001680 /*
1681 * The Art compiler's Phi nodes only handle 32-bit operands,
1682 * representing wide values using a matched set of Phi nodes
1683 * for the lower and upper halves. In the llvm world, we only
1684 * want a single Phi for wides. Here we will simply discard
1685 * the Phi node representing the high word.
1686 */
buzbeefa57c472012-11-21 12:06:18 -08001687 if (rl_dest.high_word) {
buzbee2a83e8f2012-07-13 16:42:30 -07001688 return; // No Phi node - handled via low word
1689 }
buzbeecbd6d442012-11-17 14:11:25 -08001690 int* incoming = reinterpret_cast<int*>(mir->dalvikInsn.vB);
buzbeefa57c472012-11-21 12:06:18 -08001691 llvm::Type* phi_type =
1692 LlvmTypeFromLocRec(cu, rl_dest);
1693 llvm::PHINode* phi = cu->irb->CreatePHI(phi_type, mir->ssa_rep->num_uses);
1694 for (int i = 0; i < mir->ssa_rep->num_uses; i++) {
buzbee2cfc6392012-05-07 14:51:40 -07001695 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001696 // Don't check width here.
buzbeefa57c472012-11-21 12:06:18 -08001697 loc = GetRawSrc(cu, mir, i);
1698 DCHECK_EQ(rl_dest.wide, loc.wide);
1699 DCHECK_EQ(rl_dest.wide & rl_dest.high_word, loc.wide & loc.high_word);
1700 DCHECK_EQ(rl_dest.fp, loc.fp);
1701 DCHECK_EQ(rl_dest.core, loc.core);
1702 DCHECK_EQ(rl_dest.ref, loc.ref);
buzbeed1643e42012-09-05 14:06:51 -07001703 SafeMap<unsigned int, unsigned int>::iterator it;
buzbeefa57c472012-11-21 12:06:18 -08001704 it = cu->block_id_map.find(incoming[i]);
1705 DCHECK(it != cu->block_id_map.end());
1706 phi->addIncoming(GetLLVMValue(cu, loc.orig_sreg),
1707 GetLLVMBlock(cu, it->second));
buzbee2cfc6392012-05-07 14:51:40 -07001708 }
buzbeefa57c472012-11-21 12:06:18 -08001709 DefineValue(cu, phi, rl_dest.orig_sreg);
buzbee2cfc6392012-05-07 14:51:40 -07001710 break;
1711 }
1712 case kMirOpCopy: {
1713 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1714 break;
1715 }
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001716 case kMirOpNop:
buzbeefa57c472012-11-21 12:06:18 -08001717 if ((mir == bb->last_mir_insn) && (bb->taken == NULL) &&
1718 (bb->fall_through == NULL)) {
1719 cu->irb->CreateUnreachable();
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001720 }
1721 break;
1722
buzbeeb046e162012-10-30 15:48:42 -07001723 // TODO: need GBC intrinsic to take advantage of fused operations
buzbee2cfc6392012-05-07 14:51:40 -07001724 case kMirOpFusedCmplFloat:
buzbeeb046e162012-10-30 15:48:42 -07001725 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpFloat unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001726 break;
1727 case kMirOpFusedCmpgFloat:
buzbeeb046e162012-10-30 15:48:42 -07001728 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmgFloat unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001729 break;
1730 case kMirOpFusedCmplDouble:
buzbeeb046e162012-10-30 15:48:42 -07001731 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmplDouble unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001732 break;
1733 case kMirOpFusedCmpgDouble:
buzbeeb046e162012-10-30 15:48:42 -07001734 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpgDouble unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001735 break;
1736 case kMirOpFusedCmpLong:
buzbeeb046e162012-10-30 15:48:42 -07001737 UNIMPLEMENTED(FATAL) << "kMirOpLongCmpBranch unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001738 break;
buzbee2cfc6392012-05-07 14:51:40 -07001739 default:
1740 break;
1741 }
1742}
1743
buzbeefa57c472012-11-21 12:06:18 -08001744static void SetDexOffset(CompilationUnit* cu, int32_t offset)
buzbee2cfc6392012-05-07 14:51:40 -07001745{
buzbeefa57c472012-11-21 12:06:18 -08001746 cu->current_dalvik_offset = offset;
1747 llvm::SmallVector<llvm::Value*, 1> array_ref;
1748 array_ref.push_back(cu->irb->getInt32(offset));
1749 llvm::MDNode* node = llvm::MDNode::get(*cu->context, array_ref);
1750 cu->irb->SetDexOffset(node);
buzbee2cfc6392012-05-07 14:51:40 -07001751}
1752
1753// Attach method info as metadata to special intrinsic
buzbeefa57c472012-11-21 12:06:18 -08001754static void SetMethodInfo(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -07001755{
1756 // We don't want dex offset on this
buzbeefa57c472012-11-21 12:06:18 -08001757 cu->irb->SetDexOffset(NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001758 greenland::IntrinsicHelper::IntrinsicId id;
1759 id = greenland::IntrinsicHelper::MethodInfo;
buzbeefa57c472012-11-21 12:06:18 -08001760 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
1761 llvm::Instruction* inst = cu->irb->CreateCall(intr);
1762 llvm::SmallVector<llvm::Value*, 2> reg_info;
1763 reg_info.push_back(cu->irb->getInt32(cu->num_ins));
1764 reg_info.push_back(cu->irb->getInt32(cu->num_regs));
1765 reg_info.push_back(cu->irb->getInt32(cu->num_outs));
1766 reg_info.push_back(cu->irb->getInt32(cu->num_compiler_temps));
1767 reg_info.push_back(cu->irb->getInt32(cu->num_ssa_regs));
1768 llvm::MDNode* reg_info_node = llvm::MDNode::get(*cu->context, reg_info);
1769 inst->setMetadata("RegInfo", reg_info_node);
1770 int promo_size = cu->num_dalvik_registers + cu->num_compiler_temps + 1;
buzbee2cfc6392012-05-07 14:51:40 -07001771 llvm::SmallVector<llvm::Value*, 50> pmap;
buzbeefa57c472012-11-21 12:06:18 -08001772 for (int i = 0; i < promo_size; i++) {
1773 PromotionMap* p = &cu->promotion_map[i];
1774 int32_t map_data = ((p->first_in_pair & 0xff) << 24) |
buzbee52a77fc2012-11-20 19:50:46 -08001775 ((p->FpReg & 0xff) << 16) |
buzbeefa57c472012-11-21 12:06:18 -08001776 ((p->core_reg & 0xff) << 8) |
1777 ((p->fp_location & 0xf) << 4) |
1778 (p->core_location & 0xf);
1779 pmap.push_back(cu->irb->getInt32(map_data));
buzbee2cfc6392012-05-07 14:51:40 -07001780 }
buzbeefa57c472012-11-21 12:06:18 -08001781 llvm::MDNode* map_node = llvm::MDNode::get(*cu->context, pmap);
1782 inst->setMetadata("PromotionMap", map_node);
1783 SetDexOffset(cu, cu->current_dalvik_offset);
buzbee2cfc6392012-05-07 14:51:40 -07001784}
1785
1786/* Handle the content in each basic block */
buzbeefa57c472012-11-21 12:06:18 -08001787static bool BlockBitcodeConversion(CompilationUnit* cu, BasicBlock* bb)
buzbee2cfc6392012-05-07 14:51:40 -07001788{
buzbeefa57c472012-11-21 12:06:18 -08001789 if (bb->block_type == kDead) return false;
1790 llvm::BasicBlock* llvm_bb = GetLLVMBlock(cu, bb->id);
1791 if (llvm_bb == NULL) {
1792 CHECK(bb->block_type == kExitBlock);
buzbeef5f5a122012-09-21 13:57:36 -07001793 } else {
buzbeefa57c472012-11-21 12:06:18 -08001794 cu->irb->SetInsertPoint(llvm_bb);
1795 SetDexOffset(cu, bb->start_offset);
buzbeef5f5a122012-09-21 13:57:36 -07001796 }
buzbee2cfc6392012-05-07 14:51:40 -07001797
buzbeefa57c472012-11-21 12:06:18 -08001798 if (cu->verbose) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001799 LOG(INFO) << "................................";
1800 LOG(INFO) << "Block id " << bb->id;
buzbeefa57c472012-11-21 12:06:18 -08001801 if (llvm_bb != NULL) {
1802 LOG(INFO) << "label " << llvm_bb->getName().str().c_str();
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001803 } else {
buzbeefa57c472012-11-21 12:06:18 -08001804 LOG(INFO) << "llvm_bb is NULL";
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001805 }
1806 }
1807
buzbeefa57c472012-11-21 12:06:18 -08001808 if (bb->block_type == kEntryBlock) {
1809 SetMethodInfo(cu);
1810 bool *can_be_ref = static_cast<bool*>(NewMem(cu, sizeof(bool) * cu->num_dalvik_registers,
buzbeecbd6d442012-11-17 14:11:25 -08001811 true, kAllocMisc));
buzbeefa57c472012-11-21 12:06:18 -08001812 for (int i = 0; i < cu->num_ssa_regs; i++) {
1813 int v_reg = SRegToVReg(cu, i);
1814 if (v_reg > SSA_METHOD_BASEREG) {
1815 can_be_ref[SRegToVReg(cu, i)] |= cu->reg_location[i].ref;
buzbee6ec5e232012-09-20 15:50:03 -07001816 }
buzbeeb03f4872012-06-11 15:22:11 -07001817 }
buzbeefa57c472012-11-21 12:06:18 -08001818 for (int i = 0; i < cu->num_dalvik_registers; i++) {
1819 if (can_be_ref[i]) {
1820 cu->num_shadow_frame_entries++;
buzbeeb03f4872012-06-11 15:22:11 -07001821 }
1822 }
buzbeefa57c472012-11-21 12:06:18 -08001823 if (cu->num_shadow_frame_entries > 0) {
1824 cu->shadow_map = static_cast<int*>(NewMem(cu, sizeof(int) * cu->num_shadow_frame_entries,
buzbeecbd6d442012-11-17 14:11:25 -08001825 true, kAllocMisc));
buzbeefa57c472012-11-21 12:06:18 -08001826 for (int i = 0, j = 0; i < cu->num_dalvik_registers; i++) {
1827 if (can_be_ref[i]) {
1828 cu->shadow_map[j++] = i;
buzbeeb03f4872012-06-11 15:22:11 -07001829 }
1830 }
buzbeeb03f4872012-06-11 15:22:11 -07001831 }
Shih-wei Liao569daf12012-08-10 23:22:33 -07001832 greenland::IntrinsicHelper::IntrinsicId id =
1833 greenland::IntrinsicHelper::AllocaShadowFrame;
buzbeefa57c472012-11-21 12:06:18 -08001834 llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id);
1835 llvm::Value* entries = cu->irb->getInt32(cu->num_shadow_frame_entries);
1836 llvm::Value* dalvik_regs = cu->irb->getInt32(cu->num_dalvik_registers);
1837 llvm::Value* args[] = { entries, dalvik_regs };
1838 cu->irb->CreateCall(func, args);
1839 } else if (bb->block_type == kExitBlock) {
buzbee2cfc6392012-05-07 14:51:40 -07001840 /*
1841 * Because of the differences between how MIR/LIR and llvm handle exit
1842 * blocks, we won't explicitly covert them. On the llvm-to-lir
1843 * path, it will need to be regenereated.
1844 */
1845 return false;
buzbeefa57c472012-11-21 12:06:18 -08001846 } else if (bb->block_type == kExceptionHandling) {
buzbee6969d502012-06-15 16:40:31 -07001847 /*
1848 * Because we're deferring null checking, delete the associated empty
1849 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001850 */
buzbeefa57c472012-11-21 12:06:18 -08001851 llvm_bb->eraseFromParent();
buzbee6969d502012-06-15 16:40:31 -07001852 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001853 }
1854
buzbee28c9a832012-11-21 15:39:13 -08001855 for (MIR* mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
buzbee2cfc6392012-05-07 14:51:40 -07001856
buzbeefa57c472012-11-21 12:06:18 -08001857 SetDexOffset(cu, mir->offset);
buzbee2cfc6392012-05-07 14:51:40 -07001858
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001859 int opcode = mir->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -08001860 Instruction::Format dalvik_format =
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001861 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001862
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001863 if (opcode == kMirOpCheck) {
1864 // Combine check and work halves of throwing instruction.
buzbeefa57c472012-11-21 12:06:18 -08001865 MIR* work_half = mir->meta.throw_insn;
1866 mir->dalvikInsn.opcode = work_half->dalvikInsn.opcode;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001867 opcode = mir->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -08001868 SSARepresentation* ssa_rep = work_half->ssa_rep;
1869 work_half->ssa_rep = mir->ssa_rep;
1870 mir->ssa_rep = ssa_rep;
1871 work_half->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1872 if (bb->successor_block_list.block_list_type == kCatch) {
1873 llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001874 greenland::IntrinsicHelper::CatchTargets);
buzbeefa57c472012-11-21 12:06:18 -08001875 llvm::Value* switch_key =
1876 cu->irb->CreateCall(intr, cu->irb->getInt32(mir->offset));
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001877 GrowableListIterator iter;
buzbeefa57c472012-11-21 12:06:18 -08001878 GrowableListIteratorInit(&bb->successor_block_list.blocks, &iter);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001879 // New basic block to use for work half
buzbeefa57c472012-11-21 12:06:18 -08001880 llvm::BasicBlock* work_bb =
1881 llvm::BasicBlock::Create(*cu->context, "", cu->func);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001882 llvm::SwitchInst* sw =
buzbeefa57c472012-11-21 12:06:18 -08001883 cu->irb->CreateSwitch(switch_key, work_bb,
1884 bb->successor_block_list.blocks.num_used);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001885 while (true) {
buzbeefa57c472012-11-21 12:06:18 -08001886 SuccessorBlockInfo *successor_block_info =
buzbee52a77fc2012-11-20 19:50:46 -08001887 reinterpret_cast<SuccessorBlockInfo*>(GrowableListIteratorNext(&iter));
buzbeefa57c472012-11-21 12:06:18 -08001888 if (successor_block_info == NULL) break;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001889 llvm::BasicBlock *target =
buzbeefa57c472012-11-21 12:06:18 -08001890 GetLLVMBlock(cu, successor_block_info->block->id);
1891 int type_index = successor_block_info->key;
1892 sw->addCase(cu->irb->getInt32(type_index), target);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001893 }
buzbeefa57c472012-11-21 12:06:18 -08001894 llvm_bb = work_bb;
1895 cu->irb->SetInsertPoint(llvm_bb);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001896 }
1897 }
1898
1899 if (opcode >= kMirOpFirst) {
buzbeefa57c472012-11-21 12:06:18 -08001900 ConvertExtendedMIR(cu, bb, mir, llvm_bb);
buzbee2cfc6392012-05-07 14:51:40 -07001901 continue;
1902 }
1903
buzbeefa57c472012-11-21 12:06:18 -08001904 bool not_handled = ConvertMIRNode(cu, mir, bb, llvm_bb,
1905 NULL /* label_list */);
1906 if (not_handled) {
1907 Instruction::Code dalvik_opcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001908 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001909 mir->offset, opcode,
buzbeefa57c472012-11-21 12:06:18 -08001910 Instruction::Name(dalvik_opcode),
1911 dalvik_format);
buzbee2cfc6392012-05-07 14:51:40 -07001912 }
1913 }
1914
buzbeefa57c472012-11-21 12:06:18 -08001915 if (bb->block_type == kEntryBlock) {
1916 cu->entryTarget_bb = GetLLVMBlock(cu, bb->fall_through->id);
1917 } else if ((bb->fall_through != NULL) && !bb->has_return) {
1918 cu->irb->CreateBr(GetLLVMBlock(cu, bb->fall_through->id));
buzbee2cfc6392012-05-07 14:51:40 -07001919 }
1920
1921 return false;
1922}
1923
buzbeefa57c472012-11-21 12:06:18 -08001924char RemapShorty(char shorty_type) {
buzbee4f4dfc72012-07-02 14:54:44 -07001925 /*
1926 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1927 * and longs/doubles are represented as a pair of registers. When sub-word
1928 * arguments (and method results) are passed, they are extended to Dalvik
1929 * virtual register containers. Because llvm is picky about type consistency,
1930 * we must either cast the "real" type to 32-bit container multiple Dalvik
1931 * register types, or always use the expanded values.
1932 * Here, we're doing the latter. We map the shorty signature to container
1933 * types (which is valid so long as we always do a real expansion of passed
1934 * arguments and field loads).
1935 */
buzbeefa57c472012-11-21 12:06:18 -08001936 switch(shorty_type) {
1937 case 'Z' : shorty_type = 'I'; break;
1938 case 'B' : shorty_type = 'I'; break;
1939 case 'S' : shorty_type = 'I'; break;
1940 case 'C' : shorty_type = 'I'; break;
buzbee4f4dfc72012-07-02 14:54:44 -07001941 default: break;
1942 }
buzbeefa57c472012-11-21 12:06:18 -08001943 return shorty_type;
buzbee4f4dfc72012-07-02 14:54:44 -07001944}
1945
buzbeefa57c472012-11-21 12:06:18 -08001946static llvm::FunctionType* GetFunctionType(CompilationUnit* cu) {
buzbee2cfc6392012-05-07 14:51:40 -07001947
1948 // Get return type
buzbeefa57c472012-11-21 12:06:18 -08001949 llvm::Type* ret_type = cu->irb->GetJType(RemapShorty(cu->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001950 greenland::kAccurate);
1951
1952 // Get argument type
1953 std::vector<llvm::Type*> args_type;
1954
1955 // method object
buzbeefa57c472012-11-21 12:06:18 -08001956 args_type.push_back(cu->irb->GetJMethodTy());
buzbee2cfc6392012-05-07 14:51:40 -07001957
1958 // Do we have a "this"?
buzbeefa57c472012-11-21 12:06:18 -08001959 if ((cu->access_flags & kAccStatic) == 0) {
1960 args_type.push_back(cu->irb->GetJObjectTy());
buzbee2cfc6392012-05-07 14:51:40 -07001961 }
1962
buzbeefa57c472012-11-21 12:06:18 -08001963 for (uint32_t i = 1; i < strlen(cu->shorty); ++i) {
1964 args_type.push_back(cu->irb->GetJType(RemapShorty(cu->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001965 greenland::kAccurate));
1966 }
1967
1968 return llvm::FunctionType::get(ret_type, args_type, false);
1969}
1970
buzbeefa57c472012-11-21 12:06:18 -08001971static bool CreateFunction(CompilationUnit* cu) {
1972 std::string func_name(PrettyMethod(cu->method_idx, *cu->dex_file,
buzbee2cfc6392012-05-07 14:51:40 -07001973 /* with_signature */ false));
buzbeefa57c472012-11-21 12:06:18 -08001974 llvm::FunctionType* func_type = GetFunctionType(cu);
buzbee2cfc6392012-05-07 14:51:40 -07001975
1976 if (func_type == NULL) {
1977 return false;
1978 }
1979
buzbeefa57c472012-11-21 12:06:18 -08001980 cu->func = llvm::Function::Create(func_type,
buzbee2cfc6392012-05-07 14:51:40 -07001981 llvm::Function::ExternalLinkage,
buzbeefa57c472012-11-21 12:06:18 -08001982 func_name, cu->module);
buzbee2cfc6392012-05-07 14:51:40 -07001983
buzbeefa57c472012-11-21 12:06:18 -08001984 llvm::Function::arg_iterator arg_iter(cu->func->arg_begin());
1985 llvm::Function::arg_iterator arg_end(cu->func->arg_end());
buzbee2cfc6392012-05-07 14:51:40 -07001986
1987 arg_iter->setName("method");
1988 ++arg_iter;
1989
buzbeefa57c472012-11-21 12:06:18 -08001990 int start_sreg = cu->num_regs;
buzbee2cfc6392012-05-07 14:51:40 -07001991
1992 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
buzbeefa57c472012-11-21 12:06:18 -08001993 arg_iter->setName(StringPrintf("v%i_0", start_sreg));
1994 start_sreg += cu->reg_location[start_sreg].wide ? 2 : 1;
buzbee2cfc6392012-05-07 14:51:40 -07001995 }
1996
1997 return true;
1998}
1999
buzbeefa57c472012-11-21 12:06:18 -08002000static bool CreateLLVMBasicBlock(CompilationUnit* cu, BasicBlock* bb)
buzbee2cfc6392012-05-07 14:51:40 -07002001{
2002 // Skip the exit block
buzbeefa57c472012-11-21 12:06:18 -08002003 if ((bb->block_type == kDead) ||(bb->block_type == kExitBlock)) {
2004 cu->id_to_block_map.Put(bb->id, NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002005 } else {
buzbeefa57c472012-11-21 12:06:18 -08002006 int offset = bb->start_offset;
2007 bool entry_block = (bb->block_type == kEntryBlock);
2008 llvm::BasicBlock* llvm_bb =
2009 llvm::BasicBlock::Create(*cu->context, entry_block ? "entry" :
2010 StringPrintf(kLabelFormat, bb->catch_entry ? kCatchBlock :
2011 kNormalBlock, offset, bb->id), cu->func);
2012 if (entry_block) {
2013 cu->entry_bb = llvm_bb;
2014 cu->placeholder_bb =
2015 llvm::BasicBlock::Create(*cu->context, "placeholder",
2016 cu->func);
buzbee2cfc6392012-05-07 14:51:40 -07002017 }
buzbeefa57c472012-11-21 12:06:18 -08002018 cu->id_to_block_map.Put(bb->id, llvm_bb);
buzbee2cfc6392012-05-07 14:51:40 -07002019 }
2020 return false;
2021}
2022
2023
2024/*
2025 * Convert MIR to LLVM_IR
2026 * o For each ssa name, create LLVM named value. Type these
2027 * appropriately, and ignore high half of wide and double operands.
2028 * o For each MIR basic block, create an LLVM basic block.
2029 * o Iterate through the MIR a basic block at a time, setting arguments
2030 * to recovered ssa name.
2031 */
buzbeefa57c472012-11-21 12:06:18 -08002032void MethodMIR2Bitcode(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -07002033{
buzbeefa57c472012-11-21 12:06:18 -08002034 InitIR(cu);
2035 CompilerInitGrowableList(cu, &cu->llvm_values, cu->num_ssa_regs);
buzbee2cfc6392012-05-07 14:51:40 -07002036
2037 // Create the function
buzbeefa57c472012-11-21 12:06:18 -08002038 CreateFunction(cu);
buzbee2cfc6392012-05-07 14:51:40 -07002039
2040 // Create an LLVM basic block for each MIR block in dfs preorder
buzbeefa57c472012-11-21 12:06:18 -08002041 DataFlowAnalysisDispatcher(cu, CreateLLVMBasicBlock,
2042 kPreOrderDFSTraversal, false /* is_iterative */);
buzbee2cfc6392012-05-07 14:51:40 -07002043 /*
2044 * Create an llvm named value for each MIR SSA name. Note: we'll use
2045 * placeholders for all non-argument values (because we haven't seen
2046 * the definition yet).
2047 */
buzbeefa57c472012-11-21 12:06:18 -08002048 cu->irb->SetInsertPoint(cu->placeholder_bb);
2049 llvm::Function::arg_iterator arg_iter(cu->func->arg_begin());
buzbee2cfc6392012-05-07 14:51:40 -07002050 arg_iter++; /* Skip path method */
buzbeefa57c472012-11-21 12:06:18 -08002051 for (int i = 0; i < cu->num_ssa_regs; i++) {
buzbee2cfc6392012-05-07 14:51:40 -07002052 llvm::Value* val;
buzbeefa57c472012-11-21 12:06:18 -08002053 RegLocation rl_temp = cu->reg_location[i];
2054 if ((SRegToVReg(cu, i) < 0) || rl_temp.high_word) {
2055 InsertGrowableList(cu, &cu->llvm_values, 0);
2056 } else if ((i < cu->num_regs) ||
2057 (i >= (cu->num_regs + cu->num_ins))) {
2058 llvm::Constant* imm_value = cu->reg_location[i].wide ?
2059 cu->irb->GetJLong(0) : cu->irb->GetJInt(0);
2060 val = EmitConst(cu, imm_value, cu->reg_location[i]);
2061 val->setName(LlvmSSAName(cu, i));
2062 InsertGrowableList(cu, &cu->llvm_values, reinterpret_cast<uintptr_t>(val));
buzbee2cfc6392012-05-07 14:51:40 -07002063 } else {
2064 // Recover previously-created argument values
buzbeefa57c472012-11-21 12:06:18 -08002065 llvm::Value* arg_val = arg_iter++;
2066 InsertGrowableList(cu, &cu->llvm_values, reinterpret_cast<uintptr_t>(arg_val));
buzbee2cfc6392012-05-07 14:51:40 -07002067 }
2068 }
buzbee2cfc6392012-05-07 14:51:40 -07002069
buzbeefa57c472012-11-21 12:06:18 -08002070 DataFlowAnalysisDispatcher(cu, BlockBitcodeConversion,
buzbee2cfc6392012-05-07 14:51:40 -07002071 kPreOrderDFSTraversal, false /* Iterative */);
2072
buzbee4be777b2012-07-12 14:38:18 -07002073 /*
2074 * In a few rare cases of verification failure, the verifier will
2075 * replace one or more Dalvik opcodes with the special
2076 * throw-verification-failure opcode. This can leave the SSA graph
2077 * in an invalid state, as definitions may be lost, while uses retained.
2078 * To work around this problem, we insert placeholder definitions for
2079 * all Dalvik SSA regs in the "placeholder" block. Here, after
2080 * bitcode conversion is complete, we examine those placeholder definitions
2081 * and delete any with no references (which normally is all of them).
2082 *
2083 * If any definitions remain, we link the placeholder block into the
2084 * CFG. Otherwise, it is deleted.
2085 */
buzbeefa57c472012-11-21 12:06:18 -08002086 for (llvm::BasicBlock::iterator it = cu->placeholder_bb->begin(),
2087 it_end = cu->placeholder_bb->end(); it != it_end;) {
buzbee4be777b2012-07-12 14:38:18 -07002088 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2089 DCHECK(inst != NULL);
2090 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2091 DCHECK(val != NULL);
2092 if (val->getNumUses() == 0) {
2093 inst->eraseFromParent();
2094 }
2095 }
buzbeefa57c472012-11-21 12:06:18 -08002096 SetDexOffset(cu, 0);
2097 if (cu->placeholder_bb->empty()) {
2098 cu->placeholder_bb->eraseFromParent();
buzbee4be777b2012-07-12 14:38:18 -07002099 } else {
buzbeefa57c472012-11-21 12:06:18 -08002100 cu->irb->SetInsertPoint(cu->placeholder_bb);
2101 cu->irb->CreateBr(cu->entryTarget_bb);
2102 cu->entryTarget_bb = cu->placeholder_bb;
buzbee4be777b2012-07-12 14:38:18 -07002103 }
buzbeefa57c472012-11-21 12:06:18 -08002104 cu->irb->SetInsertPoint(cu->entry_bb);
2105 cu->irb->CreateBr(cu->entryTarget_bb);
buzbee2cfc6392012-05-07 14:51:40 -07002106
buzbeefa57c472012-11-21 12:06:18 -08002107 if (cu->enable_debug & (1 << kDebugVerifyBitcode)) {
2108 if (llvm::verifyFunction(*cu->func, llvm::PrintMessageAction)) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002109 LOG(INFO) << "Bitcode verification FAILED for "
buzbeefa57c472012-11-21 12:06:18 -08002110 << PrettyMethod(cu->method_idx, *cu->dex_file)
2111 << " of size " << cu->insns_size;
2112 cu->enable_debug |= (1 << kDebugDumpBitcodeFile);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002113 }
2114 }
buzbee2cfc6392012-05-07 14:51:40 -07002115
buzbeefa57c472012-11-21 12:06:18 -08002116 if (cu->enable_debug & (1 << kDebugDumpBitcodeFile)) {
buzbeead8f15e2012-06-18 14:49:45 -07002117 // Write bitcode to file
2118 std::string errmsg;
buzbeefa57c472012-11-21 12:06:18 -08002119 std::string fname(PrettyMethod(cu->method_idx, *cu->dex_file));
buzbee52a77fc2012-11-20 19:50:46 -08002120 ReplaceSpecialChars(fname);
buzbee6459e7c2012-10-02 14:42:41 -07002121 // TODO: make configurable change naming mechanism to avoid fname length issues.
buzbee4f1181f2012-06-22 13:52:12 -07002122 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002123
buzbee6459e7c2012-10-02 14:42:41 -07002124 if (fname.size() > 240) {
2125 LOG(INFO) << "Warning: bitcode filename too long. Truncated.";
2126 fname.resize(240);
2127 }
2128
buzbeead8f15e2012-06-18 14:49:45 -07002129 llvm::OwningPtr<llvm::tool_output_file> out_file(
2130 new llvm::tool_output_file(fname.c_str(), errmsg,
2131 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002132
buzbeead8f15e2012-06-18 14:49:45 -07002133 if (!errmsg.empty()) {
2134 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2135 }
2136
buzbeefa57c472012-11-21 12:06:18 -08002137 llvm::WriteBitcodeToFile(cu->module, out_file->os());
buzbeead8f15e2012-06-18 14:49:45 -07002138 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002139 }
buzbee2cfc6392012-05-07 14:51:40 -07002140}
2141
buzbeefa57c472012-11-21 12:06:18 -08002142static RegLocation GetLoc(CompilationUnit* cu, llvm::Value* val) {
buzbee2cfc6392012-05-07 14:51:40 -07002143 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002144 DCHECK(val != NULL);
buzbeefa57c472012-11-21 12:06:18 -08002145 SafeMap<llvm::Value*, RegLocation>::iterator it = cu->loc_map.find(val);
2146 if (it == cu->loc_map.end()) {
2147 std::string val_name = val->getName().str();
2148 if (val_name.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002149 // FIXME: need to be more robust, handle FP and be in a position to
2150 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002151 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2152 memset(&res, 0, sizeof(res));
2153 res.location = kLocPhysReg;
buzbeefa57c472012-11-21 12:06:18 -08002154 res.low_reg = AllocTemp(cu);
buzbee4f1181f2012-06-22 13:52:12 -07002155 res.home = true;
buzbeefa57c472012-11-21 12:06:18 -08002156 res.s_reg_low = INVALID_SREG;
2157 res.orig_sreg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002158 llvm::Type* ty = val->getType();
buzbeefa57c472012-11-21 12:06:18 -08002159 res.wide = ((ty == cu->irb->getInt64Ty()) ||
2160 (ty == cu->irb->getDoubleTy()));
buzbee101305f2012-06-28 18:00:56 -07002161 if (res.wide) {
buzbeefa57c472012-11-21 12:06:18 -08002162 res.high_reg = AllocTemp(cu);
buzbee101305f2012-06-28 18:00:56 -07002163 }
buzbeefa57c472012-11-21 12:06:18 -08002164 cu->loc_map.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002165 } else {
buzbeefa57c472012-11-21 12:06:18 -08002166 DCHECK_EQ(val_name[0], 'v');
2167 int base_sreg = INVALID_SREG;
2168 sscanf(val_name.c_str(), "v%d_", &base_sreg);
2169 res = cu->reg_location[base_sreg];
2170 cu->loc_map.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002171 }
2172 } else {
2173 res = it->second;
2174 }
2175 return res;
2176}
2177
buzbeefa57c472012-11-21 12:06:18 -08002178static Instruction::Code GetDalvikOpcode(OpKind op, bool is_const, bool is_wide)
buzbee2cfc6392012-05-07 14:51:40 -07002179{
2180 Instruction::Code res = Instruction::NOP;
buzbeefa57c472012-11-21 12:06:18 -08002181 if (is_wide) {
buzbee2cfc6392012-05-07 14:51:40 -07002182 switch(op) {
2183 case kOpAdd: res = Instruction::ADD_LONG; break;
2184 case kOpSub: res = Instruction::SUB_LONG; break;
2185 case kOpMul: res = Instruction::MUL_LONG; break;
2186 case kOpDiv: res = Instruction::DIV_LONG; break;
2187 case kOpRem: res = Instruction::REM_LONG; break;
2188 case kOpAnd: res = Instruction::AND_LONG; break;
2189 case kOpOr: res = Instruction::OR_LONG; break;
2190 case kOpXor: res = Instruction::XOR_LONG; break;
2191 case kOpLsl: res = Instruction::SHL_LONG; break;
2192 case kOpLsr: res = Instruction::USHR_LONG; break;
2193 case kOpAsr: res = Instruction::SHR_LONG; break;
2194 default: LOG(FATAL) << "Unexpected OpKind " << op;
2195 }
buzbeefa57c472012-11-21 12:06:18 -08002196 } else if (is_const){
buzbee2cfc6392012-05-07 14:51:40 -07002197 switch(op) {
2198 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2199 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2200 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2201 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2202 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2203 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2204 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2205 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2206 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2207 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2208 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2209 default: LOG(FATAL) << "Unexpected OpKind " << op;
2210 }
2211 } else {
2212 switch(op) {
2213 case kOpAdd: res = Instruction::ADD_INT; break;
2214 case kOpSub: res = Instruction::SUB_INT; break;
2215 case kOpMul: res = Instruction::MUL_INT; break;
2216 case kOpDiv: res = Instruction::DIV_INT; break;
2217 case kOpRem: res = Instruction::REM_INT; break;
2218 case kOpAnd: res = Instruction::AND_INT; break;
2219 case kOpOr: res = Instruction::OR_INT; break;
2220 case kOpXor: res = Instruction::XOR_INT; break;
2221 case kOpLsl: res = Instruction::SHL_INT; break;
2222 case kOpLsr: res = Instruction::USHR_INT; break;
2223 case kOpAsr: res = Instruction::SHR_INT; break;
2224 default: LOG(FATAL) << "Unexpected OpKind " << op;
2225 }
2226 }
2227 return res;
2228}
2229
buzbeefa57c472012-11-21 12:06:18 -08002230static Instruction::Code GetDalvikFPOpcode(OpKind op, bool is_const, bool is_wide)
buzbee4f1181f2012-06-22 13:52:12 -07002231{
2232 Instruction::Code res = Instruction::NOP;
buzbeefa57c472012-11-21 12:06:18 -08002233 if (is_wide) {
buzbee4f1181f2012-06-22 13:52:12 -07002234 switch(op) {
2235 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2236 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2237 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2238 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2239 case kOpRem: res = Instruction::REM_DOUBLE; break;
2240 default: LOG(FATAL) << "Unexpected OpKind " << op;
2241 }
2242 } else {
2243 switch(op) {
2244 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2245 case kOpSub: res = Instruction::SUB_FLOAT; break;
2246 case kOpMul: res = Instruction::MUL_FLOAT; break;
2247 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2248 case kOpRem: res = Instruction::REM_FLOAT; break;
2249 default: LOG(FATAL) << "Unexpected OpKind " << op;
2250 }
2251 }
2252 return res;
2253}
2254
buzbeefa57c472012-11-21 12:06:18 -08002255static void CvtBinFPOp(CompilationUnit* cu, OpKind op, llvm::Instruction* inst)
buzbee4f1181f2012-06-22 13:52:12 -07002256{
buzbee02031b12012-11-23 09:41:35 -08002257 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002258 RegLocation rl_dest = GetLoc(cu, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002259 /*
2260 * Normally, we won't ever generate an FP operation with an immediate
2261 * operand (not supported in Dex instruction set). However, the IR builder
buzbeefa57c472012-11-21 12:06:18 -08002262 * may insert them - in particular for create_neg_fp. Recognize this case
buzbee4f4dfc72012-07-02 14:54:44 -07002263 * and deal with it.
2264 */
2265 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2266 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2267 DCHECK(op2C == NULL);
2268 if ((op1C != NULL) && (op == kOpSub)) {
buzbeefa57c472012-11-21 12:06:18 -08002269 RegLocation rl_src = GetLoc(cu, inst->getOperand(1));
2270 if (rl_dest.wide) {
buzbee02031b12012-11-23 09:41:35 -08002271 cg->GenArithOpDouble(cu, Instruction::NEG_DOUBLE, rl_dest, rl_src, rl_src);
buzbee4f4dfc72012-07-02 14:54:44 -07002272 } else {
buzbee02031b12012-11-23 09:41:35 -08002273 cg->GenArithOpFloat(cu, Instruction::NEG_FLOAT, rl_dest, rl_src, rl_src);
buzbee4f4dfc72012-07-02 14:54:44 -07002274 }
buzbee4f1181f2012-06-22 13:52:12 -07002275 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002276 DCHECK(op1C == NULL);
buzbeefa57c472012-11-21 12:06:18 -08002277 RegLocation rl_src1 = GetLoc(cu, inst->getOperand(0));
2278 RegLocation rl_src2 = GetLoc(cu, inst->getOperand(1));
2279 Instruction::Code dalvik_op = GetDalvikFPOpcode(op, false, rl_dest.wide);
2280 if (rl_dest.wide) {
buzbee02031b12012-11-23 09:41:35 -08002281 cg->GenArithOpDouble(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
buzbee4f4dfc72012-07-02 14:54:44 -07002282 } else {
buzbee02031b12012-11-23 09:41:35 -08002283 cg->GenArithOpFloat(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
buzbee4f4dfc72012-07-02 14:54:44 -07002284 }
buzbee4f1181f2012-06-22 13:52:12 -07002285 }
2286}
2287
buzbeefa57c472012-11-21 12:06:18 -08002288static void CvtIntNarrowing(CompilationUnit* cu, llvm::Instruction* inst,
buzbee101305f2012-06-28 18:00:56 -07002289 Instruction::Code opcode)
2290{
buzbee02031b12012-11-23 09:41:35 -08002291 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002292 RegLocation rl_dest = GetLoc(cu, inst);
2293 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
buzbee02031b12012-11-23 09:41:35 -08002294 cg->GenIntNarrowing(cu, opcode, rl_dest, rl_src);
buzbee101305f2012-06-28 18:00:56 -07002295}
2296
buzbeefa57c472012-11-21 12:06:18 -08002297static void CvtIntToFP(CompilationUnit* cu, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002298{
buzbee02031b12012-11-23 09:41:35 -08002299 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002300 RegLocation rl_dest = GetLoc(cu, inst);
2301 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002302 Instruction::Code opcode;
buzbeefa57c472012-11-21 12:06:18 -08002303 if (rl_dest.wide) {
2304 if (rl_src.wide) {
buzbee76592632012-06-29 15:18:35 -07002305 opcode = Instruction::LONG_TO_DOUBLE;
2306 } else {
2307 opcode = Instruction::INT_TO_DOUBLE;
2308 }
2309 } else {
buzbeefa57c472012-11-21 12:06:18 -08002310 if (rl_src.wide) {
buzbee76592632012-06-29 15:18:35 -07002311 opcode = Instruction::LONG_TO_FLOAT;
2312 } else {
2313 opcode = Instruction::INT_TO_FLOAT;
2314 }
2315 }
buzbee02031b12012-11-23 09:41:35 -08002316 cg->GenConversion(cu, opcode, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002317}
2318
buzbeefa57c472012-11-21 12:06:18 -08002319static void CvtFPToInt(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002320{
buzbee02031b12012-11-23 09:41:35 -08002321 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002322 RegLocation rl_dest = GetLoc(cu, call_inst);
2323 RegLocation rl_src = GetLoc(cu, call_inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002324 Instruction::Code opcode;
buzbeefa57c472012-11-21 12:06:18 -08002325 if (rl_dest.wide) {
2326 if (rl_src.wide) {
buzbee76592632012-06-29 15:18:35 -07002327 opcode = Instruction::DOUBLE_TO_LONG;
2328 } else {
2329 opcode = Instruction::FLOAT_TO_LONG;
2330 }
2331 } else {
buzbeefa57c472012-11-21 12:06:18 -08002332 if (rl_src.wide) {
buzbee76592632012-06-29 15:18:35 -07002333 opcode = Instruction::DOUBLE_TO_INT;
2334 } else {
2335 opcode = Instruction::FLOAT_TO_INT;
2336 }
2337 }
buzbee02031b12012-11-23 09:41:35 -08002338 cg->GenConversion(cu, opcode, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002339}
2340
buzbeefa57c472012-11-21 12:06:18 -08002341static void CvtFloatToDouble(CompilationUnit* cu, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002342{
buzbee02031b12012-11-23 09:41:35 -08002343 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002344 RegLocation rl_dest = GetLoc(cu, inst);
2345 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
buzbee02031b12012-11-23 09:41:35 -08002346 cg->GenConversion(cu, Instruction::FLOAT_TO_DOUBLE, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002347}
2348
buzbeefa57c472012-11-21 12:06:18 -08002349static void CvtTrunc(CompilationUnit* cu, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002350{
buzbee02031b12012-11-23 09:41:35 -08002351 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002352 RegLocation rl_dest = GetLoc(cu, inst);
2353 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
2354 rl_src = UpdateLocWide(cu, rl_src);
2355 rl_src = WideToNarrow(cu, rl_src);
buzbee02031b12012-11-23 09:41:35 -08002356 cg->StoreValue(cu, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002357}
2358
buzbeefa57c472012-11-21 12:06:18 -08002359static void CvtDoubleToFloat(CompilationUnit* cu, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002360{
buzbee02031b12012-11-23 09:41:35 -08002361 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002362 RegLocation rl_dest = GetLoc(cu, inst);
2363 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
buzbee02031b12012-11-23 09:41:35 -08002364 cg->GenConversion(cu, Instruction::DOUBLE_TO_FLOAT, rl_dest, rl_src);
buzbee76592632012-06-29 15:18:35 -07002365}
2366
2367
buzbeefa57c472012-11-21 12:06:18 -08002368static void CvtIntExt(CompilationUnit* cu, llvm::Instruction* inst, bool is_signed)
buzbee101305f2012-06-28 18:00:56 -07002369{
buzbee02031b12012-11-23 09:41:35 -08002370 Codegen* cg = cu->cg.get();
buzbee101305f2012-06-28 18:00:56 -07002371 // TODO: evaluate src/tgt types and add general support for more than int to long
buzbeefa57c472012-11-21 12:06:18 -08002372 RegLocation rl_dest = GetLoc(cu, inst);
2373 RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
2374 DCHECK(rl_dest.wide);
2375 DCHECK(!rl_src.wide);
2376 DCHECK(!rl_dest.fp);
2377 DCHECK(!rl_src.fp);
2378 RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
2379 if (rl_src.location == kLocPhysReg) {
buzbee02031b12012-11-23 09:41:35 -08002380 cg->OpRegCopy(cu, rl_result.low_reg, rl_src.low_reg);
buzbee101305f2012-06-28 18:00:56 -07002381 } else {
buzbee02031b12012-11-23 09:41:35 -08002382 cg->LoadValueDirect(cu, rl_src, rl_result.low_reg);
buzbee101305f2012-06-28 18:00:56 -07002383 }
buzbeefa57c472012-11-21 12:06:18 -08002384 if (is_signed) {
buzbee02031b12012-11-23 09:41:35 -08002385 cg->OpRegRegImm(cu, kOpAsr, rl_result.high_reg, rl_result.low_reg, 31);
buzbee101305f2012-06-28 18:00:56 -07002386 } else {
buzbee02031b12012-11-23 09:41:35 -08002387 cg->LoadConstant(cu, rl_result.high_reg, 0);
buzbee101305f2012-06-28 18:00:56 -07002388 }
buzbee02031b12012-11-23 09:41:35 -08002389 cg->StoreValueWide(cu, rl_dest, rl_result);
buzbee101305f2012-06-28 18:00:56 -07002390}
2391
buzbeefa57c472012-11-21 12:06:18 -08002392static void CvtBinOp(CompilationUnit* cu, OpKind op, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002393{
buzbee02031b12012-11-23 09:41:35 -08002394 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002395 RegLocation rl_dest = GetLoc(cu, inst);
buzbee2cfc6392012-05-07 14:51:40 -07002396 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002397 // Special-case RSUB/NEG
buzbeefa57c472012-11-21 12:06:18 -08002398 llvm::ConstantInt* lhs_imm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2399 if ((op == kOpSub) && (lhs_imm != NULL)) {
2400 RegLocation rl_src1 = GetLoc(cu, inst->getOperand(1));
2401 if (rl_src1.wide) {
2402 DCHECK_EQ(lhs_imm->getSExtValue(), 0);
buzbee02031b12012-11-23 09:41:35 -08002403 cg->GenArithOpLong(cu, Instruction::NEG_LONG, rl_dest, rl_src1, rl_src1);
buzbeef58c12c2012-07-03 15:06:29 -07002404 } else {
buzbee02031b12012-11-23 09:41:35 -08002405 cg->GenArithOpIntLit(cu, Instruction::RSUB_INT, rl_dest, rl_src1,
buzbeefa57c472012-11-21 12:06:18 -08002406 lhs_imm->getSExtValue());
buzbeef58c12c2012-07-03 15:06:29 -07002407 }
buzbee4f1181f2012-06-22 13:52:12 -07002408 return;
2409 }
buzbeefa57c472012-11-21 12:06:18 -08002410 DCHECK(lhs_imm == NULL);
2411 RegLocation rl_src1 = GetLoc(cu, inst->getOperand(0));
buzbee2cfc6392012-05-07 14:51:40 -07002412 llvm::Value* rhs = inst->getOperand(1);
buzbeefa57c472012-11-21 12:06:18 -08002413 llvm::ConstantInt* const_rhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2414 if (!rl_dest.wide && (const_rhs != NULL)) {
2415 Instruction::Code dalvik_op = GetDalvikOpcode(op, true, false);
buzbee02031b12012-11-23 09:41:35 -08002416 cg->GenArithOpIntLit(cu, dalvik_op, rl_dest, rl_src1, const_rhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002417 } else {
buzbeefa57c472012-11-21 12:06:18 -08002418 Instruction::Code dalvik_op = GetDalvikOpcode(op, false, rl_dest.wide);
2419 RegLocation rl_src2;
2420 if (const_rhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002421 // ir_builder converts NOT_LONG to xor src, -1. Restore
buzbeefa57c472012-11-21 12:06:18 -08002422 DCHECK_EQ(dalvik_op, Instruction::XOR_LONG);
2423 DCHECK_EQ(-1L, const_rhs->getSExtValue());
2424 dalvik_op = Instruction::NOT_LONG;
2425 rl_src2 = rl_src1;
buzbee9a2487f2012-07-26 14:01:13 -07002426 } else {
buzbeefa57c472012-11-21 12:06:18 -08002427 rl_src2 = GetLoc(cu, rhs);
buzbee9a2487f2012-07-26 14:01:13 -07002428 }
buzbeefa57c472012-11-21 12:06:18 -08002429 if (rl_dest.wide) {
buzbee02031b12012-11-23 09:41:35 -08002430 cg->GenArithOpLong(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
buzbee2cfc6392012-05-07 14:51:40 -07002431 } else {
buzbee02031b12012-11-23 09:41:35 -08002432 cg->GenArithOpInt(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
buzbee2cfc6392012-05-07 14:51:40 -07002433 }
2434 }
2435}
2436
buzbeefa57c472012-11-21 12:06:18 -08002437static void CvtShiftOp(CompilationUnit* cu, Instruction::Code opcode, llvm::CallInst* call_inst)
buzbee101305f2012-06-28 18:00:56 -07002438{
buzbee02031b12012-11-23 09:41:35 -08002439 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002440 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2441 RegLocation rl_dest = GetLoc(cu, call_inst);
2442 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(0));
2443 llvm::Value* rhs = call_inst->getArgOperand(1);
buzbee2a83e8f2012-07-13 16:42:30 -07002444 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
buzbeefa57c472012-11-21 12:06:18 -08002445 DCHECK(!rl_dest.wide);
buzbee02031b12012-11-23 09:41:35 -08002446 cg->GenArithOpIntLit(cu, opcode, rl_dest, rl_src, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002447 } else {
buzbeefa57c472012-11-21 12:06:18 -08002448 RegLocation rl_shift = GetLoc(cu, rhs);
2449 if (call_inst->getType() == cu->irb->getInt64Ty()) {
buzbee02031b12012-11-23 09:41:35 -08002450 cg->GenShiftOpLong(cu, opcode, rl_dest, rl_src, rl_shift);
buzbee2a83e8f2012-07-13 16:42:30 -07002451 } else {
buzbee02031b12012-11-23 09:41:35 -08002452 cg->GenArithOpInt(cu, opcode, rl_dest, rl_src, rl_shift);
buzbee2a83e8f2012-07-13 16:42:30 -07002453 }
buzbee101305f2012-06-28 18:00:56 -07002454 }
2455}
2456
buzbeefa57c472012-11-21 12:06:18 -08002457static void CvtBr(CompilationUnit* cu, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002458{
buzbee02031b12012-11-23 09:41:35 -08002459 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002460 llvm::BranchInst* br_inst = llvm::dyn_cast<llvm::BranchInst>(inst);
2461 DCHECK(br_inst != NULL);
2462 DCHECK(br_inst->isUnconditional()); // May change - but this is all we use now
2463 llvm::BasicBlock* target_bb = br_inst->getSuccessor(0);
buzbee02031b12012-11-23 09:41:35 -08002464 cg->OpUnconditionalBranch(cu, cu->block_to_label_map.Get(target_bb));
buzbee2cfc6392012-05-07 14:51:40 -07002465}
2466
buzbeefa57c472012-11-21 12:06:18 -08002467static void CvtPhi(CompilationUnit* cu, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002468{
2469 // Nop - these have already been processed
2470}
2471
buzbeefa57c472012-11-21 12:06:18 -08002472static void CvtRet(CompilationUnit* cu, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002473{
buzbee02031b12012-11-23 09:41:35 -08002474 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002475 llvm::ReturnInst* ret_inst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2476 llvm::Value* ret_val = ret_inst->getReturnValue();
2477 if (ret_val != NULL) {
2478 RegLocation rl_src = GetLoc(cu, ret_val);
2479 if (rl_src.wide) {
buzbee02031b12012-11-23 09:41:35 -08002480 cg->StoreValueWide(cu, GetReturnWide(cu, rl_src.fp), rl_src);
buzbee2cfc6392012-05-07 14:51:40 -07002481 } else {
buzbee02031b12012-11-23 09:41:35 -08002482 cg->StoreValue(cu, GetReturn(cu, rl_src.fp), rl_src);
buzbee2cfc6392012-05-07 14:51:40 -07002483 }
2484 }
buzbee02031b12012-11-23 09:41:35 -08002485 cg->GenExitSequence(cu);
buzbee2cfc6392012-05-07 14:51:40 -07002486}
2487
buzbeefa57c472012-11-21 12:06:18 -08002488static ConditionCode GetCond(llvm::ICmpInst::Predicate llvm_cond)
buzbee2cfc6392012-05-07 14:51:40 -07002489{
2490 ConditionCode res = kCondAl;
buzbeefa57c472012-11-21 12:06:18 -08002491 switch(llvm_cond) {
buzbee6969d502012-06-15 16:40:31 -07002492 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002493 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2494 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2495 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002496 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002497 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002498 default: LOG(FATAL) << "Unexpected llvm condition";
2499 }
2500 return res;
2501}
2502
buzbeefa57c472012-11-21 12:06:18 -08002503static void CvtICmp(CompilationUnit* cu, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002504{
buzbee02031b12012-11-23 09:41:35 -08002505 // cg->GenCmpLong(cu, rl_dest, rl_src1, rl_src2)
buzbee2cfc6392012-05-07 14:51:40 -07002506 UNIMPLEMENTED(FATAL);
2507}
2508
buzbeefa57c472012-11-21 12:06:18 -08002509static void CvtICmpBr(CompilationUnit* cu, llvm::Instruction* inst,
2510 llvm::BranchInst* br_inst)
buzbee2cfc6392012-05-07 14:51:40 -07002511{
buzbee02031b12012-11-23 09:41:35 -08002512 Codegen* cg = cu->cg.get();
buzbee2cfc6392012-05-07 14:51:40 -07002513 // Get targets
buzbeefa57c472012-11-21 12:06:18 -08002514 llvm::BasicBlock* taken_bb = br_inst->getSuccessor(0);
2515 LIR* taken = cu->block_to_label_map.Get(taken_bb);
2516 llvm::BasicBlock* fallthrough_bb = br_inst->getSuccessor(1);
2517 LIR* fall_through = cu->block_to_label_map.Get(fallthrough_bb);
buzbee2cfc6392012-05-07 14:51:40 -07002518 // Get comparison operands
buzbeefa57c472012-11-21 12:06:18 -08002519 llvm::ICmpInst* i_cmp_inst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2520 ConditionCode cond = GetCond(i_cmp_inst->getPredicate());
2521 llvm::Value* lhs = i_cmp_inst->getOperand(0);
buzbee2cfc6392012-05-07 14:51:40 -07002522 // Not expecting a constant as 1st operand
2523 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
buzbeefa57c472012-11-21 12:06:18 -08002524 RegLocation rl_src1 = GetLoc(cu, inst->getOperand(0));
buzbee02031b12012-11-23 09:41:35 -08002525 rl_src1 = cg->LoadValue(cu, rl_src1, kCoreReg);
buzbee2cfc6392012-05-07 14:51:40 -07002526 llvm::Value* rhs = inst->getOperand(1);
buzbeefa57c472012-11-21 12:06:18 -08002527 if (cu->instruction_set == kMips) {
buzbeeb046e162012-10-30 15:48:42 -07002528 // Compare and branch in one shot
2529 UNIMPLEMENTED(FATAL);
2530 }
buzbee2cfc6392012-05-07 14:51:40 -07002531 //Compare, then branch
2532 // TODO: handle fused CMP_LONG/IF_xxZ case
2533 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
buzbee02031b12012-11-23 09:41:35 -08002534 cg->OpRegImm(cu, kOpCmp, rl_src1.low_reg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002535 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
buzbee02031b12012-11-23 09:41:35 -08002536 cg->OpRegImm(cu, kOpCmp, rl_src1.low_reg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002537 } else {
buzbeefa57c472012-11-21 12:06:18 -08002538 RegLocation rl_src2 = GetLoc(cu, rhs);
buzbee02031b12012-11-23 09:41:35 -08002539 rl_src2 = cg->LoadValue(cu, rl_src2, kCoreReg);
2540 cg->OpRegReg(cu, kOpCmp, rl_src1.low_reg, rl_src2.low_reg);
buzbee2cfc6392012-05-07 14:51:40 -07002541 }
buzbee02031b12012-11-23 09:41:35 -08002542 cg->OpCondBranch(cu, cond, taken);
buzbee2cfc6392012-05-07 14:51:40 -07002543 // Fallthrough
buzbee02031b12012-11-23 09:41:35 -08002544 cg->OpUnconditionalBranch(cu, fall_through);
buzbee2cfc6392012-05-07 14:51:40 -07002545}
2546
buzbeefa57c472012-11-21 12:06:18 -08002547static void CvtCopy(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee2cfc6392012-05-07 14:51:40 -07002548{
buzbee02031b12012-11-23 09:41:35 -08002549 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002550 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2551 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(0));
2552 RegLocation rl_dest = GetLoc(cu, call_inst);
2553 DCHECK_EQ(rl_src.wide, rl_dest.wide);
2554 DCHECK_EQ(rl_src.fp, rl_dest.fp);
2555 if (rl_src.wide) {
buzbee02031b12012-11-23 09:41:35 -08002556 cg->StoreValueWide(cu, rl_dest, rl_src);
buzbee2cfc6392012-05-07 14:51:40 -07002557 } else {
buzbee02031b12012-11-23 09:41:35 -08002558 cg->StoreValue(cu, rl_dest, rl_src);
buzbee2cfc6392012-05-07 14:51:40 -07002559 }
2560}
2561
2562// Note: Immediate arg is a ConstantInt regardless of result type
buzbeefa57c472012-11-21 12:06:18 -08002563static void CvtConst(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee2cfc6392012-05-07 14:51:40 -07002564{
buzbee02031b12012-11-23 09:41:35 -08002565 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002566 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002567 llvm::ConstantInt* src =
buzbeefa57c472012-11-21 12:06:18 -08002568 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
buzbee2cfc6392012-05-07 14:51:40 -07002569 uint64_t immval = src->getZExtValue();
buzbeefa57c472012-11-21 12:06:18 -08002570 RegLocation rl_dest = GetLoc(cu, call_inst);
2571 RegLocation rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
2572 if (rl_dest.wide) {
buzbee02031b12012-11-23 09:41:35 -08002573 cg->LoadConstantValueWide(cu, rl_result.low_reg, rl_result.high_reg,
buzbee2cfc6392012-05-07 14:51:40 -07002574 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
buzbee02031b12012-11-23 09:41:35 -08002575 cg->StoreValueWide(cu, rl_dest, rl_result);
buzbee2cfc6392012-05-07 14:51:40 -07002576 } else {
buzbee02031b12012-11-23 09:41:35 -08002577 cg->LoadConstantNoClobber(cu, rl_result.low_reg, immval & 0xffffffff);
2578 cg->StoreValue(cu, rl_dest, rl_result);
buzbee5f61f672012-11-28 17:22:17 -08002579 cg->Workaround7250540(cu, rl_dest, immval & 0xffffffff);
buzbee2cfc6392012-05-07 14:51:40 -07002580 }
2581}
2582
buzbeefa57c472012-11-21 12:06:18 -08002583static void CvtConstObject(CompilationUnit* cu, llvm::CallInst* call_inst, bool is_string)
buzbee6969d502012-06-15 16:40:31 -07002584{
buzbee02031b12012-11-23 09:41:35 -08002585 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002586 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2587 llvm::ConstantInt* idx_val =
2588 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2589 uint32_t index = idx_val->getZExtValue();
2590 RegLocation rl_dest = GetLoc(cu, call_inst);
2591 if (is_string) {
buzbee02031b12012-11-23 09:41:35 -08002592 cg->GenConstString(cu, index, rl_dest);
buzbee101305f2012-06-28 18:00:56 -07002593 } else {
buzbee02031b12012-11-23 09:41:35 -08002594 cg->GenConstClass(cu, index, rl_dest);
buzbee101305f2012-06-28 18:00:56 -07002595 }
2596}
2597
buzbeefa57c472012-11-21 12:06:18 -08002598static void CvtFillArrayData(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee101305f2012-06-28 18:00:56 -07002599{
buzbee02031b12012-11-23 09:41:35 -08002600 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002601 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2602 llvm::ConstantInt* offset_val =
2603 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2604 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
buzbee02031b12012-11-23 09:41:35 -08002605 cg->GenFillArrayData(cu, offset_val->getSExtValue(), rl_src);
buzbee6969d502012-06-15 16:40:31 -07002606}
2607
buzbeefa57c472012-11-21 12:06:18 -08002608static void CvtNewInstance(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee4f1181f2012-06-22 13:52:12 -07002609{
buzbee02031b12012-11-23 09:41:35 -08002610 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002611 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2612 llvm::ConstantInt* type_idx_val =
2613 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2614 uint32_t type_idx = type_idx_val->getZExtValue();
2615 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002616 cg->GenNewInstance(cu, type_idx, rl_dest);
buzbee4f1181f2012-06-22 13:52:12 -07002617}
2618
buzbeefa57c472012-11-21 12:06:18 -08002619static void CvtNewArray(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee8fa0fda2012-06-27 15:44:52 -07002620{
buzbee02031b12012-11-23 09:41:35 -08002621 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002622 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2623 llvm::ConstantInt* type_idx_val =
2624 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2625 uint32_t type_idx = type_idx_val->getZExtValue();
2626 llvm::Value* len = call_inst->getArgOperand(1);
2627 RegLocation rl_len = GetLoc(cu, len);
2628 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002629 cg->GenNewArray(cu, type_idx, rl_dest, rl_len);
buzbee8fa0fda2012-06-27 15:44:52 -07002630}
2631
buzbeefa57c472012-11-21 12:06:18 -08002632static void CvtInstanceOf(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee8fa0fda2012-06-27 15:44:52 -07002633{
buzbee02031b12012-11-23 09:41:35 -08002634 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002635 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2636 llvm::ConstantInt* type_idx_val =
2637 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2638 uint32_t type_idx = type_idx_val->getZExtValue();
2639 llvm::Value* src = call_inst->getArgOperand(1);
2640 RegLocation rl_src = GetLoc(cu, src);
2641 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002642 cg->GenInstanceof(cu, type_idx, rl_dest, rl_src);
buzbee8fa0fda2012-06-27 15:44:52 -07002643}
2644
buzbeefa57c472012-11-21 12:06:18 -08002645static void CvtThrow(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee32412962012-06-26 16:27:56 -07002646{
buzbee02031b12012-11-23 09:41:35 -08002647 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002648 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2649 llvm::Value* src = call_inst->getArgOperand(0);
2650 RegLocation rl_src = GetLoc(cu, src);
buzbee02031b12012-11-23 09:41:35 -08002651 cg->GenThrow(cu, rl_src);
buzbee32412962012-06-26 16:27:56 -07002652}
2653
buzbeefa57c472012-11-21 12:06:18 -08002654static void CvtMonitorEnterExit(CompilationUnit* cu, bool is_enter,
2655 llvm::CallInst* call_inst)
buzbee8fa0fda2012-06-27 15:44:52 -07002656{
buzbee02031b12012-11-23 09:41:35 -08002657 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002658 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2659 llvm::ConstantInt* opt_flags =
2660 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2661 llvm::Value* src = call_inst->getArgOperand(1);
2662 RegLocation rl_src = GetLoc(cu, src);
2663 if (is_enter) {
buzbee02031b12012-11-23 09:41:35 -08002664 cg->GenMonitorEnter(cu, opt_flags->getZExtValue(), rl_src);
buzbee8fa0fda2012-06-27 15:44:52 -07002665 } else {
buzbee02031b12012-11-23 09:41:35 -08002666 cg->GenMonitorExit(cu, opt_flags->getZExtValue(), rl_src);
buzbee8fa0fda2012-06-27 15:44:52 -07002667 }
2668}
2669
buzbeefa57c472012-11-21 12:06:18 -08002670static void CvtArrayLength(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee8fa0fda2012-06-27 15:44:52 -07002671{
buzbee02031b12012-11-23 09:41:35 -08002672 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002673 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2674 llvm::ConstantInt* opt_flags =
2675 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2676 llvm::Value* src = call_inst->getArgOperand(1);
2677 RegLocation rl_src = GetLoc(cu, src);
buzbee02031b12012-11-23 09:41:35 -08002678 rl_src = cg->LoadValue(cu, rl_src, kCoreReg);
2679 cg->GenNullCheck(cu, rl_src.s_reg_low, rl_src.low_reg, opt_flags->getZExtValue());
buzbeefa57c472012-11-21 12:06:18 -08002680 RegLocation rl_dest = GetLoc(cu, call_inst);
2681 RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
2682 int len_offset = Array::LengthOffset().Int32Value();
buzbee02031b12012-11-23 09:41:35 -08002683 cg->LoadWordDisp(cu, rl_src.low_reg, len_offset, rl_result.low_reg);
2684 cg->StoreValue(cu, rl_dest, rl_result);
buzbee8fa0fda2012-06-27 15:44:52 -07002685}
2686
buzbeefa57c472012-11-21 12:06:18 -08002687static void CvtMoveException(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee32412962012-06-26 16:27:56 -07002688{
buzbee02031b12012-11-23 09:41:35 -08002689 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002690 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002691 cg->GenMoveException(cu, rl_dest);
buzbee32412962012-06-26 16:27:56 -07002692}
2693
buzbeefa57c472012-11-21 12:06:18 -08002694static void CvtSget(CompilationUnit* cu, llvm::CallInst* call_inst, bool is_wide, bool is_object)
buzbee4f1181f2012-06-22 13:52:12 -07002695{
buzbee02031b12012-11-23 09:41:35 -08002696 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002697 DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
2698 llvm::ConstantInt* type_idx_val =
2699 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2700 uint32_t type_idx = type_idx_val->getZExtValue();
2701 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002702 cg->GenSget(cu, type_idx, rl_dest, is_wide, is_object);
buzbee4f1181f2012-06-22 13:52:12 -07002703}
2704
buzbeefa57c472012-11-21 12:06:18 -08002705static void CvtSput(CompilationUnit* cu, llvm::CallInst* call_inst, bool is_wide, bool is_object)
buzbee8fa0fda2012-06-27 15:44:52 -07002706{
buzbee02031b12012-11-23 09:41:35 -08002707 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002708 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2709 llvm::ConstantInt* type_idx_val =
2710 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2711 uint32_t type_idx = type_idx_val->getZExtValue();
2712 llvm::Value* src = call_inst->getArgOperand(1);
2713 RegLocation rl_src = GetLoc(cu, src);
buzbee02031b12012-11-23 09:41:35 -08002714 cg->GenSput(cu, type_idx, rl_src, is_wide, is_object);
buzbee8fa0fda2012-06-27 15:44:52 -07002715}
2716
buzbeefa57c472012-11-21 12:06:18 -08002717static void CvtAget(CompilationUnit* cu, llvm::CallInst* call_inst, OpSize size, int scale)
buzbee8fa0fda2012-06-27 15:44:52 -07002718{
buzbee02031b12012-11-23 09:41:35 -08002719 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002720 DCHECK_EQ(call_inst->getNumArgOperands(), 3U);
2721 llvm::ConstantInt* opt_flags =
2722 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2723 RegLocation rl_array = GetLoc(cu, call_inst->getArgOperand(1));
2724 RegLocation rl_index = GetLoc(cu, call_inst->getArgOperand(2));
2725 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002726 cg->GenArrayGet(cu, opt_flags->getZExtValue(), size, rl_array, rl_index,
buzbeefa57c472012-11-21 12:06:18 -08002727 rl_dest, scale);
buzbee8fa0fda2012-06-27 15:44:52 -07002728}
2729
buzbeefa57c472012-11-21 12:06:18 -08002730static void CvtAput(CompilationUnit* cu, llvm::CallInst* call_inst, OpSize size,
2731 int scale, bool is_object)
buzbee8fa0fda2012-06-27 15:44:52 -07002732{
buzbee02031b12012-11-23 09:41:35 -08002733 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002734 DCHECK_EQ(call_inst->getNumArgOperands(), 4U);
2735 llvm::ConstantInt* opt_flags =
2736 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2737 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
2738 RegLocation rl_array = GetLoc(cu, call_inst->getArgOperand(2));
2739 RegLocation rl_index = GetLoc(cu, call_inst->getArgOperand(3));
2740 if (is_object) {
buzbee02031b12012-11-23 09:41:35 -08002741 cg->GenArrayObjPut(cu, opt_flags->getZExtValue(), rl_array, rl_index,
buzbeefa57c472012-11-21 12:06:18 -08002742 rl_src, scale);
buzbeef1f86362012-07-10 15:18:31 -07002743 } else {
buzbee02031b12012-11-23 09:41:35 -08002744 cg->GenArrayPut(cu, opt_flags->getZExtValue(), size, rl_array, rl_index,
buzbeefa57c472012-11-21 12:06:18 -08002745 rl_src, scale);
buzbeef1f86362012-07-10 15:18:31 -07002746 }
2747}
2748
buzbeefa57c472012-11-21 12:06:18 -08002749static void CvtAputObj(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbeef1f86362012-07-10 15:18:31 -07002750{
buzbeefa57c472012-11-21 12:06:18 -08002751 CvtAput(cu, call_inst, kWord, 2, true /* is_object */);
buzbeef1f86362012-07-10 15:18:31 -07002752}
2753
buzbeefa57c472012-11-21 12:06:18 -08002754static void CvtAputPrimitive(CompilationUnit* cu, llvm::CallInst* call_inst,
buzbeef1f86362012-07-10 15:18:31 -07002755 OpSize size, int scale)
2756{
buzbeefa57c472012-11-21 12:06:18 -08002757 CvtAput(cu, call_inst, size, scale, false /* is_object */);
buzbee8fa0fda2012-06-27 15:44:52 -07002758}
2759
buzbeefa57c472012-11-21 12:06:18 -08002760static void CvtIget(CompilationUnit* cu, llvm::CallInst* call_inst, OpSize size,
2761 bool is_wide, bool is_obj)
buzbee101305f2012-06-28 18:00:56 -07002762{
buzbee02031b12012-11-23 09:41:35 -08002763 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002764 DCHECK_EQ(call_inst->getNumArgOperands(), 3U);
2765 llvm::ConstantInt* opt_flags =
2766 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2767 RegLocation rl_obj = GetLoc(cu, call_inst->getArgOperand(1));
2768 llvm::ConstantInt* field_idx =
2769 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(2));
2770 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002771 cg->GenIGet(cu, field_idx->getZExtValue(), opt_flags->getZExtValue(),
buzbeefa57c472012-11-21 12:06:18 -08002772 size, rl_dest, rl_obj, is_wide, is_obj);
buzbee101305f2012-06-28 18:00:56 -07002773}
2774
buzbeefa57c472012-11-21 12:06:18 -08002775static void CvtIput(CompilationUnit* cu, llvm::CallInst* call_inst, OpSize size,
2776 bool is_wide, bool is_obj)
buzbee101305f2012-06-28 18:00:56 -07002777{
buzbee02031b12012-11-23 09:41:35 -08002778 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002779 DCHECK_EQ(call_inst->getNumArgOperands(), 4U);
2780 llvm::ConstantInt* opt_flags =
2781 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2782 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
2783 RegLocation rl_obj = GetLoc(cu, call_inst->getArgOperand(2));
2784 llvm::ConstantInt* field_idx =
2785 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(3));
buzbee02031b12012-11-23 09:41:35 -08002786 cg->GenIPut(cu, field_idx->getZExtValue(), opt_flags->getZExtValue(),
buzbeefa57c472012-11-21 12:06:18 -08002787 size, rl_src, rl_obj, is_wide, is_obj);
buzbee101305f2012-06-28 18:00:56 -07002788}
2789
buzbeefa57c472012-11-21 12:06:18 -08002790static void CvtCheckCast(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee101305f2012-06-28 18:00:56 -07002791{
buzbee02031b12012-11-23 09:41:35 -08002792 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002793 DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
2794 llvm::ConstantInt* type_idx =
2795 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2796 RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
buzbee02031b12012-11-23 09:41:35 -08002797 cg->GenCheckCast(cu, type_idx->getZExtValue(), rl_src);
buzbee101305f2012-06-28 18:00:56 -07002798}
2799
buzbeefa57c472012-11-21 12:06:18 -08002800static void CvtFPCompare(CompilationUnit* cu, llvm::CallInst* call_inst,
buzbeeaad94382012-11-21 07:40:50 -08002801 Instruction::Code opcode)
buzbee76592632012-06-29 15:18:35 -07002802{
buzbee02031b12012-11-23 09:41:35 -08002803 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002804 RegLocation rl_src1 = GetLoc(cu, call_inst->getArgOperand(0));
2805 RegLocation rl_src2 = GetLoc(cu, call_inst->getArgOperand(1));
2806 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002807 cg->GenCmpFP(cu, opcode, rl_dest, rl_src1, rl_src2);
buzbee76592632012-06-29 15:18:35 -07002808}
2809
buzbeefa57c472012-11-21 12:06:18 -08002810static void CvtLongCompare(CompilationUnit* cu, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002811{
buzbee02031b12012-11-23 09:41:35 -08002812 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002813 RegLocation rl_src1 = GetLoc(cu, call_inst->getArgOperand(0));
2814 RegLocation rl_src2 = GetLoc(cu, call_inst->getArgOperand(1));
2815 RegLocation rl_dest = GetLoc(cu, call_inst);
buzbee02031b12012-11-23 09:41:35 -08002816 cg->GenCmpLong(cu, rl_dest, rl_src1, rl_src2);
buzbee76592632012-06-29 15:18:35 -07002817}
2818
buzbeefa57c472012-11-21 12:06:18 -08002819static void CvtSwitch(CompilationUnit* cu, llvm::Instruction* inst)
buzbeef58c12c2012-07-03 15:06:29 -07002820{
buzbee02031b12012-11-23 09:41:35 -08002821 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002822 llvm::SwitchInst* sw_inst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2823 DCHECK(sw_inst != NULL);
2824 llvm::Value* test_val = sw_inst->getCondition();
2825 llvm::MDNode* table_offset_node = sw_inst->getMetadata("SwitchTable");
2826 DCHECK(table_offset_node != NULL);
2827 llvm::ConstantInt* table_offset_value =
2828 static_cast<llvm::ConstantInt*>(table_offset_node->getOperand(0));
2829 int32_t table_offset = table_offset_value->getSExtValue();
2830 RegLocation rl_src = GetLoc(cu, test_val);
2831 const uint16_t* table = cu->insns + cu->current_dalvik_offset + table_offset;
2832 uint16_t table_magic = *table;
2833 if (table_magic == 0x100) {
buzbee02031b12012-11-23 09:41:35 -08002834 cg->GenPackedSwitch(cu, table_offset, rl_src);
buzbeea1da8a52012-07-09 14:00:21 -07002835 } else {
buzbeefa57c472012-11-21 12:06:18 -08002836 DCHECK_EQ(table_magic, 0x200);
buzbee02031b12012-11-23 09:41:35 -08002837 cg->GenSparseSwitch(cu, table_offset, rl_src);
buzbeea1da8a52012-07-09 14:00:21 -07002838 }
buzbeef58c12c2012-07-03 15:06:29 -07002839}
2840
buzbeefa57c472012-11-21 12:06:18 -08002841static void CvtInvoke(CompilationUnit* cu, llvm::CallInst* call_inst, bool is_void,
2842 bool is_filled_new_array)
buzbee6969d502012-06-15 16:40:31 -07002843{
buzbee02031b12012-11-23 09:41:35 -08002844 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002845 CallInfo* info = static_cast<CallInfo*>(NewMem(cu, sizeof(CallInfo), true, kAllocMisc));
2846 if (is_void) {
buzbee6969d502012-06-15 16:40:31 -07002847 info->result.location = kLocInvalid;
2848 } else {
buzbeefa57c472012-11-21 12:06:18 -08002849 info->result = GetLoc(cu, call_inst);
buzbee6969d502012-06-15 16:40:31 -07002850 }
buzbeefa57c472012-11-21 12:06:18 -08002851 llvm::ConstantInt* invoke_type_val =
2852 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(0));
2853 llvm::ConstantInt* method_index_val =
2854 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(1));
2855 llvm::ConstantInt* opt_flags_val =
2856 llvm::dyn_cast<llvm::ConstantInt>(call_inst->getArgOperand(2));
2857 info->type = static_cast<InvokeType>(invoke_type_val->getZExtValue());
2858 info->index = method_index_val->getZExtValue();
2859 info->opt_flags = opt_flags_val->getZExtValue();
2860 info->offset = cu->current_dalvik_offset;
buzbee6969d502012-06-15 16:40:31 -07002861
buzbee6969d502012-06-15 16:40:31 -07002862 // Count the argument words, and then build argument array.
buzbeefa57c472012-11-21 12:06:18 -08002863 info->num_arg_words = 0;
2864 for (unsigned int i = 3; i < call_inst->getNumArgOperands(); i++) {
2865 RegLocation t_loc = GetLoc(cu, call_inst->getArgOperand(i));
2866 info->num_arg_words += t_loc.wide ? 2 : 1;
buzbee6969d502012-06-15 16:40:31 -07002867 }
buzbeefa57c472012-11-21 12:06:18 -08002868 info->args = (info->num_arg_words == 0) ? NULL : static_cast<RegLocation*>
2869 (NewMem(cu, sizeof(RegLocation) * info->num_arg_words, false, kAllocMisc));
buzbee6969d502012-06-15 16:40:31 -07002870 // Now, fill in the location records, synthesizing high loc of wide vals
buzbeefa57c472012-11-21 12:06:18 -08002871 for (int i = 3, next = 0; next < info->num_arg_words;) {
2872 info->args[next] = GetLoc(cu, call_inst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002873 if (info->args[next].wide) {
2874 next++;
2875 // TODO: Might make sense to mark this as an invalid loc
buzbeefa57c472012-11-21 12:06:18 -08002876 info->args[next].orig_sreg = info->args[next-1].orig_sreg+1;
2877 info->args[next].s_reg_low = info->args[next-1].s_reg_low+1;
buzbee6969d502012-06-15 16:40:31 -07002878 }
2879 next++;
2880 }
buzbeefa57c472012-11-21 12:06:18 -08002881 // TODO - rework such that we no longer need is_range
2882 info->is_range = (info->num_arg_words > 5);
buzbee4f4dfc72012-07-02 14:54:44 -07002883
buzbeefa57c472012-11-21 12:06:18 -08002884 if (is_filled_new_array) {
buzbee02031b12012-11-23 09:41:35 -08002885 cg->GenFilledNewArray(cu, info);
buzbee101305f2012-06-28 18:00:56 -07002886 } else {
buzbee02031b12012-11-23 09:41:35 -08002887 cg->GenInvoke(cu, info);
buzbee101305f2012-06-28 18:00:56 -07002888 }
buzbee6969d502012-06-15 16:40:31 -07002889}
2890
buzbeead8f15e2012-06-18 14:49:45 -07002891/* Look up the RegLocation associated with a Value. Must already be defined */
buzbeefa57c472012-11-21 12:06:18 -08002892static RegLocation ValToLoc(CompilationUnit* cu, llvm::Value* val)
buzbeead8f15e2012-06-18 14:49:45 -07002893{
buzbeefa57c472012-11-21 12:06:18 -08002894 SafeMap<llvm::Value*, RegLocation>::iterator it = cu->loc_map.find(val);
2895 DCHECK(it != cu->loc_map.end()) << "Missing definition";
buzbeead8f15e2012-06-18 14:49:45 -07002896 return it->second;
2897}
2898
buzbeefa57c472012-11-21 12:06:18 -08002899static bool BitcodeBlockCodeGen(CompilationUnit* cu, llvm::BasicBlock* bb)
buzbee2cfc6392012-05-07 14:51:40 -07002900{
buzbee02031b12012-11-23 09:41:35 -08002901 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08002902 while (cu->llvm_blocks.find(bb) == cu->llvm_blocks.end()) {
2903 llvm::BasicBlock* next_bb = NULL;
2904 cu->llvm_blocks.insert(bb);
2905 bool is_entry = (bb == &cu->func->getEntryBlock());
buzbee0967a252012-09-14 10:43:54 -07002906 // Define the starting label
buzbeefa57c472012-11-21 12:06:18 -08002907 LIR* block_label = cu->block_to_label_map.Get(bb);
buzbee0967a252012-09-14 10:43:54 -07002908 // Extract the type and starting offset from the block's name
buzbeefa57c472012-11-21 12:06:18 -08002909 char block_type = kInvalidBlock;
2910 if (is_entry) {
2911 block_type = kNormalBlock;
2912 block_label->operands[0] = 0;
buzbee951c0a12012-10-03 16:31:39 -07002913 } else if (!bb->hasName()) {
buzbeefa57c472012-11-21 12:06:18 -08002914 block_type = kNormalBlock;
2915 block_label->operands[0] = DexFile::kDexNoIndex;
buzbee0967a252012-09-14 10:43:54 -07002916 } else {
buzbeefa57c472012-11-21 12:06:18 -08002917 std::string block_name = bb->getName().str();
buzbee951c0a12012-10-03 16:31:39 -07002918 int dummy;
buzbeefa57c472012-11-21 12:06:18 -08002919 sscanf(block_name.c_str(), kLabelFormat, &block_type, &block_label->operands[0], &dummy);
2920 cu->current_dalvik_offset = block_label->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002921 }
buzbeefa57c472012-11-21 12:06:18 -08002922 DCHECK((block_type == kNormalBlock) || (block_type == kCatchBlock));
2923 cu->current_dalvik_offset = block_label->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002924 // Set the label kind
buzbeefa57c472012-11-21 12:06:18 -08002925 block_label->opcode = kPseudoNormalBlockLabel;
buzbee0967a252012-09-14 10:43:54 -07002926 // Insert the label
buzbeefa57c472012-11-21 12:06:18 -08002927 AppendLIR(cu, block_label);
buzbee2cfc6392012-05-07 14:51:40 -07002928
buzbeefa57c472012-11-21 12:06:18 -08002929 LIR* head_lir = NULL;
buzbee8320f382012-09-11 16:29:42 -07002930
buzbeefa57c472012-11-21 12:06:18 -08002931 if (block_type == kCatchBlock) {
2932 head_lir = NewLIR0(cu, kPseudoExportedPC);
buzbee0967a252012-09-14 10:43:54 -07002933 }
buzbee8320f382012-09-11 16:29:42 -07002934
buzbee0967a252012-09-14 10:43:54 -07002935 // Free temp registers and reset redundant store tracking */
buzbeefa57c472012-11-21 12:06:18 -08002936 ResetRegPool(cu);
2937 ResetDefTracking(cu);
buzbee2cfc6392012-05-07 14:51:40 -07002938
buzbee0967a252012-09-14 10:43:54 -07002939 //TODO: restore oat incoming liveness optimization
buzbeefa57c472012-11-21 12:06:18 -08002940 ClobberAllRegs(cu);
buzbee2cfc6392012-05-07 14:51:40 -07002941
buzbeefa57c472012-11-21 12:06:18 -08002942 if (is_entry) {
buzbee52a77fc2012-11-20 19:50:46 -08002943 RegLocation* ArgLocs = static_cast<RegLocation*>
buzbeefa57c472012-11-21 12:06:18 -08002944 (NewMem(cu, sizeof(RegLocation) * cu->num_ins, true, kAllocMisc));
2945 llvm::Function::arg_iterator it(cu->func->arg_begin());
2946 llvm::Function::arg_iterator it_end(cu->func->arg_end());
buzbee0967a252012-09-14 10:43:54 -07002947 // Skip past Method*
2948 it++;
2949 for (unsigned i = 0; it != it_end; ++it) {
2950 llvm::Value* val = it;
buzbeefa57c472012-11-21 12:06:18 -08002951 ArgLocs[i++] = ValToLoc(cu, val);
buzbee0967a252012-09-14 10:43:54 -07002952 llvm::Type* ty = val->getType();
buzbeefa57c472012-11-21 12:06:18 -08002953 if ((ty == cu->irb->getInt64Ty()) || (ty == cu->irb->getDoubleTy())) {
buzbee52a77fc2012-11-20 19:50:46 -08002954 ArgLocs[i] = ArgLocs[i-1];
buzbeefa57c472012-11-21 12:06:18 -08002955 ArgLocs[i].low_reg = ArgLocs[i].high_reg;
2956 ArgLocs[i].orig_sreg++;
2957 ArgLocs[i].s_reg_low = INVALID_SREG;
2958 ArgLocs[i].high_word = true;
buzbee0967a252012-09-14 10:43:54 -07002959 i++;
2960 }
2961 }
buzbee02031b12012-11-23 09:41:35 -08002962 cg->GenEntrySequence(cu, ArgLocs, cu->method_loc);
buzbee0967a252012-09-14 10:43:54 -07002963 }
2964
2965 // Visit all of the instructions in the block
2966 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2967 llvm::Instruction* inst = it;
buzbeefa57c472012-11-21 12:06:18 -08002968 llvm::BasicBlock::iterator next_it = ++it;
buzbee0967a252012-09-14 10:43:54 -07002969 // Extract the Dalvik offset from the instruction
2970 uint32_t opcode = inst->getOpcode();
buzbeefa57c472012-11-21 12:06:18 -08002971 llvm::MDNode* dex_offset_node = inst->getMetadata("DexOff");
2972 if (dex_offset_node != NULL) {
2973 llvm::ConstantInt* dex_offset_value =
2974 static_cast<llvm::ConstantInt*>(dex_offset_node->getOperand(0));
2975 cu->current_dalvik_offset = dex_offset_value->getZExtValue();
buzbee0967a252012-09-14 10:43:54 -07002976 }
2977
buzbeefa57c472012-11-21 12:06:18 -08002978 ResetRegPool(cu);
2979 if (cu->disable_opt & (1 << kTrackLiveTemps)) {
2980 ClobberAllRegs(cu);
buzbee0967a252012-09-14 10:43:54 -07002981 }
2982
buzbeefa57c472012-11-21 12:06:18 -08002983 if (cu->disable_opt & (1 << kSuppressLoads)) {
2984 ResetDefTracking(cu);
buzbee0967a252012-09-14 10:43:54 -07002985 }
2986
2987 #ifndef NDEBUG
2988 /* Reset temp tracking sanity check */
buzbeefa57c472012-11-21 12:06:18 -08002989 cu->live_sreg = INVALID_SREG;
buzbee0967a252012-09-14 10:43:54 -07002990 #endif
2991
2992 // TODO: use llvm opcode name here instead of "boundary" if verbose
buzbeefa57c472012-11-21 12:06:18 -08002993 LIR* boundary_lir = MarkBoundary(cu, cu->current_dalvik_offset, "boundary");
buzbee0967a252012-09-14 10:43:54 -07002994
2995 /* Remember the first LIR for thisl block*/
buzbeefa57c472012-11-21 12:06:18 -08002996 if (head_lir == NULL) {
2997 head_lir = boundary_lir;
2998 head_lir->def_mask = ENCODE_ALL;
buzbee0967a252012-09-14 10:43:54 -07002999 }
3000
3001 switch(opcode) {
3002
3003 case llvm::Instruction::ICmp: {
buzbeefa57c472012-11-21 12:06:18 -08003004 llvm::Instruction* next_inst = next_it;
3005 llvm::BranchInst* br_inst = llvm::dyn_cast<llvm::BranchInst>(next_inst);
3006 if (br_inst != NULL /* and... */) {
3007 CvtICmpBr(cu, inst, br_inst);
buzbee0967a252012-09-14 10:43:54 -07003008 ++it;
3009 } else {
buzbeefa57c472012-11-21 12:06:18 -08003010 CvtICmp(cu, inst);
buzbee0967a252012-09-14 10:43:54 -07003011 }
3012 }
3013 break;
3014
3015 case llvm::Instruction::Call: {
buzbeefa57c472012-11-21 12:06:18 -08003016 llvm::CallInst* call_inst = llvm::dyn_cast<llvm::CallInst>(inst);
3017 llvm::Function* callee = call_inst->getCalledFunction();
buzbee0967a252012-09-14 10:43:54 -07003018 greenland::IntrinsicHelper::IntrinsicId id =
buzbeefa57c472012-11-21 12:06:18 -08003019 cu->intrinsic_helper->GetIntrinsicId(callee);
buzbee0967a252012-09-14 10:43:54 -07003020 switch (id) {
3021 case greenland::IntrinsicHelper::AllocaShadowFrame:
3022 case greenland::IntrinsicHelper::SetShadowFrameEntry:
3023 case greenland::IntrinsicHelper::PopShadowFrame:
TDYa1278e950c12012-11-02 09:58:19 -07003024 case greenland::IntrinsicHelper::SetVReg:
buzbee0967a252012-09-14 10:43:54 -07003025 // Ignore shadow frame stuff for quick compiler
3026 break;
3027 case greenland::IntrinsicHelper::CopyInt:
3028 case greenland::IntrinsicHelper::CopyObj:
3029 case greenland::IntrinsicHelper::CopyFloat:
3030 case greenland::IntrinsicHelper::CopyLong:
3031 case greenland::IntrinsicHelper::CopyDouble:
buzbeefa57c472012-11-21 12:06:18 -08003032 CvtCopy(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003033 break;
3034 case greenland::IntrinsicHelper::ConstInt:
3035 case greenland::IntrinsicHelper::ConstObj:
3036 case greenland::IntrinsicHelper::ConstLong:
3037 case greenland::IntrinsicHelper::ConstFloat:
3038 case greenland::IntrinsicHelper::ConstDouble:
buzbeefa57c472012-11-21 12:06:18 -08003039 CvtConst(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003040 break;
3041 case greenland::IntrinsicHelper::DivInt:
3042 case greenland::IntrinsicHelper::DivLong:
buzbeefa57c472012-11-21 12:06:18 -08003043 CvtBinOp(cu, kOpDiv, inst);
buzbee0967a252012-09-14 10:43:54 -07003044 break;
3045 case greenland::IntrinsicHelper::RemInt:
3046 case greenland::IntrinsicHelper::RemLong:
buzbeefa57c472012-11-21 12:06:18 -08003047 CvtBinOp(cu, kOpRem, inst);
buzbee0967a252012-09-14 10:43:54 -07003048 break;
3049 case greenland::IntrinsicHelper::MethodInfo:
3050 // Already dealt with - just ignore it here.
3051 break;
3052 case greenland::IntrinsicHelper::CheckSuspend:
buzbee02031b12012-11-23 09:41:35 -08003053 cg->GenSuspendTest(cu, 0 /* opt_flags already applied */);
buzbee0967a252012-09-14 10:43:54 -07003054 break;
3055 case greenland::IntrinsicHelper::HLInvokeObj:
3056 case greenland::IntrinsicHelper::HLInvokeFloat:
3057 case greenland::IntrinsicHelper::HLInvokeDouble:
3058 case greenland::IntrinsicHelper::HLInvokeLong:
3059 case greenland::IntrinsicHelper::HLInvokeInt:
buzbeefa57c472012-11-21 12:06:18 -08003060 CvtInvoke(cu, call_inst, false /* is_void */, false /* new_array */);
buzbee0967a252012-09-14 10:43:54 -07003061 break;
3062 case greenland::IntrinsicHelper::HLInvokeVoid:
buzbeefa57c472012-11-21 12:06:18 -08003063 CvtInvoke(cu, call_inst, true /* is_void */, false /* new_array */);
buzbee0967a252012-09-14 10:43:54 -07003064 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003065 case greenland::IntrinsicHelper::HLFilledNewArray:
buzbeefa57c472012-11-21 12:06:18 -08003066 CvtInvoke(cu, call_inst, false /* is_void */, true /* new_array */);
buzbee0967a252012-09-14 10:43:54 -07003067 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003068 case greenland::IntrinsicHelper::HLFillArrayData:
buzbeefa57c472012-11-21 12:06:18 -08003069 CvtFillArrayData(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003070 break;
3071 case greenland::IntrinsicHelper::ConstString:
buzbeefa57c472012-11-21 12:06:18 -08003072 CvtConstObject(cu, call_inst, true /* is_string */);
buzbee0967a252012-09-14 10:43:54 -07003073 break;
3074 case greenland::IntrinsicHelper::ConstClass:
buzbeefa57c472012-11-21 12:06:18 -08003075 CvtConstObject(cu, call_inst, false /* is_string */);
buzbee0967a252012-09-14 10:43:54 -07003076 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003077 case greenland::IntrinsicHelper::HLCheckCast:
buzbeefa57c472012-11-21 12:06:18 -08003078 CvtCheckCast(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003079 break;
3080 case greenland::IntrinsicHelper::NewInstance:
buzbeefa57c472012-11-21 12:06:18 -08003081 CvtNewInstance(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003082 break;
3083 case greenland::IntrinsicHelper::HLSgetObject:
buzbeefa57c472012-11-21 12:06:18 -08003084 CvtSget(cu, call_inst, false /* wide */, true /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003085 break;
3086 case greenland::IntrinsicHelper::HLSget:
3087 case greenland::IntrinsicHelper::HLSgetFloat:
3088 case greenland::IntrinsicHelper::HLSgetBoolean:
3089 case greenland::IntrinsicHelper::HLSgetByte:
3090 case greenland::IntrinsicHelper::HLSgetChar:
3091 case greenland::IntrinsicHelper::HLSgetShort:
buzbeefa57c472012-11-21 12:06:18 -08003092 CvtSget(cu, call_inst, false /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003093 break;
3094 case greenland::IntrinsicHelper::HLSgetWide:
3095 case greenland::IntrinsicHelper::HLSgetDouble:
buzbeefa57c472012-11-21 12:06:18 -08003096 CvtSget(cu, call_inst, true /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003097 break;
3098 case greenland::IntrinsicHelper::HLSput:
3099 case greenland::IntrinsicHelper::HLSputFloat:
3100 case greenland::IntrinsicHelper::HLSputBoolean:
3101 case greenland::IntrinsicHelper::HLSputByte:
3102 case greenland::IntrinsicHelper::HLSputChar:
3103 case greenland::IntrinsicHelper::HLSputShort:
buzbeefa57c472012-11-21 12:06:18 -08003104 CvtSput(cu, call_inst, false /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003105 break;
3106 case greenland::IntrinsicHelper::HLSputWide:
3107 case greenland::IntrinsicHelper::HLSputDouble:
buzbeefa57c472012-11-21 12:06:18 -08003108 CvtSput(cu, call_inst, true /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003109 break;
3110 case greenland::IntrinsicHelper::HLSputObject:
buzbeefa57c472012-11-21 12:06:18 -08003111 CvtSput(cu, call_inst, false /* wide */, true /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003112 break;
3113 case greenland::IntrinsicHelper::GetException:
buzbeefa57c472012-11-21 12:06:18 -08003114 CvtMoveException(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003115 break;
TDYa127f71bf5a2012-07-29 20:09:52 -07003116 case greenland::IntrinsicHelper::HLThrowException:
buzbeefa57c472012-11-21 12:06:18 -08003117 CvtThrow(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003118 break;
3119 case greenland::IntrinsicHelper::MonitorEnter:
buzbeefa57c472012-11-21 12:06:18 -08003120 CvtMonitorEnterExit(cu, true /* is_enter */, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003121 break;
3122 case greenland::IntrinsicHelper::MonitorExit:
buzbeefa57c472012-11-21 12:06:18 -08003123 CvtMonitorEnterExit(cu, false /* is_enter */, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003124 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003125 case greenland::IntrinsicHelper::OptArrayLength:
buzbeefa57c472012-11-21 12:06:18 -08003126 CvtArrayLength(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003127 break;
3128 case greenland::IntrinsicHelper::NewArray:
buzbeefa57c472012-11-21 12:06:18 -08003129 CvtNewArray(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003130 break;
3131 case greenland::IntrinsicHelper::InstanceOf:
buzbeefa57c472012-11-21 12:06:18 -08003132 CvtInstanceOf(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003133 break;
3134
3135 case greenland::IntrinsicHelper::HLArrayGet:
3136 case greenland::IntrinsicHelper::HLArrayGetObject:
3137 case greenland::IntrinsicHelper::HLArrayGetFloat:
buzbeefa57c472012-11-21 12:06:18 -08003138 CvtAget(cu, call_inst, kWord, 2);
buzbee0967a252012-09-14 10:43:54 -07003139 break;
3140 case greenland::IntrinsicHelper::HLArrayGetWide:
3141 case greenland::IntrinsicHelper::HLArrayGetDouble:
buzbeefa57c472012-11-21 12:06:18 -08003142 CvtAget(cu, call_inst, kLong, 3);
buzbee0967a252012-09-14 10:43:54 -07003143 break;
3144 case greenland::IntrinsicHelper::HLArrayGetBoolean:
buzbeefa57c472012-11-21 12:06:18 -08003145 CvtAget(cu, call_inst, kUnsignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003146 break;
3147 case greenland::IntrinsicHelper::HLArrayGetByte:
buzbeefa57c472012-11-21 12:06:18 -08003148 CvtAget(cu, call_inst, kSignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003149 break;
3150 case greenland::IntrinsicHelper::HLArrayGetChar:
buzbeefa57c472012-11-21 12:06:18 -08003151 CvtAget(cu, call_inst, kUnsignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003152 break;
3153 case greenland::IntrinsicHelper::HLArrayGetShort:
buzbeefa57c472012-11-21 12:06:18 -08003154 CvtAget(cu, call_inst, kSignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003155 break;
3156
3157 case greenland::IntrinsicHelper::HLArrayPut:
3158 case greenland::IntrinsicHelper::HLArrayPutFloat:
buzbeefa57c472012-11-21 12:06:18 -08003159 CvtAputPrimitive(cu, call_inst, kWord, 2);
buzbee0967a252012-09-14 10:43:54 -07003160 break;
3161 case greenland::IntrinsicHelper::HLArrayPutObject:
buzbeefa57c472012-11-21 12:06:18 -08003162 CvtAputObj(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003163 break;
3164 case greenland::IntrinsicHelper::HLArrayPutWide:
3165 case greenland::IntrinsicHelper::HLArrayPutDouble:
buzbeefa57c472012-11-21 12:06:18 -08003166 CvtAputPrimitive(cu, call_inst, kLong, 3);
buzbee0967a252012-09-14 10:43:54 -07003167 break;
3168 case greenland::IntrinsicHelper::HLArrayPutBoolean:
buzbeefa57c472012-11-21 12:06:18 -08003169 CvtAputPrimitive(cu, call_inst, kUnsignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003170 break;
3171 case greenland::IntrinsicHelper::HLArrayPutByte:
buzbeefa57c472012-11-21 12:06:18 -08003172 CvtAputPrimitive(cu, call_inst, kSignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003173 break;
3174 case greenland::IntrinsicHelper::HLArrayPutChar:
buzbeefa57c472012-11-21 12:06:18 -08003175 CvtAputPrimitive(cu, call_inst, kUnsignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003176 break;
3177 case greenland::IntrinsicHelper::HLArrayPutShort:
buzbeefa57c472012-11-21 12:06:18 -08003178 CvtAputPrimitive(cu, call_inst, kSignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003179 break;
3180
3181 case greenland::IntrinsicHelper::HLIGet:
3182 case greenland::IntrinsicHelper::HLIGetFloat:
buzbeefa57c472012-11-21 12:06:18 -08003183 CvtIget(cu, call_inst, kWord, false /* is_wide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003184 break;
3185 case greenland::IntrinsicHelper::HLIGetObject:
buzbeefa57c472012-11-21 12:06:18 -08003186 CvtIget(cu, call_inst, kWord, false /* is_wide */, true /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003187 break;
3188 case greenland::IntrinsicHelper::HLIGetWide:
3189 case greenland::IntrinsicHelper::HLIGetDouble:
buzbeefa57c472012-11-21 12:06:18 -08003190 CvtIget(cu, call_inst, kLong, true /* is_wide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003191 break;
3192 case greenland::IntrinsicHelper::HLIGetBoolean:
buzbeefa57c472012-11-21 12:06:18 -08003193 CvtIget(cu, call_inst, kUnsignedByte, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003194 false /* obj */);
3195 break;
3196 case greenland::IntrinsicHelper::HLIGetByte:
buzbeefa57c472012-11-21 12:06:18 -08003197 CvtIget(cu, call_inst, kSignedByte, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003198 false /* obj */);
3199 break;
3200 case greenland::IntrinsicHelper::HLIGetChar:
buzbeefa57c472012-11-21 12:06:18 -08003201 CvtIget(cu, call_inst, kUnsignedHalf, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003202 false /* obj */);
3203 break;
3204 case greenland::IntrinsicHelper::HLIGetShort:
buzbeefa57c472012-11-21 12:06:18 -08003205 CvtIget(cu, call_inst, kSignedHalf, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003206 false /* obj */);
3207 break;
3208
3209 case greenland::IntrinsicHelper::HLIPut:
3210 case greenland::IntrinsicHelper::HLIPutFloat:
buzbeefa57c472012-11-21 12:06:18 -08003211 CvtIput(cu, call_inst, kWord, false /* is_wide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003212 break;
3213 case greenland::IntrinsicHelper::HLIPutObject:
buzbeefa57c472012-11-21 12:06:18 -08003214 CvtIput(cu, call_inst, kWord, false /* is_wide */, true /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003215 break;
3216 case greenland::IntrinsicHelper::HLIPutWide:
3217 case greenland::IntrinsicHelper::HLIPutDouble:
buzbeefa57c472012-11-21 12:06:18 -08003218 CvtIput(cu, call_inst, kLong, true /* is_wide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003219 break;
3220 case greenland::IntrinsicHelper::HLIPutBoolean:
buzbeefa57c472012-11-21 12:06:18 -08003221 CvtIput(cu, call_inst, kUnsignedByte, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003222 false /* obj */);
3223 break;
3224 case greenland::IntrinsicHelper::HLIPutByte:
buzbeefa57c472012-11-21 12:06:18 -08003225 CvtIput(cu, call_inst, kSignedByte, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003226 false /* obj */);
3227 break;
3228 case greenland::IntrinsicHelper::HLIPutChar:
buzbeefa57c472012-11-21 12:06:18 -08003229 CvtIput(cu, call_inst, kUnsignedHalf, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003230 false /* obj */);
3231 break;
3232 case greenland::IntrinsicHelper::HLIPutShort:
buzbeefa57c472012-11-21 12:06:18 -08003233 CvtIput(cu, call_inst, kSignedHalf, false /* is_wide */,
buzbee0967a252012-09-14 10:43:54 -07003234 false /* obj */);
3235 break;
3236
3237 case greenland::IntrinsicHelper::IntToChar:
buzbeefa57c472012-11-21 12:06:18 -08003238 CvtIntNarrowing(cu, call_inst, Instruction::INT_TO_CHAR);
buzbee0967a252012-09-14 10:43:54 -07003239 break;
3240 case greenland::IntrinsicHelper::IntToShort:
buzbeefa57c472012-11-21 12:06:18 -08003241 CvtIntNarrowing(cu, call_inst, Instruction::INT_TO_SHORT);
buzbee0967a252012-09-14 10:43:54 -07003242 break;
3243 case greenland::IntrinsicHelper::IntToByte:
buzbeefa57c472012-11-21 12:06:18 -08003244 CvtIntNarrowing(cu, call_inst, Instruction::INT_TO_BYTE);
buzbee0967a252012-09-14 10:43:54 -07003245 break;
3246
TDYa1274ec8ccd2012-08-11 07:04:57 -07003247 case greenland::IntrinsicHelper::F2I:
3248 case greenland::IntrinsicHelper::D2I:
3249 case greenland::IntrinsicHelper::F2L:
3250 case greenland::IntrinsicHelper::D2L:
buzbeefa57c472012-11-21 12:06:18 -08003251 CvtFPToInt(cu, call_inst);
TDYa1274ec8ccd2012-08-11 07:04:57 -07003252 break;
3253
buzbee0967a252012-09-14 10:43:54 -07003254 case greenland::IntrinsicHelper::CmplFloat:
buzbeefa57c472012-11-21 12:06:18 -08003255 CvtFPCompare(cu, call_inst, Instruction::CMPL_FLOAT);
buzbee0967a252012-09-14 10:43:54 -07003256 break;
3257 case greenland::IntrinsicHelper::CmpgFloat:
buzbeefa57c472012-11-21 12:06:18 -08003258 CvtFPCompare(cu, call_inst, Instruction::CMPG_FLOAT);
buzbee0967a252012-09-14 10:43:54 -07003259 break;
3260 case greenland::IntrinsicHelper::CmplDouble:
buzbeefa57c472012-11-21 12:06:18 -08003261 CvtFPCompare(cu, call_inst, Instruction::CMPL_DOUBLE);
buzbee0967a252012-09-14 10:43:54 -07003262 break;
3263 case greenland::IntrinsicHelper::CmpgDouble:
buzbeefa57c472012-11-21 12:06:18 -08003264 CvtFPCompare(cu, call_inst, Instruction::CMPG_DOUBLE);
buzbee0967a252012-09-14 10:43:54 -07003265 break;
3266
3267 case greenland::IntrinsicHelper::CmpLong:
buzbeefa57c472012-11-21 12:06:18 -08003268 CvtLongCompare(cu, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003269 break;
3270
3271 case greenland::IntrinsicHelper::SHLLong:
buzbeefa57c472012-11-21 12:06:18 -08003272 CvtShiftOp(cu, Instruction::SHL_LONG, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003273 break;
3274 case greenland::IntrinsicHelper::SHRLong:
buzbeefa57c472012-11-21 12:06:18 -08003275 CvtShiftOp(cu, Instruction::SHR_LONG, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003276 break;
3277 case greenland::IntrinsicHelper::USHRLong:
buzbeefa57c472012-11-21 12:06:18 -08003278 CvtShiftOp(cu, Instruction::USHR_LONG, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003279 break;
3280 case greenland::IntrinsicHelper::SHLInt:
buzbeefa57c472012-11-21 12:06:18 -08003281 CvtShiftOp(cu, Instruction::SHL_INT, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003282 break;
3283 case greenland::IntrinsicHelper::SHRInt:
buzbeefa57c472012-11-21 12:06:18 -08003284 CvtShiftOp(cu, Instruction::SHR_INT, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003285 break;
3286 case greenland::IntrinsicHelper::USHRInt:
buzbeefa57c472012-11-21 12:06:18 -08003287 CvtShiftOp(cu, Instruction::USHR_INT, call_inst);
buzbee0967a252012-09-14 10:43:54 -07003288 break;
3289
3290 case greenland::IntrinsicHelper::CatchTargets: {
buzbeefa57c472012-11-21 12:06:18 -08003291 llvm::SwitchInst* sw_inst =
3292 llvm::dyn_cast<llvm::SwitchInst>(next_it);
3293 DCHECK(sw_inst != NULL);
buzbee0967a252012-09-14 10:43:54 -07003294 /*
3295 * Discard the edges and the following conditional branch.
3296 * Do a direct branch to the default target (which is the
3297 * "work" portion of the pair.
3298 * TODO: awful code layout - rework
3299 */
buzbeefa57c472012-11-21 12:06:18 -08003300 llvm::BasicBlock* target_bb = sw_inst->getDefaultDest();
3301 DCHECK(target_bb != NULL);
buzbee02031b12012-11-23 09:41:35 -08003302 cg->OpUnconditionalBranch(cu, cu->block_to_label_map.Get(target_bb));
buzbee0967a252012-09-14 10:43:54 -07003303 ++it;
3304 // Set next bb to default target - improves code layout
buzbeefa57c472012-11-21 12:06:18 -08003305 next_bb = target_bb;
buzbee0967a252012-09-14 10:43:54 -07003306 }
3307 break;
3308
3309 default:
buzbeefa57c472012-11-21 12:06:18 -08003310 LOG(FATAL) << "Unexpected intrinsic " << cu->intrinsic_helper->GetName(id);
buzbee0967a252012-09-14 10:43:54 -07003311 }
3312 }
3313 break;
3314
buzbeefa57c472012-11-21 12:06:18 -08003315 case llvm::Instruction::Br: CvtBr(cu, inst); break;
3316 case llvm::Instruction::Add: CvtBinOp(cu, kOpAdd, inst); break;
3317 case llvm::Instruction::Sub: CvtBinOp(cu, kOpSub, inst); break;
3318 case llvm::Instruction::Mul: CvtBinOp(cu, kOpMul, inst); break;
3319 case llvm::Instruction::SDiv: CvtBinOp(cu, kOpDiv, inst); break;
3320 case llvm::Instruction::SRem: CvtBinOp(cu, kOpRem, inst); break;
3321 case llvm::Instruction::And: CvtBinOp(cu, kOpAnd, inst); break;
3322 case llvm::Instruction::Or: CvtBinOp(cu, kOpOr, inst); break;
3323 case llvm::Instruction::Xor: CvtBinOp(cu, kOpXor, inst); break;
3324 case llvm::Instruction::PHI: CvtPhi(cu, inst); break;
3325 case llvm::Instruction::Ret: CvtRet(cu, inst); break;
3326 case llvm::Instruction::FAdd: CvtBinFPOp(cu, kOpAdd, inst); break;
3327 case llvm::Instruction::FSub: CvtBinFPOp(cu, kOpSub, inst); break;
3328 case llvm::Instruction::FMul: CvtBinFPOp(cu, kOpMul, inst); break;
3329 case llvm::Instruction::FDiv: CvtBinFPOp(cu, kOpDiv, inst); break;
3330 case llvm::Instruction::FRem: CvtBinFPOp(cu, kOpRem, inst); break;
3331 case llvm::Instruction::SIToFP: CvtIntToFP(cu, inst); break;
3332 case llvm::Instruction::FPTrunc: CvtDoubleToFloat(cu, inst); break;
3333 case llvm::Instruction::FPExt: CvtFloatToDouble(cu, inst); break;
3334 case llvm::Instruction::Trunc: CvtTrunc(cu, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003335
buzbeefa57c472012-11-21 12:06:18 -08003336 case llvm::Instruction::ZExt: CvtIntExt(cu, inst, false /* signed */);
buzbee0967a252012-09-14 10:43:54 -07003337 break;
buzbeefa57c472012-11-21 12:06:18 -08003338 case llvm::Instruction::SExt: CvtIntExt(cu, inst, true /* signed */);
buzbee0967a252012-09-14 10:43:54 -07003339 break;
3340
buzbeefa57c472012-11-21 12:06:18 -08003341 case llvm::Instruction::Switch: CvtSwitch(cu, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003342
3343 case llvm::Instruction::Unreachable:
3344 break; // FIXME: can we really ignore these?
3345
3346 case llvm::Instruction::Shl:
3347 case llvm::Instruction::LShr:
3348 case llvm::Instruction::AShr:
3349 case llvm::Instruction::Invoke:
3350 case llvm::Instruction::FPToUI:
TDYa1274ec8ccd2012-08-11 07:04:57 -07003351 case llvm::Instruction::FPToSI:
buzbee0967a252012-09-14 10:43:54 -07003352 case llvm::Instruction::UIToFP:
3353 case llvm::Instruction::PtrToInt:
3354 case llvm::Instruction::IntToPtr:
3355 case llvm::Instruction::FCmp:
3356 case llvm::Instruction::URem:
3357 case llvm::Instruction::UDiv:
3358 case llvm::Instruction::Resume:
3359 case llvm::Instruction::Alloca:
3360 case llvm::Instruction::GetElementPtr:
3361 case llvm::Instruction::Fence:
3362 case llvm::Instruction::AtomicCmpXchg:
3363 case llvm::Instruction::AtomicRMW:
3364 case llvm::Instruction::BitCast:
3365 case llvm::Instruction::VAArg:
3366 case llvm::Instruction::Select:
3367 case llvm::Instruction::UserOp1:
3368 case llvm::Instruction::UserOp2:
3369 case llvm::Instruction::ExtractElement:
3370 case llvm::Instruction::InsertElement:
3371 case llvm::Instruction::ShuffleVector:
3372 case llvm::Instruction::ExtractValue:
3373 case llvm::Instruction::InsertValue:
3374 case llvm::Instruction::LandingPad:
3375 case llvm::Instruction::IndirectBr:
3376 case llvm::Instruction::Load:
3377 case llvm::Instruction::Store:
3378 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3379
3380 default:
3381 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3382 break;
buzbeead8f15e2012-06-18 14:49:45 -07003383 }
3384 }
buzbee2cfc6392012-05-07 14:51:40 -07003385
buzbeefa57c472012-11-21 12:06:18 -08003386 if (head_lir != NULL) {
3387 ApplyLocalOptimizations(cu, head_lir, cu->last_lir_insn);
buzbee2cfc6392012-05-07 14:51:40 -07003388 }
buzbeefa57c472012-11-21 12:06:18 -08003389 if (next_bb != NULL) {
3390 bb = next_bb;
3391 next_bb = NULL;
buzbee6969d502012-06-15 16:40:31 -07003392 }
buzbee6969d502012-06-15 16:40:31 -07003393 }
buzbee2cfc6392012-05-07 14:51:40 -07003394 return false;
3395}
3396
3397/*
3398 * Convert LLVM_IR to MIR:
3399 * o Iterate through the LLVM_IR and construct a graph using
3400 * standard MIR building blocks.
3401 * o Perform a basic-block optimization pass to remove unnecessary
3402 * store/load sequences.
3403 * o Convert the LLVM Value operands into RegLocations where applicable.
buzbeefa57c472012-11-21 12:06:18 -08003404 * o Create ssa_rep def/use operand arrays for each converted LLVM opcode
buzbee2cfc6392012-05-07 14:51:40 -07003405 * o Perform register promotion
3406 * o Iterate through the graph a basic block at a time, generating
3407 * LIR.
3408 * o Assemble LIR as usual.
3409 * o Profit.
3410 */
buzbeefa57c472012-11-21 12:06:18 -08003411void MethodBitcode2LIR(CompilationUnit* cu)
buzbee2cfc6392012-05-07 14:51:40 -07003412{
buzbee02031b12012-11-23 09:41:35 -08003413 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -08003414 llvm::Function* func = cu->func;
3415 int num_basic_blocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003416 // Allocate a list for LIR basic block labels
buzbeefa57c472012-11-21 12:06:18 -08003417 cu->block_label_list =
3418 static_cast<LIR*>(NewMem(cu, sizeof(LIR) * num_basic_blocks, true, kAllocLIR));
3419 LIR* label_list = cu->block_label_list;
3420 int next_label = 0;
buzbee28c9a832012-11-21 15:39:13 -08003421 for (llvm::Function::iterator i = func->begin(), e = func->end(); i != e; ++i) {
buzbeefa57c472012-11-21 12:06:18 -08003422 cu->block_to_label_map.Put(static_cast<llvm::BasicBlock*>(i),
3423 &label_list[next_label++]);
buzbee2cfc6392012-05-07 14:51:40 -07003424 }
buzbeead8f15e2012-06-18 14:49:45 -07003425
3426 /*
buzbeefa57c472012-11-21 12:06:18 -08003427 * Keep honest - clear reg_locations, Value => RegLocation,
buzbeead8f15e2012-06-18 14:49:45 -07003428 * promotion map and VmapTables.
3429 */
buzbeefa57c472012-11-21 12:06:18 -08003430 cu->loc_map.clear(); // Start fresh
3431 cu->reg_location = NULL;
buzbee28c9a832012-11-21 15:39:13 -08003432 for (int i = 0; i < cu->num_dalvik_registers + cu->num_compiler_temps + 1; i++) {
buzbeefa57c472012-11-21 12:06:18 -08003433 cu->promotion_map[i].core_location = kLocDalvikFrame;
3434 cu->promotion_map[i].fp_location = kLocDalvikFrame;
buzbeead8f15e2012-06-18 14:49:45 -07003435 }
buzbeefa57c472012-11-21 12:06:18 -08003436 cu->core_spill_mask = 0;
3437 cu->num_core_spills = 0;
3438 cu->fp_spill_mask = 0;
3439 cu->num_fp_spills = 0;
3440 cu->core_vmap_table.clear();
3441 cu->fp_vmap_table.clear();
buzbeead8f15e2012-06-18 14:49:45 -07003442
3443 /*
3444 * At this point, we've lost all knowledge of register promotion.
3445 * Rebuild that info from the MethodInfo intrinsic (if it
buzbeeca7a5e42012-08-20 11:12:18 -07003446 * exists - not required for correctness). Normally, this will
3447 * be the first instruction we encounter, so we won't have to iterate
3448 * through everything.
buzbeead8f15e2012-06-18 14:49:45 -07003449 */
buzbee28c9a832012-11-21 15:39:13 -08003450 for (llvm::inst_iterator i = llvm::inst_begin(func), e = llvm::inst_end(func); i != e; ++i) {
buzbeefa57c472012-11-21 12:06:18 -08003451 llvm::CallInst* call_inst = llvm::dyn_cast<llvm::CallInst>(&*i);
3452 if (call_inst != NULL) {
3453 llvm::Function* callee = call_inst->getCalledFunction();
buzbeeca7a5e42012-08-20 11:12:18 -07003454 greenland::IntrinsicHelper::IntrinsicId id =
buzbeefa57c472012-11-21 12:06:18 -08003455 cu->intrinsic_helper->GetIntrinsicId(callee);
buzbeeca7a5e42012-08-20 11:12:18 -07003456 if (id == greenland::IntrinsicHelper::MethodInfo) {
buzbeefa57c472012-11-21 12:06:18 -08003457 if (cu->verbose) {
buzbeeca7a5e42012-08-20 11:12:18 -07003458 LOG(INFO) << "Found MethodInfo";
3459 }
buzbeefa57c472012-11-21 12:06:18 -08003460 llvm::MDNode* reg_info_node = call_inst->getMetadata("RegInfo");
3461 if (reg_info_node != NULL) {
3462 llvm::ConstantInt* num_ins_value =
3463 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(0));
3464 llvm::ConstantInt* num_regs_value =
3465 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(1));
3466 llvm::ConstantInt* num_outs_value =
3467 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(2));
3468 llvm::ConstantInt* num_compiler_temps_value =
3469 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(3));
3470 llvm::ConstantInt* num_ssa_regs_value =
3471 static_cast<llvm::ConstantInt*>(reg_info_node->getOperand(4));
3472 if (cu->verbose) {
3473 LOG(INFO) << "RegInfo - Ins:" << num_ins_value->getZExtValue()
3474 << ", Regs:" << num_regs_value->getZExtValue()
3475 << ", Outs:" << num_outs_value->getZExtValue()
3476 << ", CTemps:" << num_compiler_temps_value->getZExtValue()
3477 << ", SSARegs:" << num_ssa_regs_value->getZExtValue();
buzbeeca7a5e42012-08-20 11:12:18 -07003478 }
3479 }
buzbeefa57c472012-11-21 12:06:18 -08003480 llvm::MDNode* pmap_info_node = call_inst->getMetadata("PromotionMap");
3481 if (pmap_info_node != NULL) {
3482 int elems = pmap_info_node->getNumOperands();
3483 if (cu->verbose) {
buzbeeca7a5e42012-08-20 11:12:18 -07003484 LOG(INFO) << "PMap size: " << elems;
3485 }
3486 for (int i = 0; i < elems; i++) {
buzbeefa57c472012-11-21 12:06:18 -08003487 llvm::ConstantInt* raw_map_data =
3488 static_cast<llvm::ConstantInt*>(pmap_info_node->getOperand(i));
3489 uint32_t map_data = raw_map_data->getZExtValue();
3490 PromotionMap* p = &cu->promotion_map[i];
3491 p->first_in_pair = (map_data >> 24) & 0xff;
3492 p->FpReg = (map_data >> 16) & 0xff;
3493 p->core_reg = (map_data >> 8) & 0xff;
3494 p->fp_location = static_cast<RegLocationType>((map_data >> 4) & 0xf);
3495 if (p->fp_location == kLocPhysReg) {
3496 RecordFpPromotion(cu, p->FpReg, i);
buzbeeca7a5e42012-08-20 11:12:18 -07003497 }
buzbeefa57c472012-11-21 12:06:18 -08003498 p->core_location = static_cast<RegLocationType>(map_data & 0xf);
3499 if (p->core_location == kLocPhysReg) {
3500 RecordCorePromotion(cu, p->core_reg, i);
buzbeeca7a5e42012-08-20 11:12:18 -07003501 }
3502 }
buzbeefa57c472012-11-21 12:06:18 -08003503 if (cu->verbose) {
3504 DumpPromotionMap(cu);
buzbeeca7a5e42012-08-20 11:12:18 -07003505 }
3506 }
3507 break;
3508 }
3509 }
3510 }
buzbee02031b12012-11-23 09:41:35 -08003511 cg->AdjustSpillMask(cu);
buzbeefa57c472012-11-21 12:06:18 -08003512 cu->frame_size = ComputeFrameSize(cu);
buzbeead8f15e2012-06-18 14:49:45 -07003513
3514 // Create RegLocations for arguments
buzbeefa57c472012-11-21 12:06:18 -08003515 llvm::Function::arg_iterator it(cu->func->arg_begin());
3516 llvm::Function::arg_iterator it_end(cu->func->arg_end());
buzbeead8f15e2012-06-18 14:49:45 -07003517 for (; it != it_end; ++it) {
3518 llvm::Value* val = it;
buzbeefa57c472012-11-21 12:06:18 -08003519 CreateLocFromValue(cu, val);
buzbeead8f15e2012-06-18 14:49:45 -07003520 }
3521 // Create RegLocations for all non-argument defintions
buzbee28c9a832012-11-21 15:39:13 -08003522 for (llvm::inst_iterator i = llvm::inst_begin(func), e = llvm::inst_end(func); i != e; ++i) {
buzbeead8f15e2012-06-18 14:49:45 -07003523 llvm::Value* val = &*i;
3524 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
buzbeefa57c472012-11-21 12:06:18 -08003525 CreateLocFromValue(cu, val);
buzbeead8f15e2012-06-18 14:49:45 -07003526 }
3527 }
3528
buzbee2cfc6392012-05-07 14:51:40 -07003529 // Walk the blocks, generating code.
buzbee28c9a832012-11-21 15:39:13 -08003530 for (llvm::Function::iterator i = cu->func->begin(), e = cu->func->end(); i != e; ++i) {
buzbeefa57c472012-11-21 12:06:18 -08003531 BitcodeBlockCodeGen(cu, static_cast<llvm::BasicBlock*>(i));
buzbee2cfc6392012-05-07 14:51:40 -07003532 }
3533
buzbee02031b12012-11-23 09:41:35 -08003534 cg->HandleSuspendLaunchPads(cu);
buzbee2cfc6392012-05-07 14:51:40 -07003535
buzbee02031b12012-11-23 09:41:35 -08003536 cg->HandleThrowLaunchPads(cu);
buzbee2cfc6392012-05-07 14:51:40 -07003537
buzbee02031b12012-11-23 09:41:35 -08003538 cg->HandleIntrinsicLaunchPads(cu);
buzbee2cfc6392012-05-07 14:51:40 -07003539
buzbeefa57c472012-11-21 12:06:18 -08003540 cu->func->eraseFromParent();
3541 cu->func = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07003542}
3543
3544
3545} // namespace art