blob: 0115484d9bf2723d4cd802ba83873c60c2f3344a [file] [log] [blame]
buzbee2cfc6392012-05-07 14:51:40 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
buzbee2cfc6392012-05-07 14:51:40 -070017#include "object_utils.h"
18
19#include <llvm/Support/ToolOutputFile.h>
20#include <llvm/Bitcode/ReaderWriter.h>
21#include <llvm/Analysis/Verifier.h>
22#include <llvm/Metadata.h>
23#include <llvm/ADT/DepthFirstIterator.h>
24#include <llvm/Instruction.h>
25#include <llvm/Type.h>
26#include <llvm/Instructions.h>
27#include <llvm/Support/Casting.h>
buzbeead8f15e2012-06-18 14:49:45 -070028#include <llvm/Support/InstIterator.h>
buzbee2cfc6392012-05-07 14:51:40 -070029
buzbee1bc37c62012-11-20 13:35:41 -080030#include "../compiler_internals.h"
buzbeeeaf09bc2012-11-15 14:51:41 -080031#include "method_codegen_driver.h"
32#include "local_optimizations.h"
buzbee1bc37c62012-11-20 13:35:41 -080033#include "codegen_util.h"
34#include "ralloc_util.h"
buzbeeeaf09bc2012-11-15 14:51:41 -080035
buzbee8320f382012-09-11 16:29:42 -070036static const char* kLabelFormat = "%c0x%x_%d";
buzbee951c0a12012-10-03 16:31:39 -070037static const char kInvalidBlock = 0xff;
buzbee8320f382012-09-11 16:29:42 -070038static const char kNormalBlock = 'L';
39static const char kCatchBlock = 'C';
buzbee2cfc6392012-05-07 14:51:40 -070040
41namespace art {
buzbee1bc37c62012-11-20 13:35:41 -080042// TODO: unify badLoc
43const RegLocation badLoc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0,
44 INVALID_REG, INVALID_REG, INVALID_SREG,
45 INVALID_SREG};
buzbee52a77fc2012-11-20 19:50:46 -080046RegLocation GetLoc(CompilationUnit* cUnit, llvm::Value* val);
buzbee2cfc6392012-05-07 14:51:40 -070047
buzbee52a77fc2012-11-20 19:50:46 -080048llvm::BasicBlock* GetLLVMBlock(CompilationUnit* cUnit, int id)
buzbee2cfc6392012-05-07 14:51:40 -070049{
50 return cUnit->idToBlockMap.Get(id);
51}
52
buzbee52a77fc2012-11-20 19:50:46 -080053llvm::Value* GetLLVMValue(CompilationUnit* cUnit, int sReg)
buzbee2cfc6392012-05-07 14:51:40 -070054{
buzbee52a77fc2012-11-20 19:50:46 -080055 return reinterpret_cast<llvm::Value*>(GrowableListGetElement(&cUnit->llvmValues, sReg));
buzbee2cfc6392012-05-07 14:51:40 -070056}
57
58// Replace the placeholder value with the real definition
buzbee52a77fc2012-11-20 19:50:46 -080059void DefineValue(CompilationUnit* cUnit, llvm::Value* val, int sReg)
buzbee2cfc6392012-05-07 14:51:40 -070060{
buzbee52a77fc2012-11-20 19:50:46 -080061 llvm::Value* placeholder = GetLLVMValue(cUnit, sReg);
buzbee9a2487f2012-07-26 14:01:13 -070062 if (placeholder == NULL) {
63 // This can happen on instruction rewrite on verification failure
Bill Buzbeec9f40dd2012-08-15 11:35:25 -070064 LOG(WARNING) << "Null placeholder";
buzbee9a2487f2012-07-26 14:01:13 -070065 return;
66 }
buzbee2cfc6392012-05-07 14:51:40 -070067 placeholder->replaceAllUsesWith(val);
68 val->takeName(placeholder);
buzbeecbd6d442012-11-17 14:11:25 -080069 cUnit->llvmValues.elemList[sReg] = reinterpret_cast<uintptr_t>(val);
buzbee4be777b2012-07-12 14:38:18 -070070 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(placeholder);
71 DCHECK(inst != NULL);
72 inst->eraseFromParent();
TDYa1278e950c12012-11-02 09:58:19 -070073
74 // Set vreg for debugging
75 if (!cUnit->compiler->IsDebuggingSupported()) {
76 greenland::IntrinsicHelper::IntrinsicId id =
77 greenland::IntrinsicHelper::SetVReg;
78 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
79 int vReg = SRegToVReg(cUnit, sReg);
80 llvm::Value* tableSlot = cUnit->irb->getInt32(vReg);
81 llvm::Value* args[] = { tableSlot, val };
82 cUnit->irb->CreateCall(func, args);
83 }
buzbee2cfc6392012-05-07 14:51:40 -070084}
85
buzbee52a77fc2012-11-20 19:50:46 -080086llvm::Type* LlvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
buzbee2cfc6392012-05-07 14:51:40 -070087{
88 llvm::Type* res = NULL;
89 if (loc.wide) {
90 if (loc.fp)
buzbee4f1181f2012-06-22 13:52:12 -070091 res = cUnit->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070092 else
buzbee4f1181f2012-06-22 13:52:12 -070093 res = cUnit->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070094 } else {
95 if (loc.fp) {
buzbee4f1181f2012-06-22 13:52:12 -070096 res = cUnit->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -070097 } else {
98 if (loc.ref)
99 res = cUnit->irb->GetJObjectTy();
100 else
buzbee4f1181f2012-06-22 13:52:12 -0700101 res = cUnit->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -0700102 }
103 }
104 return res;
105}
106
buzbeead8f15e2012-06-18 14:49:45 -0700107/* Create an in-memory RegLocation from an llvm Value. */
buzbee52a77fc2012-11-20 19:50:46 -0800108void CreateLocFromValue(CompilationUnit* cUnit, llvm::Value* val)
buzbeead8f15e2012-06-18 14:49:45 -0700109{
110 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
111 std::string s(val->getName().str());
112 const char* valName = s.c_str();
buzbeead8f15e2012-06-18 14:49:45 -0700113 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
114 DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName;
115 int baseSReg = INVALID_SREG;
116 int subscript = -1;
117 sscanf(valName, "v%d_%d", &baseSReg, &subscript);
118 if ((baseSReg == INVALID_SREG) && (!strcmp(valName, "method"))) {
119 baseSReg = SSA_METHOD_BASEREG;
120 subscript = 0;
121 }
buzbeead8f15e2012-06-18 14:49:45 -0700122 DCHECK_NE(baseSReg, INVALID_SREG);
123 DCHECK_NE(subscript, -1);
124 // TODO: redo during C++'ification
125 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
126 INVALID_REG, INVALID_SREG, INVALID_SREG};
127 llvm::Type* ty = val->getType();
128 loc.wide = ((ty == cUnit->irb->getInt64Ty()) ||
129 (ty == cUnit->irb->getDoubleTy()));
130 loc.defined = true;
buzbeeca7a5e42012-08-20 11:12:18 -0700131 loc.home = false; // May change during promotion
buzbeead8f15e2012-06-18 14:49:45 -0700132 loc.sRegLow = baseSReg;
133 loc.origSReg = cUnit->locMap.size();
buzbeeca7a5e42012-08-20 11:12:18 -0700134 PromotionMap pMap = cUnit->promotionMap[baseSReg];
135 if (ty == cUnit->irb->getFloatTy()) {
136 loc.fp = true;
137 if (pMap.fpLocation == kLocPhysReg) {
buzbee52a77fc2012-11-20 19:50:46 -0800138 loc.lowReg = pMap.FpReg;
buzbeeca7a5e42012-08-20 11:12:18 -0700139 loc.location = kLocPhysReg;
140 loc.home = true;
141 }
142 } else if (ty == cUnit->irb->getDoubleTy()) {
143 loc.fp = true;
144 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
145 if ((pMap.fpLocation == kLocPhysReg) &&
146 (pMapHigh.fpLocation == kLocPhysReg) &&
buzbee52a77fc2012-11-20 19:50:46 -0800147 ((pMap.FpReg & 0x1) == 0) &&
148 (pMap.FpReg + 1 == pMapHigh.FpReg)) {
149 loc.lowReg = pMap.FpReg;
150 loc.highReg = pMapHigh.FpReg;
buzbeeca7a5e42012-08-20 11:12:18 -0700151 loc.location = kLocPhysReg;
152 loc.home = true;
153 }
154 } else if (ty == cUnit->irb->GetJObjectTy()) {
155 loc.ref = true;
156 if (pMap.coreLocation == kLocPhysReg) {
157 loc.lowReg = pMap.coreReg;
158 loc.location = kLocPhysReg;
159 loc.home = true;
160 }
161 } else if (ty == cUnit->irb->getInt64Ty()) {
162 loc.core = true;
163 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
164 if ((pMap.coreLocation == kLocPhysReg) &&
165 (pMapHigh.coreLocation == kLocPhysReg)) {
166 loc.lowReg = pMap.coreReg;
167 loc.highReg = pMapHigh.coreReg;
168 loc.location = kLocPhysReg;
169 loc.home = true;
170 }
171 } else {
172 loc.core = true;
173 if (pMap.coreLocation == kLocPhysReg) {
174 loc.lowReg = pMap.coreReg;
175 loc.location = kLocPhysReg;
176 loc.home = true;
177 }
178 }
179
180 if (cUnit->printMe && loc.home) {
181 if (loc.wide) {
buzbeecbd6d442012-11-17 14:11:25 -0800182 LOG(INFO) << "Promoted wide " << s << " to regs " << loc.lowReg << "/" << loc.highReg;
buzbeeca7a5e42012-08-20 11:12:18 -0700183 } else {
buzbeecbd6d442012-11-17 14:11:25 -0800184 LOG(INFO) << "Promoted " << s << " to reg " << loc.lowReg;
buzbeeca7a5e42012-08-20 11:12:18 -0700185 }
186 }
buzbeead8f15e2012-06-18 14:49:45 -0700187 cUnit->locMap.Put(val, loc);
188}
buzbee52a77fc2012-11-20 19:50:46 -0800189void InitIR(CompilationUnit* cUnit)
buzbee2cfc6392012-05-07 14:51:40 -0700190{
buzbee4df2bbd2012-10-11 14:46:06 -0700191 LLVMInfo* llvmInfo = cUnit->llvm_info;
192 if (llvmInfo == NULL) {
193 CompilerTls* tls = cUnit->compiler->GetTls();
194 CHECK(tls != NULL);
195 llvmInfo = static_cast<LLVMInfo*>(tls->GetLLVMInfo());
196 if (llvmInfo == NULL) {
197 llvmInfo = new LLVMInfo();
198 tls->SetLLVMInfo(llvmInfo);
199 }
200 }
201 cUnit->context = llvmInfo->GetLLVMContext();
202 cUnit->module = llvmInfo->GetLLVMModule();
203 cUnit->intrinsic_helper = llvmInfo->GetIntrinsicHelper();
204 cUnit->irb = llvmInfo->GetIRBuilder();
buzbee2cfc6392012-05-07 14:51:40 -0700205}
206
buzbee52a77fc2012-11-20 19:50:46 -0800207const char* LlvmSSAName(CompilationUnit* cUnit, int ssaReg) {
buzbee2cfc6392012-05-07 14:51:40 -0700208 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
209}
210
buzbee52a77fc2012-11-20 19:50:46 -0800211llvm::BasicBlock* FindCaseTarget(CompilationUnit* cUnit, uint32_t vaddr)
buzbeef58c12c2012-07-03 15:06:29 -0700212{
buzbee52a77fc2012-11-20 19:50:46 -0800213 BasicBlock* bb = FindBlock(cUnit, vaddr);
buzbeef58c12c2012-07-03 15:06:29 -0700214 DCHECK(bb != NULL);
buzbee52a77fc2012-11-20 19:50:46 -0800215 return GetLLVMBlock(cUnit, bb->id);
buzbeef58c12c2012-07-03 15:06:29 -0700216}
217
buzbee52a77fc2012-11-20 19:50:46 -0800218void ConvertPackedSwitch(CompilationUnit* cUnit, BasicBlock* bb,
buzbeef58c12c2012-07-03 15:06:29 -0700219 int32_t tableOffset, RegLocation rlSrc)
220{
221 const Instruction::PackedSwitchPayload* payload =
222 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
223 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
224
buzbee52a77fc2012-11-20 19:50:46 -0800225 llvm::Value* value = GetLLVMValue(cUnit, rlSrc.origSReg);
buzbeef58c12c2012-07-03 15:06:29 -0700226
227 llvm::SwitchInst* sw =
buzbee52a77fc2012-11-20 19:50:46 -0800228 cUnit->irb->CreateSwitch(value, GetLLVMBlock(cUnit, bb->fallThrough->id),
buzbeef58c12c2012-07-03 15:06:29 -0700229 payload->case_count);
230
231 for (uint16_t i = 0; i < payload->case_count; ++i) {
232 llvm::BasicBlock* llvmBB =
buzbee52a77fc2012-11-20 19:50:46 -0800233 FindCaseTarget(cUnit, cUnit->currentDalvikOffset + payload->targets[i]);
buzbeef58c12c2012-07-03 15:06:29 -0700234 sw->addCase(cUnit->irb->getInt32(payload->first_key + i), llvmBB);
235 }
236 llvm::MDNode* switchNode =
237 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
238 sw->setMetadata("SwitchTable", switchNode);
239 bb->taken = NULL;
240 bb->fallThrough = NULL;
241}
242
buzbee52a77fc2012-11-20 19:50:46 -0800243void ConvertSparseSwitch(CompilationUnit* cUnit, BasicBlock* bb,
buzbeea1da8a52012-07-09 14:00:21 -0700244 int32_t tableOffset, RegLocation rlSrc)
245{
246 const Instruction::SparseSwitchPayload* payload =
247 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
248 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
249
250 const int32_t* keys = payload->GetKeys();
251 const int32_t* targets = payload->GetTargets();
252
buzbee52a77fc2012-11-20 19:50:46 -0800253 llvm::Value* value = GetLLVMValue(cUnit, rlSrc.origSReg);
buzbeea1da8a52012-07-09 14:00:21 -0700254
255 llvm::SwitchInst* sw =
buzbee52a77fc2012-11-20 19:50:46 -0800256 cUnit->irb->CreateSwitch(value, GetLLVMBlock(cUnit, bb->fallThrough->id),
buzbeea1da8a52012-07-09 14:00:21 -0700257 payload->case_count);
258
259 for (size_t i = 0; i < payload->case_count; ++i) {
260 llvm::BasicBlock* llvmBB =
buzbee52a77fc2012-11-20 19:50:46 -0800261 FindCaseTarget(cUnit, cUnit->currentDalvikOffset + targets[i]);
buzbeea1da8a52012-07-09 14:00:21 -0700262 sw->addCase(cUnit->irb->getInt32(keys[i]), llvmBB);
263 }
264 llvm::MDNode* switchNode =
265 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
266 sw->setMetadata("SwitchTable", switchNode);
267 bb->taken = NULL;
268 bb->fallThrough = NULL;
269}
270
buzbee52a77fc2012-11-20 19:50:46 -0800271void ConvertSget(CompilationUnit* cUnit, int32_t fieldIndex,
buzbee8fa0fda2012-06-27 15:44:52 -0700272 greenland::IntrinsicHelper::IntrinsicId id,
273 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700274{
buzbee8fa0fda2012-06-27 15:44:52 -0700275 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700276 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700277 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
buzbee52a77fc2012-11-20 19:50:46 -0800278 DefineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700279}
280
buzbee52a77fc2012-11-20 19:50:46 -0800281void ConvertSput(CompilationUnit* cUnit, int32_t fieldIndex,
buzbee8fa0fda2012-06-27 15:44:52 -0700282 greenland::IntrinsicHelper::IntrinsicId id,
283 RegLocation rlSrc)
284{
285 llvm::SmallVector<llvm::Value*, 2> args;
286 args.push_back(cUnit->irb->getInt32(fieldIndex));
buzbee52a77fc2012-11-20 19:50:46 -0800287 args.push_back(GetLLVMValue(cUnit, rlSrc.origSReg));
buzbee8fa0fda2012-06-27 15:44:52 -0700288 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
289 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700290}
291
buzbee52a77fc2012-11-20 19:50:46 -0800292void ConvertFillArrayData(CompilationUnit* cUnit, int32_t offset,
buzbee101305f2012-06-28 18:00:56 -0700293 RegLocation rlArray)
294{
295 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700296 id = greenland::IntrinsicHelper::HLFillArrayData;
buzbee101305f2012-06-28 18:00:56 -0700297 llvm::SmallVector<llvm::Value*, 2> args;
298 args.push_back(cUnit->irb->getInt32(offset));
buzbee52a77fc2012-11-20 19:50:46 -0800299 args.push_back(GetLLVMValue(cUnit, rlArray.origSReg));
buzbee101305f2012-06-28 18:00:56 -0700300 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
301 cUnit->irb->CreateCall(intr, args);
302}
303
buzbee52a77fc2012-11-20 19:50:46 -0800304llvm::Value* EmitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
buzbee2cfc6392012-05-07 14:51:40 -0700305 RegLocation loc)
306{
307 greenland::IntrinsicHelper::IntrinsicId id;
308 if (loc.wide) {
309 if (loc.fp) {
310 id = greenland::IntrinsicHelper::ConstDouble;
311 } else {
312 id = greenland::IntrinsicHelper::ConstLong;
313 }
314 } else {
315 if (loc.fp) {
316 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700317 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700318 id = greenland::IntrinsicHelper::ConstObj;
319 } else {
320 id = greenland::IntrinsicHelper::ConstInt;
321 }
322 }
323 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
324 return cUnit->irb->CreateCall(intr, src);
325}
buzbeeb03f4872012-06-11 15:22:11 -0700326
buzbee52a77fc2012-11-20 19:50:46 -0800327void EmitPopShadowFrame(CompilationUnit* cUnit)
buzbeeb03f4872012-06-11 15:22:11 -0700328{
329 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
330 greenland::IntrinsicHelper::PopShadowFrame);
331 cUnit->irb->CreateCall(intr);
332}
333
buzbee52a77fc2012-11-20 19:50:46 -0800334llvm::Value* EmitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
buzbee2cfc6392012-05-07 14:51:40 -0700335 RegLocation loc)
336{
337 greenland::IntrinsicHelper::IntrinsicId id;
338 if (loc.wide) {
339 if (loc.fp) {
340 id = greenland::IntrinsicHelper::CopyDouble;
341 } else {
342 id = greenland::IntrinsicHelper::CopyLong;
343 }
344 } else {
345 if (loc.fp) {
346 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700347 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700348 id = greenland::IntrinsicHelper::CopyObj;
349 } else {
350 id = greenland::IntrinsicHelper::CopyInt;
351 }
352 }
353 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
354 return cUnit->irb->CreateCall(intr, src);
355}
356
buzbee52a77fc2012-11-20 19:50:46 -0800357void ConvertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
buzbee32412962012-06-26 16:27:56 -0700358{
359 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
360 greenland::IntrinsicHelper::GetException);
361 llvm::Value* res = cUnit->irb->CreateCall(func);
buzbee52a77fc2012-11-20 19:50:46 -0800362 DefineValue(cUnit, res, rlDest.origSReg);
buzbee32412962012-06-26 16:27:56 -0700363}
364
buzbee52a77fc2012-11-20 19:50:46 -0800365void ConvertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
buzbee32412962012-06-26 16:27:56 -0700366{
buzbee52a77fc2012-11-20 19:50:46 -0800367 llvm::Value* src = GetLLVMValue(cUnit, rlSrc.origSReg);
buzbee32412962012-06-26 16:27:56 -0700368 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
TDYa127f71bf5a2012-07-29 20:09:52 -0700369 greenland::IntrinsicHelper::HLThrowException);
buzbee32412962012-06-26 16:27:56 -0700370 cUnit->irb->CreateCall(func, src);
buzbee32412962012-06-26 16:27:56 -0700371}
372
buzbee52a77fc2012-11-20 19:50:46 -0800373void ConvertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
buzbee8fa0fda2012-06-27 15:44:52 -0700374 greenland::IntrinsicHelper::IntrinsicId id,
375 RegLocation rlSrc)
376{
377 llvm::SmallVector<llvm::Value*, 2> args;
378 args.push_back(cUnit->irb->getInt32(optFlags));
buzbee52a77fc2012-11-20 19:50:46 -0800379 args.push_back(GetLLVMValue(cUnit, rlSrc.origSReg));
buzbee8fa0fda2012-06-27 15:44:52 -0700380 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
381 cUnit->irb->CreateCall(func, args);
382}
383
buzbee52a77fc2012-11-20 19:50:46 -0800384void ConvertArrayLength(CompilationUnit* cUnit, int optFlags,
buzbee76592632012-06-29 15:18:35 -0700385 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700386{
387 llvm::SmallVector<llvm::Value*, 2> args;
388 args.push_back(cUnit->irb->getInt32(optFlags));
buzbee52a77fc2012-11-20 19:50:46 -0800389 args.push_back(GetLLVMValue(cUnit, rlSrc.origSReg));
buzbee8fa0fda2012-06-27 15:44:52 -0700390 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700391 greenland::IntrinsicHelper::OptArrayLength);
buzbee76592632012-06-29 15:18:35 -0700392 llvm::Value* res = cUnit->irb->CreateCall(func, args);
buzbee52a77fc2012-11-20 19:50:46 -0800393 DefineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700394}
395
buzbee52a77fc2012-11-20 19:50:46 -0800396void EmitSuspendCheck(CompilationUnit* cUnit)
buzbee2cfc6392012-05-07 14:51:40 -0700397{
398 greenland::IntrinsicHelper::IntrinsicId id =
399 greenland::IntrinsicHelper::CheckSuspend;
400 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
401 cUnit->irb->CreateCall(intr);
402}
403
buzbee52a77fc2012-11-20 19:50:46 -0800404llvm::Value* ConvertCompare(CompilationUnit* cUnit, ConditionCode cc,
buzbee2cfc6392012-05-07 14:51:40 -0700405 llvm::Value* src1, llvm::Value* src2)
406{
407 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700408 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700409 switch(cc) {
410 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
411 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
412 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
413 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
414 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
415 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
416 default: LOG(FATAL) << "Unexpected cc value " << cc;
417 }
418 return res;
419}
420
buzbee52a77fc2012-11-20 19:50:46 -0800421void ConvertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee2cfc6392012-05-07 14:51:40 -0700422 ConditionCode cc, RegLocation rlSrc1,
423 RegLocation rlSrc2)
424{
425 if (bb->taken->startOffset <= mir->offset) {
buzbee52a77fc2012-11-20 19:50:46 -0800426 EmitSuspendCheck(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700427 }
buzbee52a77fc2012-11-20 19:50:46 -0800428 llvm::Value* src1 = GetLLVMValue(cUnit, rlSrc1.origSReg);
429 llvm::Value* src2 = GetLLVMValue(cUnit, rlSrc2.origSReg);
430 llvm::Value* condValue = ConvertCompare(cUnit, cc, src1, src2);
buzbee2cfc6392012-05-07 14:51:40 -0700431 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
buzbee52a77fc2012-11-20 19:50:46 -0800432 cUnit->irb->CreateCondBr(condValue, GetLLVMBlock(cUnit, bb->taken->id),
433 GetLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700434 // Don't redo the fallthrough branch in the BB driver
435 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700436}
437
buzbee52a77fc2012-11-20 19:50:46 -0800438void ConvertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
buzbee2cfc6392012-05-07 14:51:40 -0700439 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
440{
441 if (bb->taken->startOffset <= mir->offset) {
buzbee52a77fc2012-11-20 19:50:46 -0800442 EmitSuspendCheck(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700443 }
buzbee52a77fc2012-11-20 19:50:46 -0800444 llvm::Value* src1 = GetLLVMValue(cUnit, rlSrc1.origSReg);
buzbee2cfc6392012-05-07 14:51:40 -0700445 llvm::Value* src2;
446 if (rlSrc1.ref) {
447 src2 = cUnit->irb->GetJNull();
448 } else {
449 src2 = cUnit->irb->getInt32(0);
450 }
buzbee52a77fc2012-11-20 19:50:46 -0800451 llvm::Value* condValue = ConvertCompare(cUnit, cc, src1, src2);
452 cUnit->irb->CreateCondBr(condValue, GetLLVMBlock(cUnit, bb->taken->id),
453 GetLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700454 // Don't redo the fallthrough branch in the BB driver
455 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700456}
457
buzbee52a77fc2012-11-20 19:50:46 -0800458llvm::Value* GenDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
buzbee2cfc6392012-05-07 14:51:40 -0700459 llvm::Value* src1, llvm::Value* src2)
460{
461 greenland::IntrinsicHelper::IntrinsicId id;
462 if (isLong) {
463 if (isDiv) {
464 id = greenland::IntrinsicHelper::DivLong;
465 } else {
466 id = greenland::IntrinsicHelper::RemLong;
467 }
Logan Chien554e6072012-07-23 20:00:01 -0700468 } else {
469 if (isDiv) {
buzbee2cfc6392012-05-07 14:51:40 -0700470 id = greenland::IntrinsicHelper::DivInt;
471 } else {
472 id = greenland::IntrinsicHelper::RemInt;
Logan Chien554e6072012-07-23 20:00:01 -0700473 }
buzbee2cfc6392012-05-07 14:51:40 -0700474 }
475 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
476 llvm::SmallVector<llvm::Value*, 2>args;
477 args.push_back(src1);
478 args.push_back(src2);
479 return cUnit->irb->CreateCall(intr, args);
480}
481
buzbee52a77fc2012-11-20 19:50:46 -0800482llvm::Value* GenArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
buzbee2cfc6392012-05-07 14:51:40 -0700483 llvm::Value* src1, llvm::Value* src2)
484{
485 llvm::Value* res = NULL;
486 switch(op) {
487 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
488 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700489 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700490 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
491 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
492 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
493 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
buzbee52a77fc2012-11-20 19:50:46 -0800494 case kOpDiv: res = GenDivModOp(cUnit, true, isLong, src1, src2); break;
495 case kOpRem: res = GenDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700496 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
497 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
498 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700499 default:
500 LOG(FATAL) << "Invalid op " << op;
501 }
502 return res;
503}
504
buzbee52a77fc2012-11-20 19:50:46 -0800505void ConvertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
buzbee2cfc6392012-05-07 14:51:40 -0700506 RegLocation rlSrc1, RegLocation rlSrc2)
507{
buzbee52a77fc2012-11-20 19:50:46 -0800508 llvm::Value* src1 = GetLLVMValue(cUnit, rlSrc1.origSReg);
509 llvm::Value* src2 = GetLLVMValue(cUnit, rlSrc2.origSReg);
buzbee2cfc6392012-05-07 14:51:40 -0700510 llvm::Value* res = NULL;
511 switch(op) {
512 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
513 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
514 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
515 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
516 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
517 default:
518 LOG(FATAL) << "Invalid op " << op;
519 }
buzbee52a77fc2012-11-20 19:50:46 -0800520 DefineValue(cUnit, res, rlDest.origSReg);
buzbee2cfc6392012-05-07 14:51:40 -0700521}
522
buzbee52a77fc2012-11-20 19:50:46 -0800523void ConvertShift(CompilationUnit* cUnit,
buzbee2a83e8f2012-07-13 16:42:30 -0700524 greenland::IntrinsicHelper::IntrinsicId id,
525 RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2)
buzbee4f1181f2012-06-22 13:52:12 -0700526{
buzbee2a83e8f2012-07-13 16:42:30 -0700527 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
528 llvm::SmallVector<llvm::Value*, 2>args;
buzbee52a77fc2012-11-20 19:50:46 -0800529 args.push_back(GetLLVMValue(cUnit, rlSrc1.origSReg));
530 args.push_back(GetLLVMValue(cUnit, rlSrc2.origSReg));
buzbee2a83e8f2012-07-13 16:42:30 -0700531 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee52a77fc2012-11-20 19:50:46 -0800532 DefineValue(cUnit, res, rlDest.origSReg);
buzbee2a83e8f2012-07-13 16:42:30 -0700533}
534
buzbee52a77fc2012-11-20 19:50:46 -0800535void ConvertShiftLit(CompilationUnit* cUnit,
buzbee2a83e8f2012-07-13 16:42:30 -0700536 greenland::IntrinsicHelper::IntrinsicId id,
537 RegLocation rlDest, RegLocation rlSrc, int shiftAmount)
538{
539 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
540 llvm::SmallVector<llvm::Value*, 2>args;
buzbee52a77fc2012-11-20 19:50:46 -0800541 args.push_back(GetLLVMValue(cUnit, rlSrc.origSReg));
buzbee2a83e8f2012-07-13 16:42:30 -0700542 args.push_back(cUnit->irb->getInt32(shiftAmount));
543 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee52a77fc2012-11-20 19:50:46 -0800544 DefineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700545}
546
buzbee52a77fc2012-11-20 19:50:46 -0800547void ConvertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
buzbee2cfc6392012-05-07 14:51:40 -0700548 RegLocation rlSrc1, RegLocation rlSrc2)
549{
buzbee52a77fc2012-11-20 19:50:46 -0800550 llvm::Value* src1 = GetLLVMValue(cUnit, rlSrc1.origSReg);
551 llvm::Value* src2 = GetLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700552 DCHECK_EQ(src1->getType(), src2->getType());
buzbee52a77fc2012-11-20 19:50:46 -0800553 llvm::Value* res = GenArithOp(cUnit, op, rlDest.wide, src1, src2);
554 DefineValue(cUnit, res, rlDest.origSReg);
buzbee2cfc6392012-05-07 14:51:40 -0700555}
556
buzbee52a77fc2012-11-20 19:50:46 -0800557void SetShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
buzbeeb03f4872012-06-11 15:22:11 -0700558{
559 int index = -1;
560 DCHECK(newVal != NULL);
buzbee52a77fc2012-11-20 19:50:46 -0800561 int vReg = SRegToVReg(cUnit, GetLoc(cUnit, newVal).origSReg);
buzbeeb03f4872012-06-11 15:22:11 -0700562 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
563 if (cUnit->shadowMap[i] == vReg) {
564 index = i;
565 break;
566 }
567 }
TDYa127347166a2012-08-23 12:23:44 -0700568 if (index == -1) {
569 return;
570 }
buzbee6459e7c2012-10-02 14:42:41 -0700571 llvm::Type* ty = newVal->getType();
buzbeeb03f4872012-06-11 15:22:11 -0700572 greenland::IntrinsicHelper::IntrinsicId id =
573 greenland::IntrinsicHelper::SetShadowFrameEntry;
574 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
575 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
buzbee6459e7c2012-10-02 14:42:41 -0700576 // If newVal is a Null pointer, we'll see it here as a const int. Replace
577 if (!ty->isPointerTy()) {
578 // TODO: assert newVal created w/ dex_lang_const_int(0) or dex_lang_const_float(0)
579 newVal = cUnit->irb->GetJNull();
580 }
buzbeeb03f4872012-06-11 15:22:11 -0700581 llvm::Value* args[] = { newVal, tableSlot };
582 cUnit->irb->CreateCall(func, args);
583}
584
buzbee52a77fc2012-11-20 19:50:46 -0800585void ConvertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
buzbee2cfc6392012-05-07 14:51:40 -0700586 RegLocation rlSrc1, int32_t imm)
587{
buzbee52a77fc2012-11-20 19:50:46 -0800588 llvm::Value* src1 = GetLLVMValue(cUnit, rlSrc1.origSReg);
buzbee2cfc6392012-05-07 14:51:40 -0700589 llvm::Value* src2 = cUnit->irb->getInt32(imm);
buzbee52a77fc2012-11-20 19:50:46 -0800590 llvm::Value* res = GenArithOp(cUnit, op, rlDest.wide, src1, src2);
591 DefineValue(cUnit, res, rlDest.origSReg);
buzbee2cfc6392012-05-07 14:51:40 -0700592}
593
buzbee101305f2012-06-28 18:00:56 -0700594/*
595 * Process arguments for invoke. Note: this code is also used to
596 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
597 * The requirements are similar.
598 */
buzbee52a77fc2012-11-20 19:50:46 -0800599void ConvertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700600 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700601{
buzbee52a77fc2012-11-20 19:50:46 -0800602 CallInfo* info = NewMemCallInfo(cUnit, bb, mir, invokeType, isRange);
buzbee6969d502012-06-15 16:40:31 -0700603 llvm::SmallVector<llvm::Value*, 10> args;
604 // Insert the invokeType
605 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
606 // Insert the method_idx
607 args.push_back(cUnit->irb->getInt32(info->index));
608 // Insert the optimization flags
609 args.push_back(cUnit->irb->getInt32(info->optFlags));
610 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700611 for (int i = 0; i < info->numArgWords;) {
buzbee52a77fc2012-11-20 19:50:46 -0800612 llvm::Value* val = GetLLVMValue(cUnit, info->args[i].origSReg);
buzbee6969d502012-06-15 16:40:31 -0700613 args.push_back(val);
614 i += info->args[i].wide ? 2 : 1;
615 }
616 /*
617 * Choose the invoke return type based on actual usage. Note: may
618 * be different than shorty. For example, if a function return value
619 * is not used, we'll treat this as a void invoke.
620 */
621 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700622 if (isFilledNewArray) {
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700623 id = greenland::IntrinsicHelper::HLFilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700624 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700625 id = greenland::IntrinsicHelper::HLInvokeVoid;
626 } else {
627 if (info->result.wide) {
628 if (info->result.fp) {
629 id = greenland::IntrinsicHelper::HLInvokeDouble;
630 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700631 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700632 }
633 } else if (info->result.ref) {
634 id = greenland::IntrinsicHelper::HLInvokeObj;
635 } else if (info->result.fp) {
636 id = greenland::IntrinsicHelper::HLInvokeFloat;
637 } else {
638 id = greenland::IntrinsicHelper::HLInvokeInt;
639 }
640 }
641 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
642 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
643 if (info->result.location != kLocInvalid) {
buzbee52a77fc2012-11-20 19:50:46 -0800644 DefineValue(cUnit, res, info->result.origSReg);
TDYa127890ea892012-08-22 10:49:42 -0700645 if (info->result.ref) {
buzbee52a77fc2012-11-20 19:50:46 -0800646 SetShadowFrameEntry(cUnit, reinterpret_cast<llvm::Value*>
buzbeecbd6d442012-11-17 14:11:25 -0800647 (cUnit->llvmValues.elemList[info->result.origSReg]));
TDYa127890ea892012-08-22 10:49:42 -0700648 }
buzbee6969d502012-06-15 16:40:31 -0700649 }
650}
651
buzbee52a77fc2012-11-20 19:50:46 -0800652void ConvertConstObject(CompilationUnit* cUnit, uint32_t idx,
buzbee101305f2012-06-28 18:00:56 -0700653 greenland::IntrinsicHelper::IntrinsicId id,
654 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700655{
buzbee6969d502012-06-15 16:40:31 -0700656 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700657 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700658 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
buzbee52a77fc2012-11-20 19:50:46 -0800659 DefineValue(cUnit, res, rlDest.origSReg);
buzbee6969d502012-06-15 16:40:31 -0700660}
661
buzbee52a77fc2012-11-20 19:50:46 -0800662void ConvertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
buzbee101305f2012-06-28 18:00:56 -0700663 RegLocation rlSrc)
664{
665 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700666 id = greenland::IntrinsicHelper::HLCheckCast;
buzbee101305f2012-06-28 18:00:56 -0700667 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
668 llvm::SmallVector<llvm::Value*, 2> args;
669 args.push_back(cUnit->irb->getInt32(type_idx));
buzbee52a77fc2012-11-20 19:50:46 -0800670 args.push_back(GetLLVMValue(cUnit, rlSrc.origSReg));
buzbee101305f2012-06-28 18:00:56 -0700671 cUnit->irb->CreateCall(intr, args);
672}
673
buzbee52a77fc2012-11-20 19:50:46 -0800674void ConvertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
buzbee8fa0fda2012-06-27 15:44:52 -0700675 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700676{
677 greenland::IntrinsicHelper::IntrinsicId id;
678 id = greenland::IntrinsicHelper::NewInstance;
679 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
680 llvm::Value* index = cUnit->irb->getInt32(type_idx);
681 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
buzbee52a77fc2012-11-20 19:50:46 -0800682 DefineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700683}
684
buzbee52a77fc2012-11-20 19:50:46 -0800685void ConvertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
buzbee8fa0fda2012-06-27 15:44:52 -0700686 RegLocation rlDest, RegLocation rlSrc)
687{
688 greenland::IntrinsicHelper::IntrinsicId id;
689 id = greenland::IntrinsicHelper::NewArray;
690 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
691 llvm::SmallVector<llvm::Value*, 2> args;
692 args.push_back(cUnit->irb->getInt32(type_idx));
buzbee52a77fc2012-11-20 19:50:46 -0800693 args.push_back(GetLLVMValue(cUnit, rlSrc.origSReg));
buzbee8fa0fda2012-06-27 15:44:52 -0700694 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee52a77fc2012-11-20 19:50:46 -0800695 DefineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700696}
697
buzbee52a77fc2012-11-20 19:50:46 -0800698void ConvertAget(CompilationUnit* cUnit, int optFlags,
buzbee8fa0fda2012-06-27 15:44:52 -0700699 greenland::IntrinsicHelper::IntrinsicId id,
700 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
701{
702 llvm::SmallVector<llvm::Value*, 3> args;
703 args.push_back(cUnit->irb->getInt32(optFlags));
buzbee52a77fc2012-11-20 19:50:46 -0800704 args.push_back(GetLLVMValue(cUnit, rlArray.origSReg));
705 args.push_back(GetLLVMValue(cUnit, rlIndex.origSReg));
buzbee8fa0fda2012-06-27 15:44:52 -0700706 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
707 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee52a77fc2012-11-20 19:50:46 -0800708 DefineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700709}
710
buzbee52a77fc2012-11-20 19:50:46 -0800711void ConvertAput(CompilationUnit* cUnit, int optFlags,
buzbee8fa0fda2012-06-27 15:44:52 -0700712 greenland::IntrinsicHelper::IntrinsicId id,
713 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
714{
715 llvm::SmallVector<llvm::Value*, 4> args;
716 args.push_back(cUnit->irb->getInt32(optFlags));
buzbee52a77fc2012-11-20 19:50:46 -0800717 args.push_back(GetLLVMValue(cUnit, rlSrc.origSReg));
718 args.push_back(GetLLVMValue(cUnit, rlArray.origSReg));
719 args.push_back(GetLLVMValue(cUnit, rlIndex.origSReg));
buzbee8fa0fda2012-06-27 15:44:52 -0700720 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
721 cUnit->irb->CreateCall(intr, args);
722}
723
buzbee52a77fc2012-11-20 19:50:46 -0800724void ConvertIget(CompilationUnit* cUnit, int optFlags,
buzbee101305f2012-06-28 18:00:56 -0700725 greenland::IntrinsicHelper::IntrinsicId id,
726 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
727{
728 llvm::SmallVector<llvm::Value*, 3> args;
729 args.push_back(cUnit->irb->getInt32(optFlags));
buzbee52a77fc2012-11-20 19:50:46 -0800730 args.push_back(GetLLVMValue(cUnit, rlObj.origSReg));
buzbee101305f2012-06-28 18:00:56 -0700731 args.push_back(cUnit->irb->getInt32(fieldIndex));
732 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
733 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee52a77fc2012-11-20 19:50:46 -0800734 DefineValue(cUnit, res, rlDest.origSReg);
buzbee101305f2012-06-28 18:00:56 -0700735}
736
buzbee52a77fc2012-11-20 19:50:46 -0800737void ConvertIput(CompilationUnit* cUnit, int optFlags,
buzbee101305f2012-06-28 18:00:56 -0700738 greenland::IntrinsicHelper::IntrinsicId id,
739 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
740{
741 llvm::SmallVector<llvm::Value*, 4> args;
742 args.push_back(cUnit->irb->getInt32(optFlags));
buzbee52a77fc2012-11-20 19:50:46 -0800743 args.push_back(GetLLVMValue(cUnit, rlSrc.origSReg));
744 args.push_back(GetLLVMValue(cUnit, rlObj.origSReg));
buzbee101305f2012-06-28 18:00:56 -0700745 args.push_back(cUnit->irb->getInt32(fieldIndex));
746 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
747 cUnit->irb->CreateCall(intr, args);
748}
749
buzbee52a77fc2012-11-20 19:50:46 -0800750void ConvertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
buzbee8fa0fda2012-06-27 15:44:52 -0700751 RegLocation rlDest, RegLocation rlSrc)
752{
753 greenland::IntrinsicHelper::IntrinsicId id;
754 id = greenland::IntrinsicHelper::InstanceOf;
755 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
756 llvm::SmallVector<llvm::Value*, 2> args;
757 args.push_back(cUnit->irb->getInt32(type_idx));
buzbee52a77fc2012-11-20 19:50:46 -0800758 args.push_back(GetLLVMValue(cUnit, rlSrc.origSReg));
buzbee8fa0fda2012-06-27 15:44:52 -0700759 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee52a77fc2012-11-20 19:50:46 -0800760 DefineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700761}
762
buzbee52a77fc2012-11-20 19:50:46 -0800763void ConvertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
buzbee101305f2012-06-28 18:00:56 -0700764 RegLocation rlSrc)
765{
buzbee52a77fc2012-11-20 19:50:46 -0800766 llvm::Value* res = cUnit->irb->CreateSExt(GetLLVMValue(cUnit, rlSrc.origSReg),
buzbee101305f2012-06-28 18:00:56 -0700767 cUnit->irb->getInt64Ty());
buzbee52a77fc2012-11-20 19:50:46 -0800768 DefineValue(cUnit, res, rlDest.origSReg);
buzbee101305f2012-06-28 18:00:56 -0700769}
770
buzbee52a77fc2012-11-20 19:50:46 -0800771void ConvertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
buzbee76592632012-06-29 15:18:35 -0700772 RegLocation rlSrc)
773{
buzbee52a77fc2012-11-20 19:50:46 -0800774 llvm::Value* src = GetLLVMValue(cUnit, rlSrc.origSReg);
buzbee76592632012-06-29 15:18:35 -0700775 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
buzbee52a77fc2012-11-20 19:50:46 -0800776 DefineValue(cUnit, res, rlDest.origSReg);
buzbee76592632012-06-29 15:18:35 -0700777}
778
buzbee52a77fc2012-11-20 19:50:46 -0800779void ConvertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
buzbee76592632012-06-29 15:18:35 -0700780 RegLocation rlSrc)
781{
buzbee52a77fc2012-11-20 19:50:46 -0800782 llvm::Value* src = GetLLVMValue(cUnit, rlSrc.origSReg);
buzbee76592632012-06-29 15:18:35 -0700783 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
buzbee52a77fc2012-11-20 19:50:46 -0800784 DefineValue(cUnit, res, rlDest.origSReg);
buzbee76592632012-06-29 15:18:35 -0700785}
786
buzbee52a77fc2012-11-20 19:50:46 -0800787void ConvertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
buzbee76592632012-06-29 15:18:35 -0700788 RegLocation rlSrc)
789{
buzbee52a77fc2012-11-20 19:50:46 -0800790 llvm::Value* src = GetLLVMValue(cUnit, rlSrc.origSReg);
buzbee76592632012-06-29 15:18:35 -0700791 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
buzbee52a77fc2012-11-20 19:50:46 -0800792 DefineValue(cUnit, res, rlDest.origSReg);
buzbee76592632012-06-29 15:18:35 -0700793}
794
buzbee52a77fc2012-11-20 19:50:46 -0800795void ConvertWideComparison(CompilationUnit* cUnit,
buzbee76592632012-06-29 15:18:35 -0700796 greenland::IntrinsicHelper::IntrinsicId id,
797 RegLocation rlDest, RegLocation rlSrc1,
798 RegLocation rlSrc2)
799{
800 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
801 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
802 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
803 llvm::SmallVector<llvm::Value*, 2> args;
buzbee52a77fc2012-11-20 19:50:46 -0800804 args.push_back(GetLLVMValue(cUnit, rlSrc1.origSReg));
805 args.push_back(GetLLVMValue(cUnit, rlSrc2.origSReg));
buzbee76592632012-06-29 15:18:35 -0700806 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee52a77fc2012-11-20 19:50:46 -0800807 DefineValue(cUnit, res, rlDest.origSReg);
buzbee76592632012-06-29 15:18:35 -0700808}
809
buzbee52a77fc2012-11-20 19:50:46 -0800810void ConvertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
buzbee101305f2012-06-28 18:00:56 -0700811 RegLocation rlSrc,
812 greenland::IntrinsicHelper::IntrinsicId id)
813{
814 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700815 llvm::Value* res =
buzbee52a77fc2012-11-20 19:50:46 -0800816 cUnit->irb->CreateCall(intr, GetLLVMValue(cUnit, rlSrc.origSReg));
817 DefineValue(cUnit, res, rlDest.origSReg);
buzbee76592632012-06-29 15:18:35 -0700818}
819
buzbee52a77fc2012-11-20 19:50:46 -0800820void ConvertNeg(CompilationUnit* cUnit, RegLocation rlDest,
buzbee76592632012-06-29 15:18:35 -0700821 RegLocation rlSrc)
822{
buzbee52a77fc2012-11-20 19:50:46 -0800823 llvm::Value* res = cUnit->irb->CreateNeg(GetLLVMValue(cUnit, rlSrc.origSReg));
824 DefineValue(cUnit, res, rlDest.origSReg);
buzbee76592632012-06-29 15:18:35 -0700825}
826
buzbee52a77fc2012-11-20 19:50:46 -0800827void ConvertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
buzbee76592632012-06-29 15:18:35 -0700828 RegLocation rlSrc)
829{
830 llvm::Value* res =
buzbee52a77fc2012-11-20 19:50:46 -0800831 cUnit->irb->CreateSIToFP(GetLLVMValue(cUnit, rlSrc.origSReg), ty);
832 DefineValue(cUnit, res, rlDest.origSReg);
buzbee76592632012-06-29 15:18:35 -0700833}
834
buzbee52a77fc2012-11-20 19:50:46 -0800835void ConvertFPToInt(CompilationUnit* cUnit,
TDYa1274ec8ccd2012-08-11 07:04:57 -0700836 greenland::IntrinsicHelper::IntrinsicId id,
837 RegLocation rlDest,
buzbee76592632012-06-29 15:18:35 -0700838 RegLocation rlSrc)
839{
TDYa1274ec8ccd2012-08-11 07:04:57 -0700840 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee52a77fc2012-11-20 19:50:46 -0800841 llvm::Value* res = cUnit->irb->CreateCall(intr, GetLLVMValue(cUnit, rlSrc.origSReg));
842 DefineValue(cUnit, res, rlDest.origSReg);
buzbee76592632012-06-29 15:18:35 -0700843}
844
845
buzbee52a77fc2012-11-20 19:50:46 -0800846void ConvertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
buzbee76592632012-06-29 15:18:35 -0700847 RegLocation rlSrc)
848{
849 llvm::Value* res =
buzbee52a77fc2012-11-20 19:50:46 -0800850 cUnit->irb->CreateFNeg(GetLLVMValue(cUnit, rlSrc.origSReg));
851 DefineValue(cUnit, res, rlDest.origSReg);
buzbee76592632012-06-29 15:18:35 -0700852}
853
buzbee52a77fc2012-11-20 19:50:46 -0800854void ConvertNot(CompilationUnit* cUnit, RegLocation rlDest,
buzbee76592632012-06-29 15:18:35 -0700855 RegLocation rlSrc)
856{
buzbee52a77fc2012-11-20 19:50:46 -0800857 llvm::Value* src = GetLLVMValue(cUnit, rlSrc.origSReg);
buzbee76592632012-06-29 15:18:35 -0700858 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee52a77fc2012-11-20 19:50:46 -0800859 DefineValue(cUnit, res, rlDest.origSReg);
buzbee101305f2012-06-28 18:00:56 -0700860}
861
buzbee2cfc6392012-05-07 14:51:40 -0700862/*
863 * Target-independent code generation. Use only high-level
864 * load/store utilities here, or target-dependent genXX() handlers
865 * when necessary.
866 */
buzbee52a77fc2012-11-20 19:50:46 -0800867bool ConvertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
buzbee2cfc6392012-05-07 14:51:40 -0700868 llvm::BasicBlock* llvmBB, LIR* labelList)
869{
870 bool res = false; // Assume success
871 RegLocation rlSrc[3];
872 RegLocation rlDest = badLoc;
buzbee2cfc6392012-05-07 14:51:40 -0700873 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbeecbd6d442012-11-17 14:11:25 -0800874 int opVal = opcode;
buzbee6969d502012-06-15 16:40:31 -0700875 uint32_t vB = mir->dalvikInsn.vB;
876 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700877 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700878
buzbeeb03f4872012-06-11 15:22:11 -0700879 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700880
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700881 if (cUnit->printMe) {
buzbeecbd6d442012-11-17 14:11:25 -0800882 if (opVal < kMirOpFirst) {
883 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x" << std::hex << opVal;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700884 } else {
buzbeecbd6d442012-11-17 14:11:25 -0800885 LOG(INFO) << extendedMIROpNames[opVal - kMirOpFirst] << " 0x" << std::hex << opVal;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700886 }
887 }
888
buzbee2cfc6392012-05-07 14:51:40 -0700889 /* Prep Src and Dest locations */
890 int nextSreg = 0;
891 int nextLoc = 0;
892 int attrs = oatDataFlowAttributes[opcode];
893 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
894 if (attrs & DF_UA) {
895 if (attrs & DF_A_WIDE) {
buzbee52a77fc2012-11-20 19:50:46 -0800896 rlSrc[nextLoc++] = GetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700897 nextSreg+= 2;
898 } else {
buzbee52a77fc2012-11-20 19:50:46 -0800899 rlSrc[nextLoc++] = GetSrc(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700900 nextSreg++;
901 }
902 }
903 if (attrs & DF_UB) {
904 if (attrs & DF_B_WIDE) {
buzbee52a77fc2012-11-20 19:50:46 -0800905 rlSrc[nextLoc++] = GetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700906 nextSreg+= 2;
907 } else {
buzbee52a77fc2012-11-20 19:50:46 -0800908 rlSrc[nextLoc++] = GetSrc(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700909 nextSreg++;
910 }
911 }
912 if (attrs & DF_UC) {
913 if (attrs & DF_C_WIDE) {
buzbee52a77fc2012-11-20 19:50:46 -0800914 rlSrc[nextLoc++] = GetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700915 } else {
buzbee52a77fc2012-11-20 19:50:46 -0800916 rlSrc[nextLoc++] = GetSrc(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700917 }
918 }
919 if (attrs & DF_DA) {
920 if (attrs & DF_A_WIDE) {
buzbee52a77fc2012-11-20 19:50:46 -0800921 rlDest = GetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700922 } else {
buzbee52a77fc2012-11-20 19:50:46 -0800923 rlDest = GetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700924 if (rlDest.ref) {
925 objectDefinition = true;
926 }
buzbee2cfc6392012-05-07 14:51:40 -0700927 }
928 }
929
930 switch (opcode) {
931 case Instruction::NOP:
932 break;
933
934 case Instruction::MOVE:
935 case Instruction::MOVE_OBJECT:
936 case Instruction::MOVE_16:
937 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700938 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700939 case Instruction::MOVE_FROM16:
940 case Instruction::MOVE_WIDE:
941 case Instruction::MOVE_WIDE_16:
942 case Instruction::MOVE_WIDE_FROM16: {
943 /*
944 * Moves/copies are meaningless in pure SSA register form,
945 * but we need to preserve them for the conversion back into
946 * MIR (at least until we stop using the Dalvik register maps).
947 * Insert a dummy intrinsic copy call, which will be recognized
948 * by the quick path and removed by the portable path.
949 */
buzbee52a77fc2012-11-20 19:50:46 -0800950 llvm::Value* src = GetLLVMValue(cUnit, rlSrc[0].origSReg);
951 llvm::Value* res = EmitCopy(cUnit, src, rlDest);
952 DefineValue(cUnit, res, rlDest.origSReg);
buzbee2cfc6392012-05-07 14:51:40 -0700953 }
954 break;
955
956 case Instruction::CONST:
957 case Instruction::CONST_4:
958 case Instruction::CONST_16: {
TDYa127347166a2012-08-23 12:23:44 -0700959 if (vB == 0) {
960 objectDefinition = true;
961 }
buzbee6969d502012-06-15 16:40:31 -0700962 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee52a77fc2012-11-20 19:50:46 -0800963 llvm::Value* res = EmitConst(cUnit, immValue, rlDest);
964 DefineValue(cUnit, res, rlDest.origSReg);
buzbee2cfc6392012-05-07 14:51:40 -0700965 }
966 break;
967
968 case Instruction::CONST_WIDE_16:
969 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700970 // Sign extend to 64 bits
971 int64_t imm = static_cast<int32_t>(vB);
972 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee52a77fc2012-11-20 19:50:46 -0800973 llvm::Value* res = EmitConst(cUnit, immValue, rlDest);
974 DefineValue(cUnit, res, rlDest.origSReg);
buzbee2cfc6392012-05-07 14:51:40 -0700975 }
976 break;
977
978 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700979 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee52a77fc2012-11-20 19:50:46 -0800980 llvm::Value* res = EmitConst(cUnit, immValue, rlDest);
981 DefineValue(cUnit, res, rlDest.origSReg);
buzbee2cfc6392012-05-07 14:51:40 -0700982 }
983 break;
984
985 case Instruction::CONST_WIDE: {
986 llvm::Constant* immValue =
987 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
buzbee52a77fc2012-11-20 19:50:46 -0800988 llvm::Value* res = EmitConst(cUnit, immValue, rlDest);
989 DefineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700990 }
991 break;
buzbee2cfc6392012-05-07 14:51:40 -0700992 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700993 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700994 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee52a77fc2012-11-20 19:50:46 -0800995 llvm::Value* res = EmitConst(cUnit, immValue, rlDest);
996 DefineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700997 }
998 break;
999
buzbee8fa0fda2012-06-27 15:44:52 -07001000 case Instruction::SPUT_OBJECT:
buzbee52a77fc2012-11-20 19:50:46 -08001001 ConvertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -07001002 rlSrc[0]);
1003 break;
1004 case Instruction::SPUT:
1005 if (rlSrc[0].fp) {
buzbee52a77fc2012-11-20 19:50:46 -08001006 ConvertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -07001007 rlSrc[0]);
1008 } else {
buzbee52a77fc2012-11-20 19:50:46 -08001009 ConvertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001010 }
1011 break;
1012 case Instruction::SPUT_BOOLEAN:
buzbee52a77fc2012-11-20 19:50:46 -08001013 ConvertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -07001014 rlSrc[0]);
1015 break;
1016 case Instruction::SPUT_BYTE:
buzbee52a77fc2012-11-20 19:50:46 -08001017 ConvertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001018 break;
1019 case Instruction::SPUT_CHAR:
buzbee52a77fc2012-11-20 19:50:46 -08001020 ConvertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001021 break;
1022 case Instruction::SPUT_SHORT:
buzbee52a77fc2012-11-20 19:50:46 -08001023 ConvertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001024 break;
1025 case Instruction::SPUT_WIDE:
1026 if (rlSrc[0].fp) {
buzbee52a77fc2012-11-20 19:50:46 -08001027 ConvertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -07001028 rlSrc[0]);
1029 } else {
buzbee52a77fc2012-11-20 19:50:46 -08001030 ConvertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -07001031 rlSrc[0]);
1032 }
1033 break;
1034
1035 case Instruction::SGET_OBJECT:
buzbee52a77fc2012-11-20 19:50:46 -08001036 ConvertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
buzbee8fa0fda2012-06-27 15:44:52 -07001037 break;
1038 case Instruction::SGET:
1039 if (rlDest.fp) {
buzbee52a77fc2012-11-20 19:50:46 -08001040 ConvertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
buzbee8fa0fda2012-06-27 15:44:52 -07001041 } else {
buzbee52a77fc2012-11-20 19:50:46 -08001042 ConvertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
buzbee8fa0fda2012-06-27 15:44:52 -07001043 }
1044 break;
1045 case Instruction::SGET_BOOLEAN:
buzbee52a77fc2012-11-20 19:50:46 -08001046 ConvertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
buzbee8fa0fda2012-06-27 15:44:52 -07001047 break;
1048 case Instruction::SGET_BYTE:
buzbee52a77fc2012-11-20 19:50:46 -08001049 ConvertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
buzbee8fa0fda2012-06-27 15:44:52 -07001050 break;
1051 case Instruction::SGET_CHAR:
buzbee52a77fc2012-11-20 19:50:46 -08001052 ConvertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
buzbee8fa0fda2012-06-27 15:44:52 -07001053 break;
1054 case Instruction::SGET_SHORT:
buzbee52a77fc2012-11-20 19:50:46 -08001055 ConvertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
buzbee8fa0fda2012-06-27 15:44:52 -07001056 break;
1057 case Instruction::SGET_WIDE:
1058 if (rlDest.fp) {
buzbee52a77fc2012-11-20 19:50:46 -08001059 ConvertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
buzbee8fa0fda2012-06-27 15:44:52 -07001060 rlDest);
1061 } else {
buzbee52a77fc2012-11-20 19:50:46 -08001062 ConvertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001063 }
1064 break;
buzbee2cfc6392012-05-07 14:51:40 -07001065
1066 case Instruction::RETURN_WIDE:
1067 case Instruction::RETURN:
1068 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -07001069 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee52a77fc2012-11-20 19:50:46 -08001070 EmitSuspendCheck(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001071 }
buzbee52a77fc2012-11-20 19:50:46 -08001072 EmitPopShadowFrame(cUnit);
1073 cUnit->irb->CreateRet(GetLLVMValue(cUnit, rlSrc[0].origSReg));
buzbee2cfc6392012-05-07 14:51:40 -07001074 bb->hasReturn = true;
1075 }
1076 break;
1077
1078 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -07001079 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee52a77fc2012-11-20 19:50:46 -08001080 EmitSuspendCheck(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001081 }
buzbee52a77fc2012-11-20 19:50:46 -08001082 EmitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001083 cUnit->irb->CreateRetVoid();
1084 bb->hasReturn = true;
1085 }
1086 break;
1087
1088 case Instruction::IF_EQ:
buzbee52a77fc2012-11-20 19:50:46 -08001089 ConvertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001090 break;
1091 case Instruction::IF_NE:
buzbee52a77fc2012-11-20 19:50:46 -08001092 ConvertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001093 break;
1094 case Instruction::IF_LT:
buzbee52a77fc2012-11-20 19:50:46 -08001095 ConvertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001096 break;
1097 case Instruction::IF_GE:
buzbee52a77fc2012-11-20 19:50:46 -08001098 ConvertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001099 break;
1100 case Instruction::IF_GT:
buzbee52a77fc2012-11-20 19:50:46 -08001101 ConvertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001102 break;
1103 case Instruction::IF_LE:
buzbee52a77fc2012-11-20 19:50:46 -08001104 ConvertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001105 break;
1106 case Instruction::IF_EQZ:
buzbee52a77fc2012-11-20 19:50:46 -08001107 ConvertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001108 break;
1109 case Instruction::IF_NEZ:
buzbee52a77fc2012-11-20 19:50:46 -08001110 ConvertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001111 break;
1112 case Instruction::IF_LTZ:
buzbee52a77fc2012-11-20 19:50:46 -08001113 ConvertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001114 break;
1115 case Instruction::IF_GEZ:
buzbee52a77fc2012-11-20 19:50:46 -08001116 ConvertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001117 break;
1118 case Instruction::IF_GTZ:
buzbee52a77fc2012-11-20 19:50:46 -08001119 ConvertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001120 break;
1121 case Instruction::IF_LEZ:
buzbee52a77fc2012-11-20 19:50:46 -08001122 ConvertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001123 break;
1124
1125 case Instruction::GOTO:
1126 case Instruction::GOTO_16:
1127 case Instruction::GOTO_32: {
1128 if (bb->taken->startOffset <= bb->startOffset) {
buzbee52a77fc2012-11-20 19:50:46 -08001129 EmitSuspendCheck(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001130 }
buzbee52a77fc2012-11-20 19:50:46 -08001131 cUnit->irb->CreateBr(GetLLVMBlock(cUnit, bb->taken->id));
buzbee2cfc6392012-05-07 14:51:40 -07001132 }
1133 break;
1134
1135 case Instruction::ADD_LONG:
1136 case Instruction::ADD_LONG_2ADDR:
1137 case Instruction::ADD_INT:
1138 case Instruction::ADD_INT_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -08001139 ConvertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001140 break;
1141 case Instruction::SUB_LONG:
1142 case Instruction::SUB_LONG_2ADDR:
1143 case Instruction::SUB_INT:
1144 case Instruction::SUB_INT_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -08001145 ConvertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001146 break;
1147 case Instruction::MUL_LONG:
1148 case Instruction::MUL_LONG_2ADDR:
1149 case Instruction::MUL_INT:
1150 case Instruction::MUL_INT_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -08001151 ConvertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001152 break;
1153 case Instruction::DIV_LONG:
1154 case Instruction::DIV_LONG_2ADDR:
1155 case Instruction::DIV_INT:
1156 case Instruction::DIV_INT_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -08001157 ConvertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001158 break;
1159 case Instruction::REM_LONG:
1160 case Instruction::REM_LONG_2ADDR:
1161 case Instruction::REM_INT:
1162 case Instruction::REM_INT_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -08001163 ConvertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001164 break;
1165 case Instruction::AND_LONG:
1166 case Instruction::AND_LONG_2ADDR:
1167 case Instruction::AND_INT:
1168 case Instruction::AND_INT_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -08001169 ConvertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001170 break;
1171 case Instruction::OR_LONG:
1172 case Instruction::OR_LONG_2ADDR:
1173 case Instruction::OR_INT:
1174 case Instruction::OR_INT_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -08001175 ConvertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001176 break;
1177 case Instruction::XOR_LONG:
1178 case Instruction::XOR_LONG_2ADDR:
1179 case Instruction::XOR_INT:
1180 case Instruction::XOR_INT_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -08001181 ConvertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001182 break;
1183 case Instruction::SHL_LONG:
1184 case Instruction::SHL_LONG_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -08001185 ConvertShift(cUnit, greenland::IntrinsicHelper::SHLLong,
buzbee2a83e8f2012-07-13 16:42:30 -07001186 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001187 break;
buzbee2cfc6392012-05-07 14:51:40 -07001188 case Instruction::SHL_INT:
1189 case Instruction::SHL_INT_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -08001190 ConvertShift(cUnit, greenland::IntrinsicHelper::SHLInt,
buzbee2a83e8f2012-07-13 16:42:30 -07001191 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001192 break;
1193 case Instruction::SHR_LONG:
1194 case Instruction::SHR_LONG_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -08001195 ConvertShift(cUnit, greenland::IntrinsicHelper::SHRLong,
buzbee2a83e8f2012-07-13 16:42:30 -07001196 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001197 break;
buzbee2cfc6392012-05-07 14:51:40 -07001198 case Instruction::SHR_INT:
1199 case Instruction::SHR_INT_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -08001200 ConvertShift(cUnit, greenland::IntrinsicHelper::SHRInt,
buzbee2a83e8f2012-07-13 16:42:30 -07001201 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001202 break;
1203 case Instruction::USHR_LONG:
1204 case Instruction::USHR_LONG_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -08001205 ConvertShift(cUnit, greenland::IntrinsicHelper::USHRLong,
buzbee2a83e8f2012-07-13 16:42:30 -07001206 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001207 break;
buzbee2cfc6392012-05-07 14:51:40 -07001208 case Instruction::USHR_INT:
1209 case Instruction::USHR_INT_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -08001210 ConvertShift(cUnit, greenland::IntrinsicHelper::USHRInt,
buzbee2a83e8f2012-07-13 16:42:30 -07001211 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001212 break;
1213
1214 case Instruction::ADD_INT_LIT16:
1215 case Instruction::ADD_INT_LIT8:
buzbee52a77fc2012-11-20 19:50:46 -08001216 ConvertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001217 break;
1218 case Instruction::RSUB_INT:
1219 case Instruction::RSUB_INT_LIT8:
buzbee52a77fc2012-11-20 19:50:46 -08001220 ConvertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001221 break;
1222 case Instruction::MUL_INT_LIT16:
1223 case Instruction::MUL_INT_LIT8:
buzbee52a77fc2012-11-20 19:50:46 -08001224 ConvertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001225 break;
1226 case Instruction::DIV_INT_LIT16:
1227 case Instruction::DIV_INT_LIT8:
buzbee52a77fc2012-11-20 19:50:46 -08001228 ConvertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001229 break;
1230 case Instruction::REM_INT_LIT16:
1231 case Instruction::REM_INT_LIT8:
buzbee52a77fc2012-11-20 19:50:46 -08001232 ConvertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001233 break;
1234 case Instruction::AND_INT_LIT16:
1235 case Instruction::AND_INT_LIT8:
buzbee52a77fc2012-11-20 19:50:46 -08001236 ConvertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001237 break;
1238 case Instruction::OR_INT_LIT16:
1239 case Instruction::OR_INT_LIT8:
buzbee52a77fc2012-11-20 19:50:46 -08001240 ConvertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001241 break;
1242 case Instruction::XOR_INT_LIT16:
1243 case Instruction::XOR_INT_LIT8:
buzbee52a77fc2012-11-20 19:50:46 -08001244 ConvertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001245 break;
1246 case Instruction::SHL_INT_LIT8:
buzbee52a77fc2012-11-20 19:50:46 -08001247 ConvertShiftLit(cUnit, greenland::IntrinsicHelper::SHLInt,
buzbee2a83e8f2012-07-13 16:42:30 -07001248 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001249 break;
1250 case Instruction::SHR_INT_LIT8:
buzbee52a77fc2012-11-20 19:50:46 -08001251 ConvertShiftLit(cUnit, greenland::IntrinsicHelper::SHRInt,
buzbee2a83e8f2012-07-13 16:42:30 -07001252 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001253 break;
1254 case Instruction::USHR_INT_LIT8:
buzbee52a77fc2012-11-20 19:50:46 -08001255 ConvertShiftLit(cUnit, greenland::IntrinsicHelper::USHRInt,
buzbee2a83e8f2012-07-13 16:42:30 -07001256 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001257 break;
1258
1259 case Instruction::ADD_FLOAT:
1260 case Instruction::ADD_FLOAT_2ADDR:
1261 case Instruction::ADD_DOUBLE:
1262 case Instruction::ADD_DOUBLE_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -08001263 ConvertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001264 break;
1265
1266 case Instruction::SUB_FLOAT:
1267 case Instruction::SUB_FLOAT_2ADDR:
1268 case Instruction::SUB_DOUBLE:
1269 case Instruction::SUB_DOUBLE_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -08001270 ConvertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001271 break;
1272
1273 case Instruction::MUL_FLOAT:
1274 case Instruction::MUL_FLOAT_2ADDR:
1275 case Instruction::MUL_DOUBLE:
1276 case Instruction::MUL_DOUBLE_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -08001277 ConvertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001278 break;
1279
1280 case Instruction::DIV_FLOAT:
1281 case Instruction::DIV_FLOAT_2ADDR:
1282 case Instruction::DIV_DOUBLE:
1283 case Instruction::DIV_DOUBLE_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -08001284 ConvertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001285 break;
1286
1287 case Instruction::REM_FLOAT:
1288 case Instruction::REM_FLOAT_2ADDR:
1289 case Instruction::REM_DOUBLE:
1290 case Instruction::REM_DOUBLE_2ADDR:
buzbee52a77fc2012-11-20 19:50:46 -08001291 ConvertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001292 break;
1293
buzbee6969d502012-06-15 16:40:31 -07001294 case Instruction::INVOKE_STATIC:
buzbee52a77fc2012-11-20 19:50:46 -08001295 ConvertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001296 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001297 break;
1298 case Instruction::INVOKE_STATIC_RANGE:
buzbee52a77fc2012-11-20 19:50:46 -08001299 ConvertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001300 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001301 break;
1302
1303 case Instruction::INVOKE_DIRECT:
buzbee52a77fc2012-11-20 19:50:46 -08001304 ConvertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001305 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001306 break;
1307 case Instruction::INVOKE_DIRECT_RANGE:
buzbee52a77fc2012-11-20 19:50:46 -08001308 ConvertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001309 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001310 break;
1311
1312 case Instruction::INVOKE_VIRTUAL:
buzbee52a77fc2012-11-20 19:50:46 -08001313 ConvertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001314 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001315 break;
1316 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee52a77fc2012-11-20 19:50:46 -08001317 ConvertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001318 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001319 break;
1320
1321 case Instruction::INVOKE_SUPER:
buzbee52a77fc2012-11-20 19:50:46 -08001322 ConvertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001323 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001324 break;
1325 case Instruction::INVOKE_SUPER_RANGE:
buzbee52a77fc2012-11-20 19:50:46 -08001326 ConvertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001327 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001328 break;
1329
1330 case Instruction::INVOKE_INTERFACE:
buzbee52a77fc2012-11-20 19:50:46 -08001331 ConvertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001332 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001333 break;
1334 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee52a77fc2012-11-20 19:50:46 -08001335 ConvertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001336 false /* NewFilledArray */);
1337 break;
1338 case Instruction::FILLED_NEW_ARRAY:
buzbee52a77fc2012-11-20 19:50:46 -08001339 ConvertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001340 true /* NewFilledArray */);
1341 break;
1342 case Instruction::FILLED_NEW_ARRAY_RANGE:
buzbee52a77fc2012-11-20 19:50:46 -08001343 ConvertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
buzbee101305f2012-06-28 18:00:56 -07001344 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001345 break;
1346
1347 case Instruction::CONST_STRING:
1348 case Instruction::CONST_STRING_JUMBO:
buzbee52a77fc2012-11-20 19:50:46 -08001349 ConvertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
buzbee101305f2012-06-28 18:00:56 -07001350 rlDest);
1351 break;
1352
1353 case Instruction::CONST_CLASS:
buzbee52a77fc2012-11-20 19:50:46 -08001354 ConvertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
buzbee101305f2012-06-28 18:00:56 -07001355 rlDest);
1356 break;
1357
1358 case Instruction::CHECK_CAST:
buzbee52a77fc2012-11-20 19:50:46 -08001359 ConvertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001360 break;
1361
buzbee4f1181f2012-06-22 13:52:12 -07001362 case Instruction::NEW_INSTANCE:
buzbee52a77fc2012-11-20 19:50:46 -08001363 ConvertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001364 break;
1365
buzbee32412962012-06-26 16:27:56 -07001366 case Instruction::MOVE_EXCEPTION:
buzbee52a77fc2012-11-20 19:50:46 -08001367 ConvertMoveException(cUnit, rlDest);
buzbee32412962012-06-26 16:27:56 -07001368 break;
1369
1370 case Instruction::THROW:
buzbee52a77fc2012-11-20 19:50:46 -08001371 ConvertThrow(cUnit, rlSrc[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001372 /*
1373 * If this throw is standalone, terminate.
1374 * If it might rethrow, force termination
1375 * of the following block.
1376 */
1377 if (bb->fallThrough == NULL) {
1378 cUnit->irb->CreateUnreachable();
1379 } else {
1380 bb->fallThrough->fallThrough = NULL;
1381 bb->fallThrough->taken = NULL;
1382 }
buzbee32412962012-06-26 16:27:56 -07001383 break;
1384
buzbee2cfc6392012-05-07 14:51:40 -07001385 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001386 case Instruction::MOVE_RESULT:
1387 case Instruction::MOVE_RESULT_OBJECT:
buzbee9a2487f2012-07-26 14:01:13 -07001388 /*
jeffhao9a4f0032012-08-30 16:17:40 -07001389 * All move_results should have been folded into the preceeding invoke.
buzbee9a2487f2012-07-26 14:01:13 -07001390 */
jeffhao9a4f0032012-08-30 16:17:40 -07001391 LOG(FATAL) << "Unexpected move_result";
buzbee2cfc6392012-05-07 14:51:40 -07001392 break;
1393
1394 case Instruction::MONITOR_ENTER:
buzbee52a77fc2012-11-20 19:50:46 -08001395 ConvertMonitorEnterExit(cUnit, optFlags,
buzbee8fa0fda2012-06-27 15:44:52 -07001396 greenland::IntrinsicHelper::MonitorEnter,
1397 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001398 break;
1399
1400 case Instruction::MONITOR_EXIT:
buzbee52a77fc2012-11-20 19:50:46 -08001401 ConvertMonitorEnterExit(cUnit, optFlags,
buzbee8fa0fda2012-06-27 15:44:52 -07001402 greenland::IntrinsicHelper::MonitorExit,
1403 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001404 break;
1405
1406 case Instruction::ARRAY_LENGTH:
buzbee52a77fc2012-11-20 19:50:46 -08001407 ConvertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001408 break;
1409
1410 case Instruction::NEW_ARRAY:
buzbee52a77fc2012-11-20 19:50:46 -08001411 ConvertNewArray(cUnit, vC, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001412 break;
1413
1414 case Instruction::INSTANCE_OF:
buzbee52a77fc2012-11-20 19:50:46 -08001415 ConvertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001416 break;
1417
1418 case Instruction::AGET:
1419 if (rlDest.fp) {
buzbee52a77fc2012-11-20 19:50:46 -08001420 ConvertAget(cUnit, optFlags,
buzbee8fa0fda2012-06-27 15:44:52 -07001421 greenland::IntrinsicHelper::HLArrayGetFloat,
1422 rlDest, rlSrc[0], rlSrc[1]);
1423 } else {
buzbee52a77fc2012-11-20 19:50:46 -08001424 ConvertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
buzbee8fa0fda2012-06-27 15:44:52 -07001425 rlDest, rlSrc[0], rlSrc[1]);
1426 }
1427 break;
1428 case Instruction::AGET_OBJECT:
buzbee52a77fc2012-11-20 19:50:46 -08001429 ConvertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
buzbee8fa0fda2012-06-27 15:44:52 -07001430 rlDest, rlSrc[0], rlSrc[1]);
1431 break;
1432 case Instruction::AGET_BOOLEAN:
buzbee52a77fc2012-11-20 19:50:46 -08001433 ConvertAget(cUnit, optFlags,
buzbee8fa0fda2012-06-27 15:44:52 -07001434 greenland::IntrinsicHelper::HLArrayGetBoolean,
1435 rlDest, rlSrc[0], rlSrc[1]);
1436 break;
1437 case Instruction::AGET_BYTE:
buzbee52a77fc2012-11-20 19:50:46 -08001438 ConvertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
buzbee8fa0fda2012-06-27 15:44:52 -07001439 rlDest, rlSrc[0], rlSrc[1]);
1440 break;
1441 case Instruction::AGET_CHAR:
buzbee52a77fc2012-11-20 19:50:46 -08001442 ConvertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
buzbee8fa0fda2012-06-27 15:44:52 -07001443 rlDest, rlSrc[0], rlSrc[1]);
1444 break;
1445 case Instruction::AGET_SHORT:
buzbee52a77fc2012-11-20 19:50:46 -08001446 ConvertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
buzbee8fa0fda2012-06-27 15:44:52 -07001447 rlDest, rlSrc[0], rlSrc[1]);
1448 break;
1449 case Instruction::AGET_WIDE:
1450 if (rlDest.fp) {
buzbee52a77fc2012-11-20 19:50:46 -08001451 ConvertAget(cUnit, optFlags,
buzbee8fa0fda2012-06-27 15:44:52 -07001452 greenland::IntrinsicHelper::HLArrayGetDouble,
1453 rlDest, rlSrc[0], rlSrc[1]);
1454 } else {
buzbee52a77fc2012-11-20 19:50:46 -08001455 ConvertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
buzbee8fa0fda2012-06-27 15:44:52 -07001456 rlDest, rlSrc[0], rlSrc[1]);
1457 }
1458 break;
1459
1460 case Instruction::APUT:
1461 if (rlSrc[0].fp) {
buzbee52a77fc2012-11-20 19:50:46 -08001462 ConvertAput(cUnit, optFlags,
buzbee8fa0fda2012-06-27 15:44:52 -07001463 greenland::IntrinsicHelper::HLArrayPutFloat,
1464 rlSrc[0], rlSrc[1], rlSrc[2]);
1465 } else {
buzbee52a77fc2012-11-20 19:50:46 -08001466 ConvertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
buzbee8fa0fda2012-06-27 15:44:52 -07001467 rlSrc[0], rlSrc[1], rlSrc[2]);
1468 }
1469 break;
1470 case Instruction::APUT_OBJECT:
buzbee52a77fc2012-11-20 19:50:46 -08001471 ConvertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
buzbee8fa0fda2012-06-27 15:44:52 -07001472 rlSrc[0], rlSrc[1], rlSrc[2]);
1473 break;
1474 case Instruction::APUT_BOOLEAN:
buzbee52a77fc2012-11-20 19:50:46 -08001475 ConvertAput(cUnit, optFlags,
buzbee8fa0fda2012-06-27 15:44:52 -07001476 greenland::IntrinsicHelper::HLArrayPutBoolean,
1477 rlSrc[0], rlSrc[1], rlSrc[2]);
1478 break;
1479 case Instruction::APUT_BYTE:
buzbee52a77fc2012-11-20 19:50:46 -08001480 ConvertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
buzbee8fa0fda2012-06-27 15:44:52 -07001481 rlSrc[0], rlSrc[1], rlSrc[2]);
1482 break;
1483 case Instruction::APUT_CHAR:
buzbee52a77fc2012-11-20 19:50:46 -08001484 ConvertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
buzbee8fa0fda2012-06-27 15:44:52 -07001485 rlSrc[0], rlSrc[1], rlSrc[2]);
1486 break;
1487 case Instruction::APUT_SHORT:
buzbee52a77fc2012-11-20 19:50:46 -08001488 ConvertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
buzbee8fa0fda2012-06-27 15:44:52 -07001489 rlSrc[0], rlSrc[1], rlSrc[2]);
1490 break;
1491 case Instruction::APUT_WIDE:
1492 if (rlSrc[0].fp) {
buzbee52a77fc2012-11-20 19:50:46 -08001493 ConvertAput(cUnit, optFlags,
buzbee8fa0fda2012-06-27 15:44:52 -07001494 greenland::IntrinsicHelper::HLArrayPutDouble,
1495 rlSrc[0], rlSrc[1], rlSrc[2]);
1496 } else {
buzbee52a77fc2012-11-20 19:50:46 -08001497 ConvertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
buzbee8fa0fda2012-06-27 15:44:52 -07001498 rlSrc[0], rlSrc[1], rlSrc[2]);
1499 }
1500 break;
1501
buzbee101305f2012-06-28 18:00:56 -07001502 case Instruction::IGET:
1503 if (rlDest.fp) {
buzbee52a77fc2012-11-20 19:50:46 -08001504 ConvertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001505 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001506 } else {
buzbee52a77fc2012-11-20 19:50:46 -08001507 ConvertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001508 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001509 }
buzbee2cfc6392012-05-07 14:51:40 -07001510 break;
buzbee101305f2012-06-28 18:00:56 -07001511 case Instruction::IGET_OBJECT:
buzbee52a77fc2012-11-20 19:50:46 -08001512 ConvertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001513 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001514 break;
1515 case Instruction::IGET_BOOLEAN:
buzbee52a77fc2012-11-20 19:50:46 -08001516 ConvertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001517 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001518 break;
1519 case Instruction::IGET_BYTE:
buzbee52a77fc2012-11-20 19:50:46 -08001520 ConvertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001521 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001522 break;
1523 case Instruction::IGET_CHAR:
buzbee52a77fc2012-11-20 19:50:46 -08001524 ConvertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001525 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001526 break;
1527 case Instruction::IGET_SHORT:
buzbee52a77fc2012-11-20 19:50:46 -08001528 ConvertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001529 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001530 break;
1531 case Instruction::IGET_WIDE:
1532 if (rlDest.fp) {
buzbee52a77fc2012-11-20 19:50:46 -08001533 ConvertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001534 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001535 } else {
buzbee52a77fc2012-11-20 19:50:46 -08001536 ConvertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001537 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001538 }
1539 break;
1540 case Instruction::IPUT:
buzbee85eee022012-07-16 22:12:38 -07001541 if (rlSrc[0].fp) {
buzbee52a77fc2012-11-20 19:50:46 -08001542 ConvertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
buzbee101305f2012-06-28 18:00:56 -07001543 rlSrc[0], rlSrc[1], vC);
1544 } else {
buzbee52a77fc2012-11-20 19:50:46 -08001545 ConvertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
buzbee101305f2012-06-28 18:00:56 -07001546 rlSrc[0], rlSrc[1], vC);
1547 }
1548 break;
1549 case Instruction::IPUT_OBJECT:
buzbee52a77fc2012-11-20 19:50:46 -08001550 ConvertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
buzbee101305f2012-06-28 18:00:56 -07001551 rlSrc[0], rlSrc[1], vC);
1552 break;
1553 case Instruction::IPUT_BOOLEAN:
buzbee52a77fc2012-11-20 19:50:46 -08001554 ConvertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
buzbee101305f2012-06-28 18:00:56 -07001555 rlSrc[0], rlSrc[1], vC);
1556 break;
1557 case Instruction::IPUT_BYTE:
buzbee52a77fc2012-11-20 19:50:46 -08001558 ConvertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
buzbee101305f2012-06-28 18:00:56 -07001559 rlSrc[0], rlSrc[1], vC);
1560 break;
1561 case Instruction::IPUT_CHAR:
buzbee52a77fc2012-11-20 19:50:46 -08001562 ConvertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
buzbee101305f2012-06-28 18:00:56 -07001563 rlSrc[0], rlSrc[1], vC);
1564 break;
1565 case Instruction::IPUT_SHORT:
buzbee52a77fc2012-11-20 19:50:46 -08001566 ConvertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
buzbee101305f2012-06-28 18:00:56 -07001567 rlSrc[0], rlSrc[1], vC);
1568 break;
1569 case Instruction::IPUT_WIDE:
buzbee85eee022012-07-16 22:12:38 -07001570 if (rlSrc[0].fp) {
buzbee52a77fc2012-11-20 19:50:46 -08001571 ConvertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
buzbee101305f2012-06-28 18:00:56 -07001572 rlSrc[0], rlSrc[1], vC);
1573 } else {
buzbee52a77fc2012-11-20 19:50:46 -08001574 ConvertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
buzbee101305f2012-06-28 18:00:56 -07001575 rlSrc[0], rlSrc[1], vC);
1576 }
buzbee2cfc6392012-05-07 14:51:40 -07001577 break;
1578
1579 case Instruction::FILL_ARRAY_DATA:
buzbee52a77fc2012-11-20 19:50:46 -08001580 ConvertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001581 break;
1582
buzbee76592632012-06-29 15:18:35 -07001583 case Instruction::LONG_TO_INT:
buzbee52a77fc2012-11-20 19:50:46 -08001584 ConvertLongToInt(cUnit, rlDest, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001585 break;
1586
buzbee101305f2012-06-28 18:00:56 -07001587 case Instruction::INT_TO_LONG:
buzbee52a77fc2012-11-20 19:50:46 -08001588 ConvertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001589 break;
1590
buzbee101305f2012-06-28 18:00:56 -07001591 case Instruction::INT_TO_CHAR:
buzbee52a77fc2012-11-20 19:50:46 -08001592 ConvertIntNarrowing(cUnit, rlDest, rlSrc[0],
buzbee101305f2012-06-28 18:00:56 -07001593 greenland::IntrinsicHelper::IntToChar);
1594 break;
1595 case Instruction::INT_TO_BYTE:
buzbee52a77fc2012-11-20 19:50:46 -08001596 ConvertIntNarrowing(cUnit, rlDest, rlSrc[0],
buzbee101305f2012-06-28 18:00:56 -07001597 greenland::IntrinsicHelper::IntToByte);
1598 break;
1599 case Instruction::INT_TO_SHORT:
buzbee52a77fc2012-11-20 19:50:46 -08001600 ConvertIntNarrowing(cUnit, rlDest, rlSrc[0],
buzbee101305f2012-06-28 18:00:56 -07001601 greenland::IntrinsicHelper::IntToShort);
1602 break;
1603
buzbee76592632012-06-29 15:18:35 -07001604 case Instruction::INT_TO_FLOAT:
1605 case Instruction::LONG_TO_FLOAT:
buzbee52a77fc2012-11-20 19:50:46 -08001606 ConvertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001607 break;
1608
buzbee76592632012-06-29 15:18:35 -07001609 case Instruction::INT_TO_DOUBLE:
1610 case Instruction::LONG_TO_DOUBLE:
buzbee52a77fc2012-11-20 19:50:46 -08001611 ConvertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001612 break;
1613
buzbee76592632012-06-29 15:18:35 -07001614 case Instruction::FLOAT_TO_DOUBLE:
buzbee52a77fc2012-11-20 19:50:46 -08001615 ConvertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001616 break;
1617
buzbee76592632012-06-29 15:18:35 -07001618 case Instruction::DOUBLE_TO_FLOAT:
buzbee52a77fc2012-11-20 19:50:46 -08001619 ConvertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001620 break;
1621
1622 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001623 case Instruction::NEG_INT:
buzbee52a77fc2012-11-20 19:50:46 -08001624 ConvertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001625 break;
1626
1627 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001628 case Instruction::NEG_DOUBLE:
buzbee52a77fc2012-11-20 19:50:46 -08001629 ConvertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001630 break;
1631
buzbee76592632012-06-29 15:18:35 -07001632 case Instruction::NOT_LONG:
1633 case Instruction::NOT_INT:
buzbee52a77fc2012-11-20 19:50:46 -08001634 ConvertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001635 break;
1636
buzbee2cfc6392012-05-07 14:51:40 -07001637 case Instruction::FLOAT_TO_INT:
buzbee52a77fc2012-11-20 19:50:46 -08001638 ConvertFPToInt(cUnit, greenland::IntrinsicHelper::F2I, rlDest, rlSrc[0]);
TDYa1274ec8ccd2012-08-11 07:04:57 -07001639 break;
1640
buzbee2cfc6392012-05-07 14:51:40 -07001641 case Instruction::DOUBLE_TO_INT:
buzbee52a77fc2012-11-20 19:50:46 -08001642 ConvertFPToInt(cUnit, greenland::IntrinsicHelper::D2I, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001643 break;
1644
buzbee76592632012-06-29 15:18:35 -07001645 case Instruction::FLOAT_TO_LONG:
buzbee52a77fc2012-11-20 19:50:46 -08001646 ConvertFPToInt(cUnit, greenland::IntrinsicHelper::F2L, rlDest, rlSrc[0]);
TDYa1274ec8ccd2012-08-11 07:04:57 -07001647 break;
1648
buzbee76592632012-06-29 15:18:35 -07001649 case Instruction::DOUBLE_TO_LONG:
buzbee52a77fc2012-11-20 19:50:46 -08001650 ConvertFPToInt(cUnit, greenland::IntrinsicHelper::D2L, rlDest, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001651 break;
1652
1653 case Instruction::CMPL_FLOAT:
buzbee52a77fc2012-11-20 19:50:46 -08001654 ConvertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
buzbee76592632012-06-29 15:18:35 -07001655 rlDest, rlSrc[0], rlSrc[1]);
1656 break;
1657 case Instruction::CMPG_FLOAT:
buzbee52a77fc2012-11-20 19:50:46 -08001658 ConvertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
buzbee76592632012-06-29 15:18:35 -07001659 rlDest, rlSrc[0], rlSrc[1]);
1660 break;
1661 case Instruction::CMPL_DOUBLE:
buzbee52a77fc2012-11-20 19:50:46 -08001662 ConvertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
buzbee76592632012-06-29 15:18:35 -07001663 rlDest, rlSrc[0], rlSrc[1]);
1664 break;
1665 case Instruction::CMPG_DOUBLE:
buzbee52a77fc2012-11-20 19:50:46 -08001666 ConvertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
buzbee76592632012-06-29 15:18:35 -07001667 rlDest, rlSrc[0], rlSrc[1]);
1668 break;
1669 case Instruction::CMP_LONG:
buzbee52a77fc2012-11-20 19:50:46 -08001670 ConvertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
buzbee76592632012-06-29 15:18:35 -07001671 rlDest, rlSrc[0], rlSrc[1]);
1672 break;
1673
buzbee76592632012-06-29 15:18:35 -07001674 case Instruction::PACKED_SWITCH:
buzbee52a77fc2012-11-20 19:50:46 -08001675 ConvertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001676 break;
1677
1678 case Instruction::SPARSE_SWITCH:
buzbee52a77fc2012-11-20 19:50:46 -08001679 ConvertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001680 break;
buzbee2cfc6392012-05-07 14:51:40 -07001681
1682 default:
buzbee32412962012-06-26 16:27:56 -07001683 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001684 res = true;
1685 }
buzbeeb03f4872012-06-11 15:22:11 -07001686 if (objectDefinition) {
buzbee52a77fc2012-11-20 19:50:46 -08001687 SetShadowFrameEntry(cUnit, reinterpret_cast<llvm::Value*>
buzbeecbd6d442012-11-17 14:11:25 -08001688 (cUnit->llvmValues.elemList[rlDest.origSReg]));
buzbeeb03f4872012-06-11 15:22:11 -07001689 }
buzbee2cfc6392012-05-07 14:51:40 -07001690 return res;
1691}
1692
1693/* Extended MIR instructions like PHI */
buzbee52a77fc2012-11-20 19:50:46 -08001694void ConvertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee2cfc6392012-05-07 14:51:40 -07001695 llvm::BasicBlock* llvmBB)
1696{
1697
buzbeecbd6d442012-11-17 14:11:25 -08001698 switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) {
buzbee2cfc6392012-05-07 14:51:40 -07001699 case kMirOpPhi: {
buzbee2cfc6392012-05-07 14:51:40 -07001700 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001701 /*
1702 * The Art compiler's Phi nodes only handle 32-bit operands,
1703 * representing wide values using a matched set of Phi nodes
1704 * for the lower and upper halves. In the llvm world, we only
1705 * want a single Phi for wides. Here we will simply discard
1706 * the Phi node representing the high word.
1707 */
1708 if (rlDest.highWord) {
1709 return; // No Phi node - handled via low word
1710 }
buzbeecbd6d442012-11-17 14:11:25 -08001711 int* incoming = reinterpret_cast<int*>(mir->dalvikInsn.vB);
buzbee2cfc6392012-05-07 14:51:40 -07001712 llvm::Type* phiType =
buzbee52a77fc2012-11-20 19:50:46 -08001713 LlvmTypeFromLocRec(cUnit, rlDest);
buzbee2cfc6392012-05-07 14:51:40 -07001714 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1715 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1716 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001717 // Don't check width here.
buzbee52a77fc2012-11-20 19:50:46 -08001718 loc = GetRawSrc(cUnit, mir, i);
buzbee2a83e8f2012-07-13 16:42:30 -07001719 DCHECK_EQ(rlDest.wide, loc.wide);
1720 DCHECK_EQ(rlDest.wide & rlDest.highWord, loc.wide & loc.highWord);
1721 DCHECK_EQ(rlDest.fp, loc.fp);
1722 DCHECK_EQ(rlDest.core, loc.core);
1723 DCHECK_EQ(rlDest.ref, loc.ref);
buzbeed1643e42012-09-05 14:06:51 -07001724 SafeMap<unsigned int, unsigned int>::iterator it;
1725 it = cUnit->blockIdMap.find(incoming[i]);
1726 DCHECK(it != cUnit->blockIdMap.end());
buzbee52a77fc2012-11-20 19:50:46 -08001727 phi->addIncoming(GetLLVMValue(cUnit, loc.origSReg),
1728 GetLLVMBlock(cUnit, it->second));
buzbee2cfc6392012-05-07 14:51:40 -07001729 }
buzbee52a77fc2012-11-20 19:50:46 -08001730 DefineValue(cUnit, phi, rlDest.origSReg);
buzbee2cfc6392012-05-07 14:51:40 -07001731 break;
1732 }
1733 case kMirOpCopy: {
1734 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1735 break;
1736 }
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001737 case kMirOpNop:
1738 if ((mir == bb->lastMIRInsn) && (bb->taken == NULL) &&
1739 (bb->fallThrough == NULL)) {
1740 cUnit->irb->CreateUnreachable();
1741 }
1742 break;
1743
buzbeeb046e162012-10-30 15:48:42 -07001744 // TODO: need GBC intrinsic to take advantage of fused operations
buzbee2cfc6392012-05-07 14:51:40 -07001745 case kMirOpFusedCmplFloat:
buzbeeb046e162012-10-30 15:48:42 -07001746 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpFloat unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001747 break;
1748 case kMirOpFusedCmpgFloat:
buzbeeb046e162012-10-30 15:48:42 -07001749 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmgFloat unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001750 break;
1751 case kMirOpFusedCmplDouble:
buzbeeb046e162012-10-30 15:48:42 -07001752 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmplDouble unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001753 break;
1754 case kMirOpFusedCmpgDouble:
buzbeeb046e162012-10-30 15:48:42 -07001755 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpgDouble unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001756 break;
1757 case kMirOpFusedCmpLong:
buzbeeb046e162012-10-30 15:48:42 -07001758 UNIMPLEMENTED(FATAL) << "kMirOpLongCmpBranch unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001759 break;
buzbee2cfc6392012-05-07 14:51:40 -07001760 default:
1761 break;
1762 }
1763}
1764
buzbee52a77fc2012-11-20 19:50:46 -08001765void SetDexOffset(CompilationUnit* cUnit, int32_t offset)
buzbee2cfc6392012-05-07 14:51:40 -07001766{
1767 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001768 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001769 arrayRef.push_back(cUnit->irb->getInt32(offset));
1770 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1771 cUnit->irb->SetDexOffset(node);
1772}
1773
1774// Attach method info as metadata to special intrinsic
buzbee52a77fc2012-11-20 19:50:46 -08001775void SetMethodInfo(CompilationUnit* cUnit)
buzbee2cfc6392012-05-07 14:51:40 -07001776{
1777 // We don't want dex offset on this
1778 cUnit->irb->SetDexOffset(NULL);
1779 greenland::IntrinsicHelper::IntrinsicId id;
1780 id = greenland::IntrinsicHelper::MethodInfo;
1781 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1782 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1783 llvm::SmallVector<llvm::Value*, 2> regInfo;
1784 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1785 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1786 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1787 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1788 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1789 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1790 inst->setMetadata("RegInfo", regInfoNode);
1791 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1792 llvm::SmallVector<llvm::Value*, 50> pmap;
1793 for (int i = 0; i < promoSize; i++) {
1794 PromotionMap* p = &cUnit->promotionMap[i];
1795 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
buzbee52a77fc2012-11-20 19:50:46 -08001796 ((p->FpReg & 0xff) << 16) |
buzbee2cfc6392012-05-07 14:51:40 -07001797 ((p->coreReg & 0xff) << 8) |
1798 ((p->fpLocation & 0xf) << 4) |
1799 (p->coreLocation & 0xf);
1800 pmap.push_back(cUnit->irb->getInt32(mapData));
1801 }
1802 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1803 inst->setMetadata("PromotionMap", mapNode);
buzbee52a77fc2012-11-20 19:50:46 -08001804 SetDexOffset(cUnit, cUnit->currentDalvikOffset);
buzbee2cfc6392012-05-07 14:51:40 -07001805}
1806
1807/* Handle the content in each basic block */
buzbee52a77fc2012-11-20 19:50:46 -08001808bool MethodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
buzbee2cfc6392012-05-07 14:51:40 -07001809{
buzbeed1643e42012-09-05 14:06:51 -07001810 if (bb->blockType == kDead) return false;
buzbee52a77fc2012-11-20 19:50:46 -08001811 llvm::BasicBlock* llvmBB = GetLLVMBlock(cUnit, bb->id);
buzbeef5f5a122012-09-21 13:57:36 -07001812 if (llvmBB == NULL) {
1813 CHECK(bb->blockType == kExitBlock);
1814 } else {
1815 cUnit->irb->SetInsertPoint(llvmBB);
buzbee52a77fc2012-11-20 19:50:46 -08001816 SetDexOffset(cUnit, bb->startOffset);
buzbeef5f5a122012-09-21 13:57:36 -07001817 }
buzbee2cfc6392012-05-07 14:51:40 -07001818
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001819 if (cUnit->printMe) {
1820 LOG(INFO) << "................................";
1821 LOG(INFO) << "Block id " << bb->id;
1822 if (llvmBB != NULL) {
1823 LOG(INFO) << "label " << llvmBB->getName().str().c_str();
1824 } else {
1825 LOG(INFO) << "llvmBB is NULL";
1826 }
1827 }
1828
buzbee2cfc6392012-05-07 14:51:40 -07001829 if (bb->blockType == kEntryBlock) {
buzbee52a77fc2012-11-20 19:50:46 -08001830 SetMethodInfo(cUnit);
1831 bool *canBeRef = static_cast<bool*>(NewMem(cUnit, sizeof(bool) * cUnit->numDalvikRegisters,
buzbeecbd6d442012-11-17 14:11:25 -08001832 true, kAllocMisc));
buzbeeb03f4872012-06-11 15:22:11 -07001833 for (int i = 0; i < cUnit->numSSARegs; i++) {
buzbee6ec5e232012-09-20 15:50:03 -07001834 int vReg = SRegToVReg(cUnit, i);
1835 if (vReg > SSA_METHOD_BASEREG) {
1836 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1837 }
buzbeeb03f4872012-06-11 15:22:11 -07001838 }
1839 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1840 if (canBeRef[i]) {
1841 cUnit->numShadowFrameEntries++;
1842 }
1843 }
1844 if (cUnit->numShadowFrameEntries > 0) {
buzbee52a77fc2012-11-20 19:50:46 -08001845 cUnit->shadowMap = static_cast<int*>(NewMem(cUnit, sizeof(int) * cUnit->numShadowFrameEntries,
buzbeecbd6d442012-11-17 14:11:25 -08001846 true, kAllocMisc));
buzbeeb03f4872012-06-11 15:22:11 -07001847 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1848 if (canBeRef[i]) {
1849 cUnit->shadowMap[j++] = i;
1850 }
1851 }
buzbeeb03f4872012-06-11 15:22:11 -07001852 }
Shih-wei Liao569daf12012-08-10 23:22:33 -07001853 greenland::IntrinsicHelper::IntrinsicId id =
1854 greenland::IntrinsicHelper::AllocaShadowFrame;
1855 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1856 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
TDYa1278e950c12012-11-02 09:58:19 -07001857 llvm::Value* dalvikRegs = cUnit->irb->getInt32(cUnit->numDalvikRegisters);
1858 llvm::Value* args[] = { entries, dalvikRegs };
1859 cUnit->irb->CreateCall(func, args);
buzbee2cfc6392012-05-07 14:51:40 -07001860 } else if (bb->blockType == kExitBlock) {
1861 /*
1862 * Because of the differences between how MIR/LIR and llvm handle exit
1863 * blocks, we won't explicitly covert them. On the llvm-to-lir
1864 * path, it will need to be regenereated.
1865 */
1866 return false;
buzbee6969d502012-06-15 16:40:31 -07001867 } else if (bb->blockType == kExceptionHandling) {
1868 /*
1869 * Because we're deferring null checking, delete the associated empty
1870 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001871 */
1872 llvmBB->eraseFromParent();
1873 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001874 }
1875
1876 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1877
buzbee52a77fc2012-11-20 19:50:46 -08001878 SetDexOffset(cUnit, mir->offset);
buzbee2cfc6392012-05-07 14:51:40 -07001879
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001880 int opcode = mir->dalvikInsn.opcode;
1881 Instruction::Format dalvikFormat =
1882 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001883
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001884 if (opcode == kMirOpCheck) {
1885 // Combine check and work halves of throwing instruction.
1886 MIR* workHalf = mir->meta.throwInsn;
1887 mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
1888 opcode = mir->dalvikInsn.opcode;
1889 SSARepresentation* ssaRep = workHalf->ssaRep;
1890 workHalf->ssaRep = mir->ssaRep;
1891 mir->ssaRep = ssaRep;
1892 workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1893 if (bb->successorBlockList.blockListType == kCatch) {
1894 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
1895 greenland::IntrinsicHelper::CatchTargets);
1896 llvm::Value* switchKey =
1897 cUnit->irb->CreateCall(intr, cUnit->irb->getInt32(mir->offset));
1898 GrowableListIterator iter;
buzbee52a77fc2012-11-20 19:50:46 -08001899 GrowableListIteratorInit(&bb->successorBlockList.blocks, &iter);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001900 // New basic block to use for work half
1901 llvm::BasicBlock* workBB =
1902 llvm::BasicBlock::Create(*cUnit->context, "", cUnit->func);
1903 llvm::SwitchInst* sw =
1904 cUnit->irb->CreateSwitch(switchKey, workBB,
1905 bb->successorBlockList.blocks.numUsed);
1906 while (true) {
1907 SuccessorBlockInfo *successorBlockInfo =
buzbee52a77fc2012-11-20 19:50:46 -08001908 reinterpret_cast<SuccessorBlockInfo*>(GrowableListIteratorNext(&iter));
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001909 if (successorBlockInfo == NULL) break;
1910 llvm::BasicBlock *target =
buzbee52a77fc2012-11-20 19:50:46 -08001911 GetLLVMBlock(cUnit, successorBlockInfo->block->id);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001912 int typeIndex = successorBlockInfo->key;
1913 sw->addCase(cUnit->irb->getInt32(typeIndex), target);
1914 }
1915 llvmBB = workBB;
1916 cUnit->irb->SetInsertPoint(llvmBB);
1917 }
1918 }
1919
1920 if (opcode >= kMirOpFirst) {
buzbee52a77fc2012-11-20 19:50:46 -08001921 ConvertExtendedMIR(cUnit, bb, mir, llvmBB);
buzbee2cfc6392012-05-07 14:51:40 -07001922 continue;
1923 }
1924
buzbee52a77fc2012-11-20 19:50:46 -08001925 bool notHandled = ConvertMIRNode(cUnit, mir, bb, llvmBB,
buzbee2cfc6392012-05-07 14:51:40 -07001926 NULL /* labelList */);
1927 if (notHandled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001928 Instruction::Code dalvikOpcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001929 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001930 mir->offset, opcode,
buzbee2cfc6392012-05-07 14:51:40 -07001931 Instruction::Name(dalvikOpcode),
1932 dalvikFormat);
1933 }
1934 }
1935
buzbee4be777b2012-07-12 14:38:18 -07001936 if (bb->blockType == kEntryBlock) {
buzbee52a77fc2012-11-20 19:50:46 -08001937 cUnit->entryTargetBB = GetLLVMBlock(cUnit, bb->fallThrough->id);
buzbee4be777b2012-07-12 14:38:18 -07001938 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee52a77fc2012-11-20 19:50:46 -08001939 cUnit->irb->CreateBr(GetLLVMBlock(cUnit, bb->fallThrough->id));
buzbee2cfc6392012-05-07 14:51:40 -07001940 }
1941
1942 return false;
1943}
1944
buzbee52a77fc2012-11-20 19:50:46 -08001945char RemapShorty(char shortyType) {
buzbee4f4dfc72012-07-02 14:54:44 -07001946 /*
1947 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1948 * and longs/doubles are represented as a pair of registers. When sub-word
1949 * arguments (and method results) are passed, they are extended to Dalvik
1950 * virtual register containers. Because llvm is picky about type consistency,
1951 * we must either cast the "real" type to 32-bit container multiple Dalvik
1952 * register types, or always use the expanded values.
1953 * Here, we're doing the latter. We map the shorty signature to container
1954 * types (which is valid so long as we always do a real expansion of passed
1955 * arguments and field loads).
1956 */
1957 switch(shortyType) {
1958 case 'Z' : shortyType = 'I'; break;
1959 case 'B' : shortyType = 'I'; break;
1960 case 'S' : shortyType = 'I'; break;
1961 case 'C' : shortyType = 'I'; break;
1962 default: break;
1963 }
1964 return shortyType;
1965}
1966
buzbee52a77fc2012-11-20 19:50:46 -08001967llvm::FunctionType* GetFunctionType(CompilationUnit* cUnit) {
buzbee2cfc6392012-05-07 14:51:40 -07001968
1969 // Get return type
buzbee52a77fc2012-11-20 19:50:46 -08001970 llvm::Type* ret_type = cUnit->irb->GetJType(RemapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001971 greenland::kAccurate);
1972
1973 // Get argument type
1974 std::vector<llvm::Type*> args_type;
1975
1976 // method object
1977 args_type.push_back(cUnit->irb->GetJMethodTy());
1978
1979 // Do we have a "this"?
1980 if ((cUnit->access_flags & kAccStatic) == 0) {
1981 args_type.push_back(cUnit->irb->GetJObjectTy());
1982 }
1983
1984 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee52a77fc2012-11-20 19:50:46 -08001985 args_type.push_back(cUnit->irb->GetJType(RemapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001986 greenland::kAccurate));
1987 }
1988
1989 return llvm::FunctionType::get(ret_type, args_type, false);
1990}
1991
buzbee52a77fc2012-11-20 19:50:46 -08001992bool CreateFunction(CompilationUnit* cUnit) {
buzbee2cfc6392012-05-07 14:51:40 -07001993 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1994 /* with_signature */ false));
buzbee52a77fc2012-11-20 19:50:46 -08001995 llvm::FunctionType* func_type = GetFunctionType(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001996
1997 if (func_type == NULL) {
1998 return false;
1999 }
2000
2001 cUnit->func = llvm::Function::Create(func_type,
2002 llvm::Function::ExternalLinkage,
2003 func_name, cUnit->module);
2004
2005 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2006 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
2007
2008 arg_iter->setName("method");
2009 ++arg_iter;
2010
2011 int startSReg = cUnit->numRegs;
2012
2013 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
2014 arg_iter->setName(StringPrintf("v%i_0", startSReg));
2015 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
2016 }
2017
2018 return true;
2019}
2020
buzbee52a77fc2012-11-20 19:50:46 -08002021bool CreateLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
buzbee2cfc6392012-05-07 14:51:40 -07002022{
2023 // Skip the exit block
buzbeed1643e42012-09-05 14:06:51 -07002024 if ((bb->blockType == kDead) ||(bb->blockType == kExitBlock)) {
buzbee2cfc6392012-05-07 14:51:40 -07002025 cUnit->idToBlockMap.Put(bb->id, NULL);
2026 } else {
2027 int offset = bb->startOffset;
2028 bool entryBlock = (bb->blockType == kEntryBlock);
2029 llvm::BasicBlock* llvmBB =
2030 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
buzbee8320f382012-09-11 16:29:42 -07002031 StringPrintf(kLabelFormat, bb->catchEntry ? kCatchBlock :
2032 kNormalBlock, offset, bb->id), cUnit->func);
buzbee2cfc6392012-05-07 14:51:40 -07002033 if (entryBlock) {
2034 cUnit->entryBB = llvmBB;
2035 cUnit->placeholderBB =
2036 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
2037 cUnit->func);
2038 }
2039 cUnit->idToBlockMap.Put(bb->id, llvmBB);
2040 }
2041 return false;
2042}
2043
2044
2045/*
2046 * Convert MIR to LLVM_IR
2047 * o For each ssa name, create LLVM named value. Type these
2048 * appropriately, and ignore high half of wide and double operands.
2049 * o For each MIR basic block, create an LLVM basic block.
2050 * o Iterate through the MIR a basic block at a time, setting arguments
2051 * to recovered ssa name.
2052 */
buzbee52a77fc2012-11-20 19:50:46 -08002053void MethodMIR2Bitcode(CompilationUnit* cUnit)
buzbee2cfc6392012-05-07 14:51:40 -07002054{
buzbee52a77fc2012-11-20 19:50:46 -08002055 InitIR(cUnit);
2056 CompilerInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
buzbee2cfc6392012-05-07 14:51:40 -07002057
2058 // Create the function
buzbee52a77fc2012-11-20 19:50:46 -08002059 CreateFunction(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002060
2061 // Create an LLVM basic block for each MIR block in dfs preorder
buzbee52a77fc2012-11-20 19:50:46 -08002062 DataFlowAnalysisDispatcher(cUnit, CreateLLVMBasicBlock,
buzbee2cfc6392012-05-07 14:51:40 -07002063 kPreOrderDFSTraversal, false /* isIterative */);
2064 /*
2065 * Create an llvm named value for each MIR SSA name. Note: we'll use
2066 * placeholders for all non-argument values (because we haven't seen
2067 * the definition yet).
2068 */
2069 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2070 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2071 arg_iter++; /* Skip path method */
2072 for (int i = 0; i < cUnit->numSSARegs; i++) {
2073 llvm::Value* val;
buzbee85eee022012-07-16 22:12:38 -07002074 RegLocation rlTemp = cUnit->regLocation[i];
2075 if ((SRegToVReg(cUnit, i) < 0) || rlTemp.highWord) {
buzbee52a77fc2012-11-20 19:50:46 -08002076 InsertGrowableList(cUnit, &cUnit->llvmValues, 0);
buzbee2a83e8f2012-07-13 16:42:30 -07002077 } else if ((i < cUnit->numRegs) ||
2078 (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee85eee022012-07-16 22:12:38 -07002079 llvm::Constant* immValue = cUnit->regLocation[i].wide ?
2080 cUnit->irb->GetJLong(0) : cUnit->irb->GetJInt(0);
buzbee52a77fc2012-11-20 19:50:46 -08002081 val = EmitConst(cUnit, immValue, cUnit->regLocation[i]);
2082 val->setName(LlvmSSAName(cUnit, i));
2083 InsertGrowableList(cUnit, &cUnit->llvmValues, reinterpret_cast<uintptr_t>(val));
buzbee2cfc6392012-05-07 14:51:40 -07002084 } else {
2085 // Recover previously-created argument values
2086 llvm::Value* argVal = arg_iter++;
buzbee52a77fc2012-11-20 19:50:46 -08002087 InsertGrowableList(cUnit, &cUnit->llvmValues, reinterpret_cast<uintptr_t>(argVal));
buzbee2cfc6392012-05-07 14:51:40 -07002088 }
2089 }
buzbee2cfc6392012-05-07 14:51:40 -07002090
buzbee52a77fc2012-11-20 19:50:46 -08002091 DataFlowAnalysisDispatcher(cUnit, MethodBlockBitcodeConversion,
buzbee2cfc6392012-05-07 14:51:40 -07002092 kPreOrderDFSTraversal, false /* Iterative */);
2093
buzbee4be777b2012-07-12 14:38:18 -07002094 /*
2095 * In a few rare cases of verification failure, the verifier will
2096 * replace one or more Dalvik opcodes with the special
2097 * throw-verification-failure opcode. This can leave the SSA graph
2098 * in an invalid state, as definitions may be lost, while uses retained.
2099 * To work around this problem, we insert placeholder definitions for
2100 * all Dalvik SSA regs in the "placeholder" block. Here, after
2101 * bitcode conversion is complete, we examine those placeholder definitions
2102 * and delete any with no references (which normally is all of them).
2103 *
2104 * If any definitions remain, we link the placeholder block into the
2105 * CFG. Otherwise, it is deleted.
2106 */
2107 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
2108 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
2109 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2110 DCHECK(inst != NULL);
2111 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2112 DCHECK(val != NULL);
2113 if (val->getNumUses() == 0) {
2114 inst->eraseFromParent();
2115 }
2116 }
buzbee52a77fc2012-11-20 19:50:46 -08002117 SetDexOffset(cUnit, 0);
buzbee4be777b2012-07-12 14:38:18 -07002118 if (cUnit->placeholderBB->empty()) {
2119 cUnit->placeholderBB->eraseFromParent();
2120 } else {
2121 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2122 cUnit->irb->CreateBr(cUnit->entryTargetBB);
2123 cUnit->entryTargetBB = cUnit->placeholderBB;
2124 }
2125 cUnit->irb->SetInsertPoint(cUnit->entryBB);
2126 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07002127
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002128 if (cUnit->enableDebug & (1 << kDebugVerifyBitcode)) {
2129 if (llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction)) {
2130 LOG(INFO) << "Bitcode verification FAILED for "
2131 << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
2132 << " of size " << cUnit->insnsSize;
2133 cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
2134 }
2135 }
buzbee2cfc6392012-05-07 14:51:40 -07002136
buzbeead8f15e2012-06-18 14:49:45 -07002137 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
2138 // Write bitcode to file
2139 std::string errmsg;
2140 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
buzbee52a77fc2012-11-20 19:50:46 -08002141 ReplaceSpecialChars(fname);
buzbee6459e7c2012-10-02 14:42:41 -07002142 // TODO: make configurable change naming mechanism to avoid fname length issues.
buzbee4f1181f2012-06-22 13:52:12 -07002143 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002144
buzbee6459e7c2012-10-02 14:42:41 -07002145 if (fname.size() > 240) {
2146 LOG(INFO) << "Warning: bitcode filename too long. Truncated.";
2147 fname.resize(240);
2148 }
2149
buzbeead8f15e2012-06-18 14:49:45 -07002150 llvm::OwningPtr<llvm::tool_output_file> out_file(
2151 new llvm::tool_output_file(fname.c_str(), errmsg,
2152 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002153
buzbeead8f15e2012-06-18 14:49:45 -07002154 if (!errmsg.empty()) {
2155 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2156 }
2157
2158 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
2159 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002160 }
buzbee2cfc6392012-05-07 14:51:40 -07002161}
2162
buzbee52a77fc2012-11-20 19:50:46 -08002163RegLocation GetLoc(CompilationUnit* cUnit, llvm::Value* val) {
buzbee2cfc6392012-05-07 14:51:40 -07002164 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002165 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002166 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2167 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07002168 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07002169 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002170 // FIXME: need to be more robust, handle FP and be in a position to
2171 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002172 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2173 memset(&res, 0, sizeof(res));
2174 res.location = kLocPhysReg;
buzbee52a77fc2012-11-20 19:50:46 -08002175 res.lowReg = AllocTemp(cUnit);
buzbee4f1181f2012-06-22 13:52:12 -07002176 res.home = true;
2177 res.sRegLow = INVALID_SREG;
2178 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002179 llvm::Type* ty = val->getType();
2180 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2181 (ty == cUnit->irb->getDoubleTy()));
2182 if (res.wide) {
buzbee52a77fc2012-11-20 19:50:46 -08002183 res.highReg = AllocTemp(cUnit);
buzbee101305f2012-06-28 18:00:56 -07002184 }
buzbee4f1181f2012-06-22 13:52:12 -07002185 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002186 } else {
2187 DCHECK_EQ(valName[0], 'v');
2188 int baseSReg = INVALID_SREG;
2189 sscanf(valName.c_str(), "v%d_", &baseSReg);
2190 res = cUnit->regLocation[baseSReg];
2191 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002192 }
2193 } else {
2194 res = it->second;
2195 }
2196 return res;
2197}
2198
buzbee52a77fc2012-11-20 19:50:46 -08002199Instruction::Code GetDalvikOpcode(OpKind op, bool isConst, bool isWide)
buzbee2cfc6392012-05-07 14:51:40 -07002200{
2201 Instruction::Code res = Instruction::NOP;
2202 if (isWide) {
2203 switch(op) {
2204 case kOpAdd: res = Instruction::ADD_LONG; break;
2205 case kOpSub: res = Instruction::SUB_LONG; break;
2206 case kOpMul: res = Instruction::MUL_LONG; break;
2207 case kOpDiv: res = Instruction::DIV_LONG; break;
2208 case kOpRem: res = Instruction::REM_LONG; break;
2209 case kOpAnd: res = Instruction::AND_LONG; break;
2210 case kOpOr: res = Instruction::OR_LONG; break;
2211 case kOpXor: res = Instruction::XOR_LONG; break;
2212 case kOpLsl: res = Instruction::SHL_LONG; break;
2213 case kOpLsr: res = Instruction::USHR_LONG; break;
2214 case kOpAsr: res = Instruction::SHR_LONG; break;
2215 default: LOG(FATAL) << "Unexpected OpKind " << op;
2216 }
2217 } else if (isConst){
2218 switch(op) {
2219 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2220 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2221 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2222 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2223 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2224 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2225 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2226 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2227 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2228 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2229 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2230 default: LOG(FATAL) << "Unexpected OpKind " << op;
2231 }
2232 } else {
2233 switch(op) {
2234 case kOpAdd: res = Instruction::ADD_INT; break;
2235 case kOpSub: res = Instruction::SUB_INT; break;
2236 case kOpMul: res = Instruction::MUL_INT; break;
2237 case kOpDiv: res = Instruction::DIV_INT; break;
2238 case kOpRem: res = Instruction::REM_INT; break;
2239 case kOpAnd: res = Instruction::AND_INT; break;
2240 case kOpOr: res = Instruction::OR_INT; break;
2241 case kOpXor: res = Instruction::XOR_INT; break;
2242 case kOpLsl: res = Instruction::SHL_INT; break;
2243 case kOpLsr: res = Instruction::USHR_INT; break;
2244 case kOpAsr: res = Instruction::SHR_INT; break;
2245 default: LOG(FATAL) << "Unexpected OpKind " << op;
2246 }
2247 }
2248 return res;
2249}
2250
buzbee52a77fc2012-11-20 19:50:46 -08002251Instruction::Code GetDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
buzbee4f1181f2012-06-22 13:52:12 -07002252{
2253 Instruction::Code res = Instruction::NOP;
2254 if (isWide) {
2255 switch(op) {
2256 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2257 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2258 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2259 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2260 case kOpRem: res = Instruction::REM_DOUBLE; break;
2261 default: LOG(FATAL) << "Unexpected OpKind " << op;
2262 }
2263 } else {
2264 switch(op) {
2265 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2266 case kOpSub: res = Instruction::SUB_FLOAT; break;
2267 case kOpMul: res = Instruction::MUL_FLOAT; break;
2268 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2269 case kOpRem: res = Instruction::REM_FLOAT; break;
2270 default: LOG(FATAL) << "Unexpected OpKind " << op;
2271 }
2272 }
2273 return res;
2274}
2275
buzbee52a77fc2012-11-20 19:50:46 -08002276void CvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
buzbee4f1181f2012-06-22 13:52:12 -07002277{
buzbee52a77fc2012-11-20 19:50:46 -08002278 RegLocation rlDest = GetLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002279 /*
2280 * Normally, we won't ever generate an FP operation with an immediate
2281 * operand (not supported in Dex instruction set). However, the IR builder
2282 * may insert them - in particular for createNegFP. Recognize this case
2283 * and deal with it.
2284 */
2285 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2286 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2287 DCHECK(op2C == NULL);
2288 if ((op1C != NULL) && (op == kOpSub)) {
buzbee52a77fc2012-11-20 19:50:46 -08002289 RegLocation rlSrc = GetLoc(cUnit, inst->getOperand(1));
buzbee4f4dfc72012-07-02 14:54:44 -07002290 if (rlDest.wide) {
buzbee52a77fc2012-11-20 19:50:46 -08002291 GenArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
buzbee4f4dfc72012-07-02 14:54:44 -07002292 } else {
buzbee52a77fc2012-11-20 19:50:46 -08002293 GenArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
buzbee4f4dfc72012-07-02 14:54:44 -07002294 }
buzbee4f1181f2012-06-22 13:52:12 -07002295 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002296 DCHECK(op1C == NULL);
buzbee52a77fc2012-11-20 19:50:46 -08002297 RegLocation rlSrc1 = GetLoc(cUnit, inst->getOperand(0));
2298 RegLocation rlSrc2 = GetLoc(cUnit, inst->getOperand(1));
2299 Instruction::Code dalvikOp = GetDalvikFPOpcode(op, false, rlDest.wide);
buzbee4f4dfc72012-07-02 14:54:44 -07002300 if (rlDest.wide) {
buzbee52a77fc2012-11-20 19:50:46 -08002301 GenArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
buzbee4f4dfc72012-07-02 14:54:44 -07002302 } else {
buzbee52a77fc2012-11-20 19:50:46 -08002303 GenArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
buzbee4f4dfc72012-07-02 14:54:44 -07002304 }
buzbee4f1181f2012-06-22 13:52:12 -07002305 }
2306}
2307
buzbee52a77fc2012-11-20 19:50:46 -08002308void CvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
buzbee101305f2012-06-28 18:00:56 -07002309 Instruction::Code opcode)
2310{
buzbee52a77fc2012-11-20 19:50:46 -08002311 RegLocation rlDest = GetLoc(cUnit, inst);
2312 RegLocation rlSrc = GetLoc(cUnit, inst->getOperand(0));
2313 GenIntNarrowing(cUnit, opcode, rlDest, rlSrc);
buzbee101305f2012-06-28 18:00:56 -07002314}
2315
buzbee52a77fc2012-11-20 19:50:46 -08002316void CvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002317{
buzbee52a77fc2012-11-20 19:50:46 -08002318 RegLocation rlDest = GetLoc(cUnit, inst);
2319 RegLocation rlSrc = GetLoc(cUnit, inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002320 Instruction::Code opcode;
2321 if (rlDest.wide) {
2322 if (rlSrc.wide) {
2323 opcode = Instruction::LONG_TO_DOUBLE;
2324 } else {
2325 opcode = Instruction::INT_TO_DOUBLE;
2326 }
2327 } else {
2328 if (rlSrc.wide) {
2329 opcode = Instruction::LONG_TO_FLOAT;
2330 } else {
2331 opcode = Instruction::INT_TO_FLOAT;
2332 }
2333 }
buzbee52a77fc2012-11-20 19:50:46 -08002334 GenConversion(cUnit, opcode, rlDest, rlSrc);
buzbee76592632012-06-29 15:18:35 -07002335}
2336
buzbee52a77fc2012-11-20 19:50:46 -08002337void CvtFPToInt(CompilationUnit* cUnit, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002338{
buzbee52a77fc2012-11-20 19:50:46 -08002339 RegLocation rlDest = GetLoc(cUnit, call_inst);
2340 RegLocation rlSrc = GetLoc(cUnit, call_inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002341 Instruction::Code opcode;
2342 if (rlDest.wide) {
2343 if (rlSrc.wide) {
2344 opcode = Instruction::DOUBLE_TO_LONG;
2345 } else {
2346 opcode = Instruction::FLOAT_TO_LONG;
2347 }
2348 } else {
2349 if (rlSrc.wide) {
2350 opcode = Instruction::DOUBLE_TO_INT;
2351 } else {
2352 opcode = Instruction::FLOAT_TO_INT;
2353 }
2354 }
buzbee52a77fc2012-11-20 19:50:46 -08002355 GenConversion(cUnit, opcode, rlDest, rlSrc);
buzbee76592632012-06-29 15:18:35 -07002356}
2357
buzbee52a77fc2012-11-20 19:50:46 -08002358void CvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002359{
buzbee52a77fc2012-11-20 19:50:46 -08002360 RegLocation rlDest = GetLoc(cUnit, inst);
2361 RegLocation rlSrc = GetLoc(cUnit, inst->getOperand(0));
2362 GenConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
buzbee76592632012-06-29 15:18:35 -07002363}
2364
buzbee52a77fc2012-11-20 19:50:46 -08002365void CvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002366{
buzbee52a77fc2012-11-20 19:50:46 -08002367 RegLocation rlDest = GetLoc(cUnit, inst);
2368 RegLocation rlSrc = GetLoc(cUnit, inst->getOperand(0));
2369 rlSrc = UpdateLocWide(cUnit, rlSrc);
2370 rlSrc = WideToNarrow(cUnit, rlSrc);
2371 StoreValue(cUnit, rlDest, rlSrc);
buzbee76592632012-06-29 15:18:35 -07002372}
2373
buzbee52a77fc2012-11-20 19:50:46 -08002374void CvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
buzbee76592632012-06-29 15:18:35 -07002375{
buzbee52a77fc2012-11-20 19:50:46 -08002376 RegLocation rlDest = GetLoc(cUnit, inst);
2377 RegLocation rlSrc = GetLoc(cUnit, inst->getOperand(0));
2378 GenConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
buzbee76592632012-06-29 15:18:35 -07002379}
2380
2381
buzbee52a77fc2012-11-20 19:50:46 -08002382void CvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
buzbee101305f2012-06-28 18:00:56 -07002383{
2384 // TODO: evaluate src/tgt types and add general support for more than int to long
buzbee52a77fc2012-11-20 19:50:46 -08002385 RegLocation rlDest = GetLoc(cUnit, inst);
2386 RegLocation rlSrc = GetLoc(cUnit, inst->getOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002387 DCHECK(rlDest.wide);
2388 DCHECK(!rlSrc.wide);
2389 DCHECK(!rlDest.fp);
2390 DCHECK(!rlSrc.fp);
buzbee52a77fc2012-11-20 19:50:46 -08002391 RegLocation rlResult = EvalLoc(cUnit, rlDest, kCoreReg, true);
buzbee101305f2012-06-28 18:00:56 -07002392 if (rlSrc.location == kLocPhysReg) {
buzbee52a77fc2012-11-20 19:50:46 -08002393 OpRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
buzbee101305f2012-06-28 18:00:56 -07002394 } else {
buzbee52a77fc2012-11-20 19:50:46 -08002395 LoadValueDirect(cUnit, rlSrc, rlResult.lowReg);
buzbee101305f2012-06-28 18:00:56 -07002396 }
2397 if (isSigned) {
buzbee52a77fc2012-11-20 19:50:46 -08002398 OpRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
buzbee101305f2012-06-28 18:00:56 -07002399 } else {
buzbee52a77fc2012-11-20 19:50:46 -08002400 LoadConstant(cUnit, rlResult.highReg, 0);
buzbee101305f2012-06-28 18:00:56 -07002401 }
buzbee52a77fc2012-11-20 19:50:46 -08002402 StoreValueWide(cUnit, rlDest, rlResult);
buzbee101305f2012-06-28 18:00:56 -07002403}
2404
buzbee52a77fc2012-11-20 19:50:46 -08002405void CvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002406{
buzbee52a77fc2012-11-20 19:50:46 -08002407 RegLocation rlDest = GetLoc(cUnit, inst);
buzbee2cfc6392012-05-07 14:51:40 -07002408 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002409 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002410 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2411 if ((op == kOpSub) && (lhsImm != NULL)) {
buzbee52a77fc2012-11-20 19:50:46 -08002412 RegLocation rlSrc1 = GetLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002413 if (rlSrc1.wide) {
2414 DCHECK_EQ(lhsImm->getSExtValue(), 0);
buzbee52a77fc2012-11-20 19:50:46 -08002415 GenArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
buzbeef58c12c2012-07-03 15:06:29 -07002416 } else {
buzbee52a77fc2012-11-20 19:50:46 -08002417 GenArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
buzbeef58c12c2012-07-03 15:06:29 -07002418 lhsImm->getSExtValue());
2419 }
buzbee4f1181f2012-06-22 13:52:12 -07002420 return;
2421 }
2422 DCHECK(lhsImm == NULL);
buzbee52a77fc2012-11-20 19:50:46 -08002423 RegLocation rlSrc1 = GetLoc(cUnit, inst->getOperand(0));
buzbee2cfc6392012-05-07 14:51:40 -07002424 llvm::Value* rhs = inst->getOperand(1);
buzbee9a2487f2012-07-26 14:01:13 -07002425 llvm::ConstantInt* constRhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2426 if (!rlDest.wide && (constRhs != NULL)) {
buzbee52a77fc2012-11-20 19:50:46 -08002427 Instruction::Code dalvikOp = GetDalvikOpcode(op, true, false);
2428 GenArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, constRhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002429 } else {
buzbee52a77fc2012-11-20 19:50:46 -08002430 Instruction::Code dalvikOp = GetDalvikOpcode(op, false, rlDest.wide);
buzbee9a2487f2012-07-26 14:01:13 -07002431 RegLocation rlSrc2;
2432 if (constRhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002433 // ir_builder converts NOT_LONG to xor src, -1. Restore
2434 DCHECK_EQ(dalvikOp, Instruction::XOR_LONG);
2435 DCHECK_EQ(-1L, constRhs->getSExtValue());
2436 dalvikOp = Instruction::NOT_LONG;
buzbee9a2487f2012-07-26 14:01:13 -07002437 rlSrc2 = rlSrc1;
2438 } else {
buzbee52a77fc2012-11-20 19:50:46 -08002439 rlSrc2 = GetLoc(cUnit, rhs);
buzbee9a2487f2012-07-26 14:01:13 -07002440 }
buzbee2cfc6392012-05-07 14:51:40 -07002441 if (rlDest.wide) {
buzbee52a77fc2012-11-20 19:50:46 -08002442 GenArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
buzbee2cfc6392012-05-07 14:51:40 -07002443 } else {
buzbee52a77fc2012-11-20 19:50:46 -08002444 GenArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
buzbee2cfc6392012-05-07 14:51:40 -07002445 }
2446 }
2447}
2448
buzbee52a77fc2012-11-20 19:50:46 -08002449void CvtShiftOp(CompilationUnit* cUnit, Instruction::Code opcode,
buzbee2a83e8f2012-07-13 16:42:30 -07002450 llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002451{
buzbee2a83e8f2012-07-13 16:42:30 -07002452 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
buzbee52a77fc2012-11-20 19:50:46 -08002453 RegLocation rlDest = GetLoc(cUnit, callInst);
2454 RegLocation rlSrc = GetLoc(cUnit, callInst->getArgOperand(0));
buzbee2a83e8f2012-07-13 16:42:30 -07002455 llvm::Value* rhs = callInst->getArgOperand(1);
2456 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2457 DCHECK(!rlDest.wide);
buzbee52a77fc2012-11-20 19:50:46 -08002458 GenArithOpIntLit(cUnit, opcode, rlDest, rlSrc, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002459 } else {
buzbee52a77fc2012-11-20 19:50:46 -08002460 RegLocation rlShift = GetLoc(cUnit, rhs);
buzbee2a83e8f2012-07-13 16:42:30 -07002461 if (callInst->getType() == cUnit->irb->getInt64Ty()) {
buzbee52a77fc2012-11-20 19:50:46 -08002462 GenShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
buzbee2a83e8f2012-07-13 16:42:30 -07002463 } else {
buzbee52a77fc2012-11-20 19:50:46 -08002464 GenArithOpInt(cUnit, opcode, rlDest, rlSrc, rlShift);
buzbee2a83e8f2012-07-13 16:42:30 -07002465 }
buzbee101305f2012-06-28 18:00:56 -07002466 }
2467}
2468
buzbee52a77fc2012-11-20 19:50:46 -08002469void CvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002470{
2471 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2472 DCHECK(brInst != NULL);
2473 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2474 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
buzbee52a77fc2012-11-20 19:50:46 -08002475 OpUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
buzbee2cfc6392012-05-07 14:51:40 -07002476}
2477
buzbee52a77fc2012-11-20 19:50:46 -08002478void CvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002479{
2480 // Nop - these have already been processed
2481}
2482
buzbee52a77fc2012-11-20 19:50:46 -08002483void CvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002484{
2485 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2486 llvm::Value* retVal = retInst->getReturnValue();
2487 if (retVal != NULL) {
buzbee52a77fc2012-11-20 19:50:46 -08002488 RegLocation rlSrc = GetLoc(cUnit, retVal);
buzbee2cfc6392012-05-07 14:51:40 -07002489 if (rlSrc.wide) {
buzbee52a77fc2012-11-20 19:50:46 -08002490 StoreValueWide(cUnit, GetReturnWide(cUnit, rlSrc.fp), rlSrc);
buzbee2cfc6392012-05-07 14:51:40 -07002491 } else {
buzbee52a77fc2012-11-20 19:50:46 -08002492 StoreValue(cUnit, GetReturn(cUnit, rlSrc.fp), rlSrc);
buzbee2cfc6392012-05-07 14:51:40 -07002493 }
2494 }
buzbee52a77fc2012-11-20 19:50:46 -08002495 GenExitSequence(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002496}
2497
buzbee52a77fc2012-11-20 19:50:46 -08002498ConditionCode GetCond(llvm::ICmpInst::Predicate llvmCond)
buzbee2cfc6392012-05-07 14:51:40 -07002499{
2500 ConditionCode res = kCondAl;
2501 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002502 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002503 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2504 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2505 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002506 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002507 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002508 default: LOG(FATAL) << "Unexpected llvm condition";
2509 }
2510 return res;
2511}
2512
buzbee52a77fc2012-11-20 19:50:46 -08002513void CvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
buzbee2cfc6392012-05-07 14:51:40 -07002514{
buzbee52a77fc2012-11-20 19:50:46 -08002515 // GenCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
buzbee2cfc6392012-05-07 14:51:40 -07002516 UNIMPLEMENTED(FATAL);
2517}
2518
buzbee52a77fc2012-11-20 19:50:46 -08002519void CvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
buzbee2cfc6392012-05-07 14:51:40 -07002520 llvm::BranchInst* brInst)
2521{
2522 // Get targets
2523 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2524 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2525 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2526 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2527 // Get comparison operands
2528 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
buzbee52a77fc2012-11-20 19:50:46 -08002529 ConditionCode cond = GetCond(iCmpInst->getPredicate());
buzbee2cfc6392012-05-07 14:51:40 -07002530 llvm::Value* lhs = iCmpInst->getOperand(0);
2531 // Not expecting a constant as 1st operand
2532 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
buzbee52a77fc2012-11-20 19:50:46 -08002533 RegLocation rlSrc1 = GetLoc(cUnit, inst->getOperand(0));
2534 rlSrc1 = LoadValue(cUnit, rlSrc1, kCoreReg);
buzbee2cfc6392012-05-07 14:51:40 -07002535 llvm::Value* rhs = inst->getOperand(1);
buzbeeb046e162012-10-30 15:48:42 -07002536 if (cUnit->instructionSet == kMips) {
2537 // Compare and branch in one shot
2538 UNIMPLEMENTED(FATAL);
2539 }
buzbee2cfc6392012-05-07 14:51:40 -07002540 //Compare, then branch
2541 // TODO: handle fused CMP_LONG/IF_xxZ case
2542 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
buzbee52a77fc2012-11-20 19:50:46 -08002543 OpRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002544 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
buzbee52a77fc2012-11-20 19:50:46 -08002545 OpRegImm(cUnit, kOpCmp, rlSrc1.lowReg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002546 } else {
buzbee52a77fc2012-11-20 19:50:46 -08002547 RegLocation rlSrc2 = GetLoc(cUnit, rhs);
2548 rlSrc2 = LoadValue(cUnit, rlSrc2, kCoreReg);
2549 OpRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
buzbee2cfc6392012-05-07 14:51:40 -07002550 }
buzbee52a77fc2012-11-20 19:50:46 -08002551 OpCondBranch(cUnit, cond, taken);
buzbee2cfc6392012-05-07 14:51:40 -07002552 // Fallthrough
buzbee52a77fc2012-11-20 19:50:46 -08002553 OpUnconditionalBranch(cUnit, fallThrough);
buzbee2cfc6392012-05-07 14:51:40 -07002554}
2555
buzbee52a77fc2012-11-20 19:50:46 -08002556void CvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee2cfc6392012-05-07 14:51:40 -07002557 llvm::Function* callee)
2558{
2559 UNIMPLEMENTED(FATAL);
2560}
2561
buzbee52a77fc2012-11-20 19:50:46 -08002562void CvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee2cfc6392012-05-07 14:51:40 -07002563{
buzbee4f1181f2012-06-22 13:52:12 -07002564 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee52a77fc2012-11-20 19:50:46 -08002565 RegLocation rlSrc = GetLoc(cUnit, callInst->getArgOperand(0));
2566 RegLocation rlDest = GetLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002567 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2568 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002569 if (rlSrc.wide) {
buzbee52a77fc2012-11-20 19:50:46 -08002570 StoreValueWide(cUnit, rlDest, rlSrc);
buzbee2cfc6392012-05-07 14:51:40 -07002571 } else {
buzbee52a77fc2012-11-20 19:50:46 -08002572 StoreValue(cUnit, rlDest, rlSrc);
buzbee2cfc6392012-05-07 14:51:40 -07002573 }
2574}
2575
2576// Note: Immediate arg is a ConstantInt regardless of result type
buzbee52a77fc2012-11-20 19:50:46 -08002577void CvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee2cfc6392012-05-07 14:51:40 -07002578{
buzbee4f1181f2012-06-22 13:52:12 -07002579 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002580 llvm::ConstantInt* src =
2581 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2582 uint64_t immval = src->getZExtValue();
buzbee52a77fc2012-11-20 19:50:46 -08002583 RegLocation rlDest = GetLoc(cUnit, callInst);
2584 RegLocation rlResult = EvalLoc(cUnit, rlDest, kAnyReg, true);
buzbee2cfc6392012-05-07 14:51:40 -07002585 if (rlDest.wide) {
buzbee52a77fc2012-11-20 19:50:46 -08002586 LoadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
buzbee2cfc6392012-05-07 14:51:40 -07002587 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
buzbee52a77fc2012-11-20 19:50:46 -08002588 StoreValueWide(cUnit, rlDest, rlResult);
buzbee2cfc6392012-05-07 14:51:40 -07002589 } else {
buzbee52a77fc2012-11-20 19:50:46 -08002590 LoadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2591 StoreValue(cUnit, rlDest, rlResult);
buzbee2cfc6392012-05-07 14:51:40 -07002592 }
2593}
2594
buzbee52a77fc2012-11-20 19:50:46 -08002595void CvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee101305f2012-06-28 18:00:56 -07002596 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002597{
buzbee4f1181f2012-06-22 13:52:12 -07002598 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002599 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002600 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002601 uint32_t index = idxVal->getZExtValue();
buzbee52a77fc2012-11-20 19:50:46 -08002602 RegLocation rlDest = GetLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002603 if (isString) {
buzbee52a77fc2012-11-20 19:50:46 -08002604 GenConstString(cUnit, index, rlDest);
buzbee101305f2012-06-28 18:00:56 -07002605 } else {
buzbee52a77fc2012-11-20 19:50:46 -08002606 GenConstClass(cUnit, index, rlDest);
buzbee101305f2012-06-28 18:00:56 -07002607 }
2608}
2609
buzbee52a77fc2012-11-20 19:50:46 -08002610void CvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002611{
2612 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2613 llvm::ConstantInt* offsetVal =
2614 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee52a77fc2012-11-20 19:50:46 -08002615 RegLocation rlSrc = GetLoc(cUnit, callInst->getArgOperand(1));
2616 GenFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002617}
2618
buzbee52a77fc2012-11-20 19:50:46 -08002619void CvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee4f1181f2012-06-22 13:52:12 -07002620{
buzbee32412962012-06-26 16:27:56 -07002621 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002622 llvm::ConstantInt* typeIdxVal =
2623 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2624 uint32_t typeIdx = typeIdxVal->getZExtValue();
buzbee52a77fc2012-11-20 19:50:46 -08002625 RegLocation rlDest = GetLoc(cUnit, callInst);
2626 GenNewInstance(cUnit, typeIdx, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07002627}
2628
buzbee52a77fc2012-11-20 19:50:46 -08002629void CvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002630{
2631 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2632 llvm::ConstantInt* typeIdxVal =
2633 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2634 uint32_t typeIdx = typeIdxVal->getZExtValue();
2635 llvm::Value* len = callInst->getArgOperand(1);
buzbee52a77fc2012-11-20 19:50:46 -08002636 RegLocation rlLen = GetLoc(cUnit, len);
2637 RegLocation rlDest = GetLoc(cUnit, callInst);
2638 GenNewArray(cUnit, typeIdx, rlDest, rlLen);
buzbee8fa0fda2012-06-27 15:44:52 -07002639}
2640
buzbee52a77fc2012-11-20 19:50:46 -08002641void CvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002642{
2643 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2644 llvm::ConstantInt* typeIdxVal =
2645 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2646 uint32_t typeIdx = typeIdxVal->getZExtValue();
2647 llvm::Value* src = callInst->getArgOperand(1);
buzbee52a77fc2012-11-20 19:50:46 -08002648 RegLocation rlSrc = GetLoc(cUnit, src);
2649 RegLocation rlDest = GetLoc(cUnit, callInst);
2650 GenInstanceof(cUnit, typeIdx, rlDest, rlSrc);
buzbee8fa0fda2012-06-27 15:44:52 -07002651}
2652
buzbee52a77fc2012-11-20 19:50:46 -08002653void CvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee32412962012-06-26 16:27:56 -07002654{
2655 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2656 llvm::Value* src = callInst->getArgOperand(0);
buzbee52a77fc2012-11-20 19:50:46 -08002657 RegLocation rlSrc = GetLoc(cUnit, src);
2658 GenThrow(cUnit, rlSrc);
buzbee32412962012-06-26 16:27:56 -07002659}
2660
buzbee52a77fc2012-11-20 19:50:46 -08002661void CvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
buzbee8fa0fda2012-06-27 15:44:52 -07002662 llvm::CallInst* callInst)
2663{
2664 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2665 llvm::ConstantInt* optFlags =
2666 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2667 llvm::Value* src = callInst->getArgOperand(1);
buzbee52a77fc2012-11-20 19:50:46 -08002668 RegLocation rlSrc = GetLoc(cUnit, src);
buzbee8fa0fda2012-06-27 15:44:52 -07002669 if (isEnter) {
buzbee52a77fc2012-11-20 19:50:46 -08002670 GenMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
buzbee8fa0fda2012-06-27 15:44:52 -07002671 } else {
buzbee52a77fc2012-11-20 19:50:46 -08002672 GenMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
buzbee8fa0fda2012-06-27 15:44:52 -07002673 }
2674}
2675
buzbee52a77fc2012-11-20 19:50:46 -08002676void CvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002677{
2678 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2679 llvm::ConstantInt* optFlags =
2680 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2681 llvm::Value* src = callInst->getArgOperand(1);
buzbee52a77fc2012-11-20 19:50:46 -08002682 RegLocation rlSrc = GetLoc(cUnit, src);
2683 rlSrc = LoadValue(cUnit, rlSrc, kCoreReg);
2684 GenNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2685 RegLocation rlDest = GetLoc(cUnit, callInst);
2686 RegLocation rlResult = EvalLoc(cUnit, rlDest, kCoreReg, true);
buzbee8fa0fda2012-06-27 15:44:52 -07002687 int lenOffset = Array::LengthOffset().Int32Value();
buzbee52a77fc2012-11-20 19:50:46 -08002688 LoadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2689 StoreValue(cUnit, rlDest, rlResult);
buzbee8fa0fda2012-06-27 15:44:52 -07002690}
2691
buzbee52a77fc2012-11-20 19:50:46 -08002692void CvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee32412962012-06-26 16:27:56 -07002693{
buzbee52a77fc2012-11-20 19:50:46 -08002694 RegLocation rlDest = GetLoc(cUnit, callInst);
2695 GenMoveException(cUnit, rlDest);
buzbee32412962012-06-26 16:27:56 -07002696}
2697
buzbee52a77fc2012-11-20 19:50:46 -08002698void CvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
buzbee4f1181f2012-06-22 13:52:12 -07002699 bool isObject)
2700{
buzbee32412962012-06-26 16:27:56 -07002701 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002702 llvm::ConstantInt* typeIdxVal =
2703 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2704 uint32_t typeIdx = typeIdxVal->getZExtValue();
buzbee52a77fc2012-11-20 19:50:46 -08002705 RegLocation rlDest = GetLoc(cUnit, callInst);
2706 GenSget(cUnit, typeIdx, rlDest, isWide, isObject);
buzbee4f1181f2012-06-22 13:52:12 -07002707}
2708
buzbee52a77fc2012-11-20 19:50:46 -08002709void CvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
buzbee8fa0fda2012-06-27 15:44:52 -07002710 bool isObject)
2711{
2712 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2713 llvm::ConstantInt* typeIdxVal =
2714 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2715 uint32_t typeIdx = typeIdxVal->getZExtValue();
2716 llvm::Value* src = callInst->getArgOperand(1);
buzbee52a77fc2012-11-20 19:50:46 -08002717 RegLocation rlSrc = GetLoc(cUnit, src);
2718 GenSput(cUnit, typeIdx, rlSrc, isWide, isObject);
buzbee8fa0fda2012-06-27 15:44:52 -07002719}
2720
buzbee52a77fc2012-11-20 19:50:46 -08002721void CvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbee8fa0fda2012-06-27 15:44:52 -07002722 int scale)
2723{
2724 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2725 llvm::ConstantInt* optFlags =
2726 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee52a77fc2012-11-20 19:50:46 -08002727 RegLocation rlArray = GetLoc(cUnit, callInst->getArgOperand(1));
2728 RegLocation rlIndex = GetLoc(cUnit, callInst->getArgOperand(2));
2729 RegLocation rlDest = GetLoc(cUnit, callInst);
2730 GenArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
buzbee8fa0fda2012-06-27 15:44:52 -07002731 rlDest, scale);
2732}
2733
buzbee52a77fc2012-11-20 19:50:46 -08002734void CvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002735 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002736{
2737 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2738 llvm::ConstantInt* optFlags =
2739 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee52a77fc2012-11-20 19:50:46 -08002740 RegLocation rlSrc = GetLoc(cUnit, callInst->getArgOperand(1));
2741 RegLocation rlArray = GetLoc(cUnit, callInst->getArgOperand(2));
2742 RegLocation rlIndex = GetLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002743 if (isObject) {
buzbee52a77fc2012-11-20 19:50:46 -08002744 GenArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
buzbeef1f86362012-07-10 15:18:31 -07002745 rlSrc, scale);
2746 } else {
buzbee52a77fc2012-11-20 19:50:46 -08002747 GenArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
buzbeef1f86362012-07-10 15:18:31 -07002748 rlSrc, scale);
2749 }
2750}
2751
buzbee52a77fc2012-11-20 19:50:46 -08002752void CvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbeef1f86362012-07-10 15:18:31 -07002753{
buzbee52a77fc2012-11-20 19:50:46 -08002754 CvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
buzbeef1f86362012-07-10 15:18:31 -07002755}
2756
buzbee52a77fc2012-11-20 19:50:46 -08002757void CvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbeef1f86362012-07-10 15:18:31 -07002758 OpSize size, int scale)
2759{
buzbee52a77fc2012-11-20 19:50:46 -08002760 CvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002761}
2762
buzbee52a77fc2012-11-20 19:50:46 -08002763void CvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbee101305f2012-06-28 18:00:56 -07002764 bool isWide, bool isObj)
2765{
2766 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2767 llvm::ConstantInt* optFlags =
2768 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee52a77fc2012-11-20 19:50:46 -08002769 RegLocation rlObj = GetLoc(cUnit, callInst->getArgOperand(1));
buzbee101305f2012-06-28 18:00:56 -07002770 llvm::ConstantInt* fieldIdx =
2771 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
buzbee52a77fc2012-11-20 19:50:46 -08002772 RegLocation rlDest = GetLoc(cUnit, callInst);
2773 GenIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
buzbee101305f2012-06-28 18:00:56 -07002774 size, rlDest, rlObj, isWide, isObj);
2775}
2776
buzbee52a77fc2012-11-20 19:50:46 -08002777void CvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbee101305f2012-06-28 18:00:56 -07002778 bool isWide, bool isObj)
2779{
2780 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2781 llvm::ConstantInt* optFlags =
2782 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee52a77fc2012-11-20 19:50:46 -08002783 RegLocation rlSrc = GetLoc(cUnit, callInst->getArgOperand(1));
2784 RegLocation rlObj = GetLoc(cUnit, callInst->getArgOperand(2));
buzbee101305f2012-06-28 18:00:56 -07002785 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002786 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee52a77fc2012-11-20 19:50:46 -08002787 GenIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
buzbee101305f2012-06-28 18:00:56 -07002788 size, rlSrc, rlObj, isWide, isObj);
2789}
2790
buzbee52a77fc2012-11-20 19:50:46 -08002791void CvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002792{
2793 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2794 llvm::ConstantInt* typeIdx =
2795 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee52a77fc2012-11-20 19:50:46 -08002796 RegLocation rlSrc = GetLoc(cUnit, callInst->getArgOperand(1));
2797 GenCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
buzbee101305f2012-06-28 18:00:56 -07002798}
2799
buzbee52a77fc2012-11-20 19:50:46 -08002800void CvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002801 Instruction::Code opcode)
2802{
buzbee52a77fc2012-11-20 19:50:46 -08002803 RegLocation rlSrc1 = GetLoc(cUnit, callInst->getArgOperand(0));
2804 RegLocation rlSrc2 = GetLoc(cUnit, callInst->getArgOperand(1));
2805 RegLocation rlDest = GetLoc(cUnit, callInst);
2806 GenCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
buzbee76592632012-06-29 15:18:35 -07002807}
2808
buzbee52a77fc2012-11-20 19:50:46 -08002809void CvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee76592632012-06-29 15:18:35 -07002810{
buzbee52a77fc2012-11-20 19:50:46 -08002811 RegLocation rlSrc1 = GetLoc(cUnit, callInst->getArgOperand(0));
2812 RegLocation rlSrc2 = GetLoc(cUnit, callInst->getArgOperand(1));
2813 RegLocation rlDest = GetLoc(cUnit, callInst);
2814 GenCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
buzbee76592632012-06-29 15:18:35 -07002815}
2816
buzbee52a77fc2012-11-20 19:50:46 -08002817void CvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
buzbeef58c12c2012-07-03 15:06:29 -07002818{
2819 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2820 DCHECK(swInst != NULL);
2821 llvm::Value* testVal = swInst->getCondition();
2822 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2823 DCHECK(tableOffsetNode != NULL);
2824 llvm::ConstantInt* tableOffsetValue =
2825 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2826 int32_t tableOffset = tableOffsetValue->getSExtValue();
buzbee52a77fc2012-11-20 19:50:46 -08002827 RegLocation rlSrc = GetLoc(cUnit, testVal);
buzbeeeaf09bc2012-11-15 14:51:41 -08002828 const uint16_t* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2829 uint16_t tableMagic = *table;
buzbeea1da8a52012-07-09 14:00:21 -07002830 if (tableMagic == 0x100) {
buzbee52a77fc2012-11-20 19:50:46 -08002831 GenPackedSwitch(cUnit, tableOffset, rlSrc);
buzbeea1da8a52012-07-09 14:00:21 -07002832 } else {
2833 DCHECK_EQ(tableMagic, 0x200);
buzbee52a77fc2012-11-20 19:50:46 -08002834 GenSparseSwitch(cUnit, tableOffset, rlSrc);
buzbeea1da8a52012-07-09 14:00:21 -07002835 }
buzbeef58c12c2012-07-03 15:06:29 -07002836}
2837
buzbee52a77fc2012-11-20 19:50:46 -08002838void CvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002839 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002840{
buzbee52a77fc2012-11-20 19:50:46 -08002841 CallInfo* info = static_cast<CallInfo*>(NewMem(cUnit, sizeof(CallInfo), true, kAllocMisc));
buzbee8fa0fda2012-06-27 15:44:52 -07002842 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002843 info->result.location = kLocInvalid;
2844 } else {
buzbee52a77fc2012-11-20 19:50:46 -08002845 info->result = GetLoc(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07002846 }
2847 llvm::ConstantInt* invokeTypeVal =
2848 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2849 llvm::ConstantInt* methodIndexVal =
2850 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2851 llvm::ConstantInt* optFlagsVal =
2852 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2853 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2854 info->index = methodIndexVal->getZExtValue();
2855 info->optFlags = optFlagsVal->getZExtValue();
2856 info->offset = cUnit->currentDalvikOffset;
2857
buzbee6969d502012-06-15 16:40:31 -07002858 // Count the argument words, and then build argument array.
2859 info->numArgWords = 0;
2860 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
buzbee52a77fc2012-11-20 19:50:46 -08002861 RegLocation tLoc = GetLoc(cUnit, callInst->getArgOperand(i));
buzbee6969d502012-06-15 16:40:31 -07002862 info->numArgWords += tLoc.wide ? 2 : 1;
2863 }
buzbeecbd6d442012-11-17 14:11:25 -08002864 info->args = (info->numArgWords == 0) ? NULL : static_cast<RegLocation*>
buzbee52a77fc2012-11-20 19:50:46 -08002865 (NewMem(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc));
buzbee6969d502012-06-15 16:40:31 -07002866 // Now, fill in the location records, synthesizing high loc of wide vals
2867 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee52a77fc2012-11-20 19:50:46 -08002868 info->args[next] = GetLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002869 if (info->args[next].wide) {
2870 next++;
2871 // TODO: Might make sense to mark this as an invalid loc
2872 info->args[next].origSReg = info->args[next-1].origSReg+1;
2873 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2874 }
2875 next++;
2876 }
buzbee4f4dfc72012-07-02 14:54:44 -07002877 // TODO - rework such that we no longer need isRange
2878 info->isRange = (info->numArgWords > 5);
2879
buzbee76592632012-06-29 15:18:35 -07002880 if (isFilledNewArray) {
buzbee52a77fc2012-11-20 19:50:46 -08002881 GenFilledNewArray(cUnit, info);
buzbee101305f2012-06-28 18:00:56 -07002882 } else {
buzbee52a77fc2012-11-20 19:50:46 -08002883 GenInvoke(cUnit, info);
buzbee101305f2012-06-28 18:00:56 -07002884 }
buzbee6969d502012-06-15 16:40:31 -07002885}
2886
buzbeead8f15e2012-06-18 14:49:45 -07002887/* Look up the RegLocation associated with a Value. Must already be defined */
buzbee52a77fc2012-11-20 19:50:46 -08002888RegLocation ValToLoc(CompilationUnit* cUnit, llvm::Value* val)
buzbeead8f15e2012-06-18 14:49:45 -07002889{
2890 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2891 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2892 return it->second;
2893}
2894
buzbee52a77fc2012-11-20 19:50:46 -08002895bool MethodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
buzbee2cfc6392012-05-07 14:51:40 -07002896{
buzbee0967a252012-09-14 10:43:54 -07002897 while (cUnit->llvmBlocks.find(bb) == cUnit->llvmBlocks.end()) {
2898 llvm::BasicBlock* nextBB = NULL;
2899 cUnit->llvmBlocks.insert(bb);
2900 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2901 // Define the starting label
2902 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2903 // Extract the type and starting offset from the block's name
buzbee951c0a12012-10-03 16:31:39 -07002904 char blockType = kInvalidBlock;
2905 if (isEntry) {
2906 blockType = kNormalBlock;
2907 blockLabel->operands[0] = 0;
2908 } else if (!bb->hasName()) {
2909 blockType = kNormalBlock;
2910 blockLabel->operands[0] = DexFile::kDexNoIndex;
buzbee0967a252012-09-14 10:43:54 -07002911 } else {
buzbee951c0a12012-10-03 16:31:39 -07002912 std::string blockName = bb->getName().str();
2913 int dummy;
2914 sscanf(blockName.c_str(), kLabelFormat, &blockType, &blockLabel->operands[0], &dummy);
2915 cUnit->currentDalvikOffset = blockLabel->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002916 }
buzbee951c0a12012-10-03 16:31:39 -07002917 DCHECK((blockType == kNormalBlock) || (blockType == kCatchBlock));
2918 cUnit->currentDalvikOffset = blockLabel->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002919 // Set the label kind
2920 blockLabel->opcode = kPseudoNormalBlockLabel;
2921 // Insert the label
buzbee52a77fc2012-11-20 19:50:46 -08002922 AppendLIR(cUnit, blockLabel);
buzbee2cfc6392012-05-07 14:51:40 -07002923
buzbee0967a252012-09-14 10:43:54 -07002924 LIR* headLIR = NULL;
buzbee8320f382012-09-11 16:29:42 -07002925
buzbee0967a252012-09-14 10:43:54 -07002926 if (blockType == kCatchBlock) {
buzbee52a77fc2012-11-20 19:50:46 -08002927 headLIR = NewLIR0(cUnit, kPseudoExportedPC);
buzbee0967a252012-09-14 10:43:54 -07002928 }
buzbee8320f382012-09-11 16:29:42 -07002929
buzbee0967a252012-09-14 10:43:54 -07002930 // Free temp registers and reset redundant store tracking */
buzbee52a77fc2012-11-20 19:50:46 -08002931 ResetRegPool(cUnit);
2932 ResetDefTracking(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002933
buzbee0967a252012-09-14 10:43:54 -07002934 //TODO: restore oat incoming liveness optimization
buzbee52a77fc2012-11-20 19:50:46 -08002935 ClobberAllRegs(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002936
buzbee0967a252012-09-14 10:43:54 -07002937 if (isEntry) {
buzbee52a77fc2012-11-20 19:50:46 -08002938 RegLocation* ArgLocs = static_cast<RegLocation*>
2939 (NewMem(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc));
buzbee0967a252012-09-14 10:43:54 -07002940 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2941 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2942 // Skip past Method*
2943 it++;
2944 for (unsigned i = 0; it != it_end; ++it) {
2945 llvm::Value* val = it;
buzbee52a77fc2012-11-20 19:50:46 -08002946 ArgLocs[i++] = ValToLoc(cUnit, val);
buzbee0967a252012-09-14 10:43:54 -07002947 llvm::Type* ty = val->getType();
2948 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
buzbee52a77fc2012-11-20 19:50:46 -08002949 ArgLocs[i] = ArgLocs[i-1];
2950 ArgLocs[i].lowReg = ArgLocs[i].highReg;
2951 ArgLocs[i].origSReg++;
2952 ArgLocs[i].sRegLow = INVALID_SREG;
2953 ArgLocs[i].highWord = true;
buzbee0967a252012-09-14 10:43:54 -07002954 i++;
2955 }
2956 }
buzbee52a77fc2012-11-20 19:50:46 -08002957 GenEntrySequence(cUnit, ArgLocs, cUnit->methodLoc);
buzbee0967a252012-09-14 10:43:54 -07002958 }
2959
2960 // Visit all of the instructions in the block
2961 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2962 llvm::Instruction* inst = it;
2963 llvm::BasicBlock::iterator nextIt = ++it;
2964 // Extract the Dalvik offset from the instruction
2965 uint32_t opcode = inst->getOpcode();
2966 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2967 if (dexOffsetNode != NULL) {
2968 llvm::ConstantInt* dexOffsetValue =
2969 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2970 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2971 }
2972
buzbee52a77fc2012-11-20 19:50:46 -08002973 ResetRegPool(cUnit);
buzbee0967a252012-09-14 10:43:54 -07002974 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
buzbee52a77fc2012-11-20 19:50:46 -08002975 ClobberAllRegs(cUnit);
buzbee0967a252012-09-14 10:43:54 -07002976 }
2977
2978 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
buzbee52a77fc2012-11-20 19:50:46 -08002979 ResetDefTracking(cUnit);
buzbee0967a252012-09-14 10:43:54 -07002980 }
2981
2982 #ifndef NDEBUG
2983 /* Reset temp tracking sanity check */
2984 cUnit->liveSReg = INVALID_SREG;
2985 #endif
2986
2987 // TODO: use llvm opcode name here instead of "boundary" if verbose
buzbee52a77fc2012-11-20 19:50:46 -08002988 LIR* boundaryLIR = MarkBoundary(cUnit, cUnit->currentDalvikOffset, "boundary");
buzbee0967a252012-09-14 10:43:54 -07002989
2990 /* Remember the first LIR for thisl block*/
2991 if (headLIR == NULL) {
2992 headLIR = boundaryLIR;
2993 headLIR->defMask = ENCODE_ALL;
2994 }
2995
2996 switch(opcode) {
2997
2998 case llvm::Instruction::ICmp: {
2999 llvm::Instruction* nextInst = nextIt;
3000 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
3001 if (brInst != NULL /* and... */) {
buzbee52a77fc2012-11-20 19:50:46 -08003002 CvtICmpBr(cUnit, inst, brInst);
buzbee0967a252012-09-14 10:43:54 -07003003 ++it;
3004 } else {
buzbee52a77fc2012-11-20 19:50:46 -08003005 CvtICmp(cUnit, inst);
buzbee0967a252012-09-14 10:43:54 -07003006 }
3007 }
3008 break;
3009
3010 case llvm::Instruction::Call: {
3011 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
3012 llvm::Function* callee = callInst->getCalledFunction();
3013 greenland::IntrinsicHelper::IntrinsicId id =
3014 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3015 switch (id) {
3016 case greenland::IntrinsicHelper::AllocaShadowFrame:
3017 case greenland::IntrinsicHelper::SetShadowFrameEntry:
3018 case greenland::IntrinsicHelper::PopShadowFrame:
TDYa1278e950c12012-11-02 09:58:19 -07003019 case greenland::IntrinsicHelper::SetVReg:
buzbee0967a252012-09-14 10:43:54 -07003020 // Ignore shadow frame stuff for quick compiler
3021 break;
3022 case greenland::IntrinsicHelper::CopyInt:
3023 case greenland::IntrinsicHelper::CopyObj:
3024 case greenland::IntrinsicHelper::CopyFloat:
3025 case greenland::IntrinsicHelper::CopyLong:
3026 case greenland::IntrinsicHelper::CopyDouble:
buzbee52a77fc2012-11-20 19:50:46 -08003027 CvtCopy(cUnit, callInst);
buzbee0967a252012-09-14 10:43:54 -07003028 break;
3029 case greenland::IntrinsicHelper::ConstInt:
3030 case greenland::IntrinsicHelper::ConstObj:
3031 case greenland::IntrinsicHelper::ConstLong:
3032 case greenland::IntrinsicHelper::ConstFloat:
3033 case greenland::IntrinsicHelper::ConstDouble:
buzbee52a77fc2012-11-20 19:50:46 -08003034 CvtConst(cUnit, callInst);
buzbee0967a252012-09-14 10:43:54 -07003035 break;
3036 case greenland::IntrinsicHelper::DivInt:
3037 case greenland::IntrinsicHelper::DivLong:
buzbee52a77fc2012-11-20 19:50:46 -08003038 CvtBinOp(cUnit, kOpDiv, inst);
buzbee0967a252012-09-14 10:43:54 -07003039 break;
3040 case greenland::IntrinsicHelper::RemInt:
3041 case greenland::IntrinsicHelper::RemLong:
buzbee52a77fc2012-11-20 19:50:46 -08003042 CvtBinOp(cUnit, kOpRem, inst);
buzbee0967a252012-09-14 10:43:54 -07003043 break;
3044 case greenland::IntrinsicHelper::MethodInfo:
3045 // Already dealt with - just ignore it here.
3046 break;
3047 case greenland::IntrinsicHelper::CheckSuspend:
buzbee52a77fc2012-11-20 19:50:46 -08003048 GenSuspendTest(cUnit, 0 /* optFlags already applied */);
buzbee0967a252012-09-14 10:43:54 -07003049 break;
3050 case greenland::IntrinsicHelper::HLInvokeObj:
3051 case greenland::IntrinsicHelper::HLInvokeFloat:
3052 case greenland::IntrinsicHelper::HLInvokeDouble:
3053 case greenland::IntrinsicHelper::HLInvokeLong:
3054 case greenland::IntrinsicHelper::HLInvokeInt:
buzbee52a77fc2012-11-20 19:50:46 -08003055 CvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
buzbee0967a252012-09-14 10:43:54 -07003056 break;
3057 case greenland::IntrinsicHelper::HLInvokeVoid:
buzbee52a77fc2012-11-20 19:50:46 -08003058 CvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
buzbee0967a252012-09-14 10:43:54 -07003059 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003060 case greenland::IntrinsicHelper::HLFilledNewArray:
buzbee52a77fc2012-11-20 19:50:46 -08003061 CvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
buzbee0967a252012-09-14 10:43:54 -07003062 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003063 case greenland::IntrinsicHelper::HLFillArrayData:
buzbee52a77fc2012-11-20 19:50:46 -08003064 CvtFillArrayData(cUnit, callInst);
buzbee0967a252012-09-14 10:43:54 -07003065 break;
3066 case greenland::IntrinsicHelper::ConstString:
buzbee52a77fc2012-11-20 19:50:46 -08003067 CvtConstObject(cUnit, callInst, true /* isString */);
buzbee0967a252012-09-14 10:43:54 -07003068 break;
3069 case greenland::IntrinsicHelper::ConstClass:
buzbee52a77fc2012-11-20 19:50:46 -08003070 CvtConstObject(cUnit, callInst, false /* isString */);
buzbee0967a252012-09-14 10:43:54 -07003071 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003072 case greenland::IntrinsicHelper::HLCheckCast:
buzbee52a77fc2012-11-20 19:50:46 -08003073 CvtCheckCast(cUnit, callInst);
buzbee0967a252012-09-14 10:43:54 -07003074 break;
3075 case greenland::IntrinsicHelper::NewInstance:
buzbee52a77fc2012-11-20 19:50:46 -08003076 CvtNewInstance(cUnit, callInst);
buzbee0967a252012-09-14 10:43:54 -07003077 break;
3078 case greenland::IntrinsicHelper::HLSgetObject:
buzbee52a77fc2012-11-20 19:50:46 -08003079 CvtSget(cUnit, callInst, false /* wide */, true /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003080 break;
3081 case greenland::IntrinsicHelper::HLSget:
3082 case greenland::IntrinsicHelper::HLSgetFloat:
3083 case greenland::IntrinsicHelper::HLSgetBoolean:
3084 case greenland::IntrinsicHelper::HLSgetByte:
3085 case greenland::IntrinsicHelper::HLSgetChar:
3086 case greenland::IntrinsicHelper::HLSgetShort:
buzbee52a77fc2012-11-20 19:50:46 -08003087 CvtSget(cUnit, callInst, false /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003088 break;
3089 case greenland::IntrinsicHelper::HLSgetWide:
3090 case greenland::IntrinsicHelper::HLSgetDouble:
buzbee52a77fc2012-11-20 19:50:46 -08003091 CvtSget(cUnit, callInst, true /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003092 break;
3093 case greenland::IntrinsicHelper::HLSput:
3094 case greenland::IntrinsicHelper::HLSputFloat:
3095 case greenland::IntrinsicHelper::HLSputBoolean:
3096 case greenland::IntrinsicHelper::HLSputByte:
3097 case greenland::IntrinsicHelper::HLSputChar:
3098 case greenland::IntrinsicHelper::HLSputShort:
buzbee52a77fc2012-11-20 19:50:46 -08003099 CvtSput(cUnit, callInst, false /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003100 break;
3101 case greenland::IntrinsicHelper::HLSputWide:
3102 case greenland::IntrinsicHelper::HLSputDouble:
buzbee52a77fc2012-11-20 19:50:46 -08003103 CvtSput(cUnit, callInst, true /* wide */, false /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003104 break;
3105 case greenland::IntrinsicHelper::HLSputObject:
buzbee52a77fc2012-11-20 19:50:46 -08003106 CvtSput(cUnit, callInst, false /* wide */, true /* Object */);
buzbee0967a252012-09-14 10:43:54 -07003107 break;
3108 case greenland::IntrinsicHelper::GetException:
buzbee52a77fc2012-11-20 19:50:46 -08003109 CvtMoveException(cUnit, callInst);
buzbee0967a252012-09-14 10:43:54 -07003110 break;
TDYa127f71bf5a2012-07-29 20:09:52 -07003111 case greenland::IntrinsicHelper::HLThrowException:
buzbee52a77fc2012-11-20 19:50:46 -08003112 CvtThrow(cUnit, callInst);
buzbee0967a252012-09-14 10:43:54 -07003113 break;
3114 case greenland::IntrinsicHelper::MonitorEnter:
buzbee52a77fc2012-11-20 19:50:46 -08003115 CvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
buzbee0967a252012-09-14 10:43:54 -07003116 break;
3117 case greenland::IntrinsicHelper::MonitorExit:
buzbee52a77fc2012-11-20 19:50:46 -08003118 CvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
buzbee0967a252012-09-14 10:43:54 -07003119 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003120 case greenland::IntrinsicHelper::OptArrayLength:
buzbee52a77fc2012-11-20 19:50:46 -08003121 CvtArrayLength(cUnit, callInst);
buzbee0967a252012-09-14 10:43:54 -07003122 break;
3123 case greenland::IntrinsicHelper::NewArray:
buzbee52a77fc2012-11-20 19:50:46 -08003124 CvtNewArray(cUnit, callInst);
buzbee0967a252012-09-14 10:43:54 -07003125 break;
3126 case greenland::IntrinsicHelper::InstanceOf:
buzbee52a77fc2012-11-20 19:50:46 -08003127 CvtInstanceOf(cUnit, callInst);
buzbee0967a252012-09-14 10:43:54 -07003128 break;
3129
3130 case greenland::IntrinsicHelper::HLArrayGet:
3131 case greenland::IntrinsicHelper::HLArrayGetObject:
3132 case greenland::IntrinsicHelper::HLArrayGetFloat:
buzbee52a77fc2012-11-20 19:50:46 -08003133 CvtAget(cUnit, callInst, kWord, 2);
buzbee0967a252012-09-14 10:43:54 -07003134 break;
3135 case greenland::IntrinsicHelper::HLArrayGetWide:
3136 case greenland::IntrinsicHelper::HLArrayGetDouble:
buzbee52a77fc2012-11-20 19:50:46 -08003137 CvtAget(cUnit, callInst, kLong, 3);
buzbee0967a252012-09-14 10:43:54 -07003138 break;
3139 case greenland::IntrinsicHelper::HLArrayGetBoolean:
buzbee52a77fc2012-11-20 19:50:46 -08003140 CvtAget(cUnit, callInst, kUnsignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003141 break;
3142 case greenland::IntrinsicHelper::HLArrayGetByte:
buzbee52a77fc2012-11-20 19:50:46 -08003143 CvtAget(cUnit, callInst, kSignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003144 break;
3145 case greenland::IntrinsicHelper::HLArrayGetChar:
buzbee52a77fc2012-11-20 19:50:46 -08003146 CvtAget(cUnit, callInst, kUnsignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003147 break;
3148 case greenland::IntrinsicHelper::HLArrayGetShort:
buzbee52a77fc2012-11-20 19:50:46 -08003149 CvtAget(cUnit, callInst, kSignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003150 break;
3151
3152 case greenland::IntrinsicHelper::HLArrayPut:
3153 case greenland::IntrinsicHelper::HLArrayPutFloat:
buzbee52a77fc2012-11-20 19:50:46 -08003154 CvtAputPrimitive(cUnit, callInst, kWord, 2);
buzbee0967a252012-09-14 10:43:54 -07003155 break;
3156 case greenland::IntrinsicHelper::HLArrayPutObject:
buzbee52a77fc2012-11-20 19:50:46 -08003157 CvtAputObj(cUnit, callInst);
buzbee0967a252012-09-14 10:43:54 -07003158 break;
3159 case greenland::IntrinsicHelper::HLArrayPutWide:
3160 case greenland::IntrinsicHelper::HLArrayPutDouble:
buzbee52a77fc2012-11-20 19:50:46 -08003161 CvtAputPrimitive(cUnit, callInst, kLong, 3);
buzbee0967a252012-09-14 10:43:54 -07003162 break;
3163 case greenland::IntrinsicHelper::HLArrayPutBoolean:
buzbee52a77fc2012-11-20 19:50:46 -08003164 CvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003165 break;
3166 case greenland::IntrinsicHelper::HLArrayPutByte:
buzbee52a77fc2012-11-20 19:50:46 -08003167 CvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
buzbee0967a252012-09-14 10:43:54 -07003168 break;
3169 case greenland::IntrinsicHelper::HLArrayPutChar:
buzbee52a77fc2012-11-20 19:50:46 -08003170 CvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003171 break;
3172 case greenland::IntrinsicHelper::HLArrayPutShort:
buzbee52a77fc2012-11-20 19:50:46 -08003173 CvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
buzbee0967a252012-09-14 10:43:54 -07003174 break;
3175
3176 case greenland::IntrinsicHelper::HLIGet:
3177 case greenland::IntrinsicHelper::HLIGetFloat:
buzbee52a77fc2012-11-20 19:50:46 -08003178 CvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003179 break;
3180 case greenland::IntrinsicHelper::HLIGetObject:
buzbee52a77fc2012-11-20 19:50:46 -08003181 CvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003182 break;
3183 case greenland::IntrinsicHelper::HLIGetWide:
3184 case greenland::IntrinsicHelper::HLIGetDouble:
buzbee52a77fc2012-11-20 19:50:46 -08003185 CvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003186 break;
3187 case greenland::IntrinsicHelper::HLIGetBoolean:
buzbee52a77fc2012-11-20 19:50:46 -08003188 CvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
buzbee0967a252012-09-14 10:43:54 -07003189 false /* obj */);
3190 break;
3191 case greenland::IntrinsicHelper::HLIGetByte:
buzbee52a77fc2012-11-20 19:50:46 -08003192 CvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
buzbee0967a252012-09-14 10:43:54 -07003193 false /* obj */);
3194 break;
3195 case greenland::IntrinsicHelper::HLIGetChar:
buzbee52a77fc2012-11-20 19:50:46 -08003196 CvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
buzbee0967a252012-09-14 10:43:54 -07003197 false /* obj */);
3198 break;
3199 case greenland::IntrinsicHelper::HLIGetShort:
buzbee52a77fc2012-11-20 19:50:46 -08003200 CvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
buzbee0967a252012-09-14 10:43:54 -07003201 false /* obj */);
3202 break;
3203
3204 case greenland::IntrinsicHelper::HLIPut:
3205 case greenland::IntrinsicHelper::HLIPutFloat:
buzbee52a77fc2012-11-20 19:50:46 -08003206 CvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003207 break;
3208 case greenland::IntrinsicHelper::HLIPutObject:
buzbee52a77fc2012-11-20 19:50:46 -08003209 CvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003210 break;
3211 case greenland::IntrinsicHelper::HLIPutWide:
3212 case greenland::IntrinsicHelper::HLIPutDouble:
buzbee52a77fc2012-11-20 19:50:46 -08003213 CvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
buzbee0967a252012-09-14 10:43:54 -07003214 break;
3215 case greenland::IntrinsicHelper::HLIPutBoolean:
buzbee52a77fc2012-11-20 19:50:46 -08003216 CvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
buzbee0967a252012-09-14 10:43:54 -07003217 false /* obj */);
3218 break;
3219 case greenland::IntrinsicHelper::HLIPutByte:
buzbee52a77fc2012-11-20 19:50:46 -08003220 CvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
buzbee0967a252012-09-14 10:43:54 -07003221 false /* obj */);
3222 break;
3223 case greenland::IntrinsicHelper::HLIPutChar:
buzbee52a77fc2012-11-20 19:50:46 -08003224 CvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
buzbee0967a252012-09-14 10:43:54 -07003225 false /* obj */);
3226 break;
3227 case greenland::IntrinsicHelper::HLIPutShort:
buzbee52a77fc2012-11-20 19:50:46 -08003228 CvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
buzbee0967a252012-09-14 10:43:54 -07003229 false /* obj */);
3230 break;
3231
3232 case greenland::IntrinsicHelper::IntToChar:
buzbee52a77fc2012-11-20 19:50:46 -08003233 CvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
buzbee0967a252012-09-14 10:43:54 -07003234 break;
3235 case greenland::IntrinsicHelper::IntToShort:
buzbee52a77fc2012-11-20 19:50:46 -08003236 CvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
buzbee0967a252012-09-14 10:43:54 -07003237 break;
3238 case greenland::IntrinsicHelper::IntToByte:
buzbee52a77fc2012-11-20 19:50:46 -08003239 CvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
buzbee0967a252012-09-14 10:43:54 -07003240 break;
3241
TDYa1274ec8ccd2012-08-11 07:04:57 -07003242 case greenland::IntrinsicHelper::F2I:
3243 case greenland::IntrinsicHelper::D2I:
3244 case greenland::IntrinsicHelper::F2L:
3245 case greenland::IntrinsicHelper::D2L:
buzbee52a77fc2012-11-20 19:50:46 -08003246 CvtFPToInt(cUnit, callInst);
TDYa1274ec8ccd2012-08-11 07:04:57 -07003247 break;
3248
buzbee0967a252012-09-14 10:43:54 -07003249 case greenland::IntrinsicHelper::CmplFloat:
buzbee52a77fc2012-11-20 19:50:46 -08003250 CvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
buzbee0967a252012-09-14 10:43:54 -07003251 break;
3252 case greenland::IntrinsicHelper::CmpgFloat:
buzbee52a77fc2012-11-20 19:50:46 -08003253 CvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
buzbee0967a252012-09-14 10:43:54 -07003254 break;
3255 case greenland::IntrinsicHelper::CmplDouble:
buzbee52a77fc2012-11-20 19:50:46 -08003256 CvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
buzbee0967a252012-09-14 10:43:54 -07003257 break;
3258 case greenland::IntrinsicHelper::CmpgDouble:
buzbee52a77fc2012-11-20 19:50:46 -08003259 CvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
buzbee0967a252012-09-14 10:43:54 -07003260 break;
3261
3262 case greenland::IntrinsicHelper::CmpLong:
buzbee52a77fc2012-11-20 19:50:46 -08003263 CvtLongCompare(cUnit, callInst);
buzbee0967a252012-09-14 10:43:54 -07003264 break;
3265
3266 case greenland::IntrinsicHelper::SHLLong:
buzbee52a77fc2012-11-20 19:50:46 -08003267 CvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
buzbee0967a252012-09-14 10:43:54 -07003268 break;
3269 case greenland::IntrinsicHelper::SHRLong:
buzbee52a77fc2012-11-20 19:50:46 -08003270 CvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
buzbee0967a252012-09-14 10:43:54 -07003271 break;
3272 case greenland::IntrinsicHelper::USHRLong:
buzbee52a77fc2012-11-20 19:50:46 -08003273 CvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
buzbee0967a252012-09-14 10:43:54 -07003274 break;
3275 case greenland::IntrinsicHelper::SHLInt:
buzbee52a77fc2012-11-20 19:50:46 -08003276 CvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
buzbee0967a252012-09-14 10:43:54 -07003277 break;
3278 case greenland::IntrinsicHelper::SHRInt:
buzbee52a77fc2012-11-20 19:50:46 -08003279 CvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
buzbee0967a252012-09-14 10:43:54 -07003280 break;
3281 case greenland::IntrinsicHelper::USHRInt:
buzbee52a77fc2012-11-20 19:50:46 -08003282 CvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
buzbee0967a252012-09-14 10:43:54 -07003283 break;
3284
3285 case greenland::IntrinsicHelper::CatchTargets: {
3286 llvm::SwitchInst* swInst =
3287 llvm::dyn_cast<llvm::SwitchInst>(nextIt);
3288 DCHECK(swInst != NULL);
3289 /*
3290 * Discard the edges and the following conditional branch.
3291 * Do a direct branch to the default target (which is the
3292 * "work" portion of the pair.
3293 * TODO: awful code layout - rework
3294 */
3295 llvm::BasicBlock* targetBB = swInst->getDefaultDest();
3296 DCHECK(targetBB != NULL);
buzbee52a77fc2012-11-20 19:50:46 -08003297 OpUnconditionalBranch(cUnit,
buzbee0967a252012-09-14 10:43:54 -07003298 cUnit->blockToLabelMap.Get(targetBB));
3299 ++it;
3300 // Set next bb to default target - improves code layout
3301 nextBB = targetBB;
3302 }
3303 break;
3304
3305 default:
buzbeecbd6d442012-11-17 14:11:25 -08003306 LOG(FATAL) << "Unexpected intrinsic " << cUnit->intrinsic_helper->GetName(id);
buzbee0967a252012-09-14 10:43:54 -07003307 }
3308 }
3309 break;
3310
buzbee52a77fc2012-11-20 19:50:46 -08003311 case llvm::Instruction::Br: CvtBr(cUnit, inst); break;
3312 case llvm::Instruction::Add: CvtBinOp(cUnit, kOpAdd, inst); break;
3313 case llvm::Instruction::Sub: CvtBinOp(cUnit, kOpSub, inst); break;
3314 case llvm::Instruction::Mul: CvtBinOp(cUnit, kOpMul, inst); break;
3315 case llvm::Instruction::SDiv: CvtBinOp(cUnit, kOpDiv, inst); break;
3316 case llvm::Instruction::SRem: CvtBinOp(cUnit, kOpRem, inst); break;
3317 case llvm::Instruction::And: CvtBinOp(cUnit, kOpAnd, inst); break;
3318 case llvm::Instruction::Or: CvtBinOp(cUnit, kOpOr, inst); break;
3319 case llvm::Instruction::Xor: CvtBinOp(cUnit, kOpXor, inst); break;
3320 case llvm::Instruction::PHI: CvtPhi(cUnit, inst); break;
3321 case llvm::Instruction::Ret: CvtRet(cUnit, inst); break;
3322 case llvm::Instruction::FAdd: CvtBinFPOp(cUnit, kOpAdd, inst); break;
3323 case llvm::Instruction::FSub: CvtBinFPOp(cUnit, kOpSub, inst); break;
3324 case llvm::Instruction::FMul: CvtBinFPOp(cUnit, kOpMul, inst); break;
3325 case llvm::Instruction::FDiv: CvtBinFPOp(cUnit, kOpDiv, inst); break;
3326 case llvm::Instruction::FRem: CvtBinFPOp(cUnit, kOpRem, inst); break;
3327 case llvm::Instruction::SIToFP: CvtIntToFP(cUnit, inst); break;
3328 case llvm::Instruction::FPTrunc: CvtDoubleToFloat(cUnit, inst); break;
3329 case llvm::Instruction::FPExt: CvtFloatToDouble(cUnit, inst); break;
3330 case llvm::Instruction::Trunc: CvtTrunc(cUnit, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003331
buzbee52a77fc2012-11-20 19:50:46 -08003332 case llvm::Instruction::ZExt: CvtIntExt(cUnit, inst, false /* signed */);
buzbee0967a252012-09-14 10:43:54 -07003333 break;
buzbee52a77fc2012-11-20 19:50:46 -08003334 case llvm::Instruction::SExt: CvtIntExt(cUnit, inst, true /* signed */);
buzbee0967a252012-09-14 10:43:54 -07003335 break;
3336
buzbee52a77fc2012-11-20 19:50:46 -08003337 case llvm::Instruction::Switch: CvtSwitch(cUnit, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003338
3339 case llvm::Instruction::Unreachable:
3340 break; // FIXME: can we really ignore these?
3341
3342 case llvm::Instruction::Shl:
3343 case llvm::Instruction::LShr:
3344 case llvm::Instruction::AShr:
3345 case llvm::Instruction::Invoke:
3346 case llvm::Instruction::FPToUI:
TDYa1274ec8ccd2012-08-11 07:04:57 -07003347 case llvm::Instruction::FPToSI:
buzbee0967a252012-09-14 10:43:54 -07003348 case llvm::Instruction::UIToFP:
3349 case llvm::Instruction::PtrToInt:
3350 case llvm::Instruction::IntToPtr:
3351 case llvm::Instruction::FCmp:
3352 case llvm::Instruction::URem:
3353 case llvm::Instruction::UDiv:
3354 case llvm::Instruction::Resume:
3355 case llvm::Instruction::Alloca:
3356 case llvm::Instruction::GetElementPtr:
3357 case llvm::Instruction::Fence:
3358 case llvm::Instruction::AtomicCmpXchg:
3359 case llvm::Instruction::AtomicRMW:
3360 case llvm::Instruction::BitCast:
3361 case llvm::Instruction::VAArg:
3362 case llvm::Instruction::Select:
3363 case llvm::Instruction::UserOp1:
3364 case llvm::Instruction::UserOp2:
3365 case llvm::Instruction::ExtractElement:
3366 case llvm::Instruction::InsertElement:
3367 case llvm::Instruction::ShuffleVector:
3368 case llvm::Instruction::ExtractValue:
3369 case llvm::Instruction::InsertValue:
3370 case llvm::Instruction::LandingPad:
3371 case llvm::Instruction::IndirectBr:
3372 case llvm::Instruction::Load:
3373 case llvm::Instruction::Store:
3374 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3375
3376 default:
3377 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3378 break;
buzbeead8f15e2012-06-18 14:49:45 -07003379 }
3380 }
buzbee2cfc6392012-05-07 14:51:40 -07003381
buzbee0967a252012-09-14 10:43:54 -07003382 if (headLIR != NULL) {
buzbee52a77fc2012-11-20 19:50:46 -08003383 ApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
buzbee2cfc6392012-05-07 14:51:40 -07003384 }
buzbee0967a252012-09-14 10:43:54 -07003385 if (nextBB != NULL) {
3386 bb = nextBB;
3387 nextBB = NULL;
buzbee6969d502012-06-15 16:40:31 -07003388 }
buzbee6969d502012-06-15 16:40:31 -07003389 }
buzbee2cfc6392012-05-07 14:51:40 -07003390 return false;
3391}
3392
3393/*
3394 * Convert LLVM_IR to MIR:
3395 * o Iterate through the LLVM_IR and construct a graph using
3396 * standard MIR building blocks.
3397 * o Perform a basic-block optimization pass to remove unnecessary
3398 * store/load sequences.
3399 * o Convert the LLVM Value operands into RegLocations where applicable.
3400 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3401 * o Perform register promotion
3402 * o Iterate through the graph a basic block at a time, generating
3403 * LIR.
3404 * o Assemble LIR as usual.
3405 * o Profit.
3406 */
buzbee52a77fc2012-11-20 19:50:46 -08003407void MethodBitcode2LIR(CompilationUnit* cUnit)
buzbee2cfc6392012-05-07 14:51:40 -07003408{
buzbeead8f15e2012-06-18 14:49:45 -07003409 llvm::Function* func = cUnit->func;
3410 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003411 // Allocate a list for LIR basic block labels
3412 cUnit->blockLabelList =
buzbee52a77fc2012-11-20 19:50:46 -08003413 static_cast<LIR*>(NewMem(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR));
buzbeea1da8a52012-07-09 14:00:21 -07003414 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003415 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003416 for (llvm::Function::iterator i = func->begin(),
3417 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003418 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3419 &labelList[nextLabel++]);
3420 }
buzbeead8f15e2012-06-18 14:49:45 -07003421
3422 /*
3423 * Keep honest - clear regLocations, Value => RegLocation,
3424 * promotion map and VmapTables.
3425 */
3426 cUnit->locMap.clear(); // Start fresh
3427 cUnit->regLocation = NULL;
3428 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3429 i++) {
3430 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3431 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3432 }
3433 cUnit->coreSpillMask = 0;
3434 cUnit->numCoreSpills = 0;
3435 cUnit->fpSpillMask = 0;
3436 cUnit->numFPSpills = 0;
3437 cUnit->coreVmapTable.clear();
3438 cUnit->fpVmapTable.clear();
buzbeead8f15e2012-06-18 14:49:45 -07003439
3440 /*
3441 * At this point, we've lost all knowledge of register promotion.
3442 * Rebuild that info from the MethodInfo intrinsic (if it
buzbeeca7a5e42012-08-20 11:12:18 -07003443 * exists - not required for correctness). Normally, this will
3444 * be the first instruction we encounter, so we won't have to iterate
3445 * through everything.
buzbeead8f15e2012-06-18 14:49:45 -07003446 */
buzbeeca7a5e42012-08-20 11:12:18 -07003447 for (llvm::inst_iterator i = llvm::inst_begin(func),
3448 e = llvm::inst_end(func); i != e; ++i) {
3449 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(&*i);
3450 if (callInst != NULL) {
3451 llvm::Function* callee = callInst->getCalledFunction();
3452 greenland::IntrinsicHelper::IntrinsicId id =
3453 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3454 if (id == greenland::IntrinsicHelper::MethodInfo) {
3455 if (cUnit->printMe) {
3456 LOG(INFO) << "Found MethodInfo";
3457 }
3458 llvm::MDNode* regInfoNode = callInst->getMetadata("RegInfo");
3459 if (regInfoNode != NULL) {
3460 llvm::ConstantInt* numInsValue =
3461 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(0));
3462 llvm::ConstantInt* numRegsValue =
3463 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(1));
3464 llvm::ConstantInt* numOutsValue =
3465 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(2));
3466 llvm::ConstantInt* numCompilerTempsValue =
3467 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(3));
3468 llvm::ConstantInt* numSSARegsValue =
3469 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(4));
3470 if (cUnit->printMe) {
3471 LOG(INFO) << "RegInfo - Ins:" << numInsValue->getZExtValue()
3472 << ", Regs:" << numRegsValue->getZExtValue()
3473 << ", Outs:" << numOutsValue->getZExtValue()
3474 << ", CTemps:" << numCompilerTempsValue->getZExtValue()
3475 << ", SSARegs:" << numSSARegsValue->getZExtValue();
3476 }
3477 }
3478 llvm::MDNode* pmapInfoNode = callInst->getMetadata("PromotionMap");
3479 if (pmapInfoNode != NULL) {
3480 int elems = pmapInfoNode->getNumOperands();
3481 if (cUnit->printMe) {
3482 LOG(INFO) << "PMap size: " << elems;
3483 }
3484 for (int i = 0; i < elems; i++) {
3485 llvm::ConstantInt* rawMapData =
3486 static_cast<llvm::ConstantInt*>(pmapInfoNode->getOperand(i));
3487 uint32_t mapData = rawMapData->getZExtValue();
3488 PromotionMap* p = &cUnit->promotionMap[i];
3489 p->firstInPair = (mapData >> 24) & 0xff;
buzbee52a77fc2012-11-20 19:50:46 -08003490 p->FpReg = (mapData >> 16) & 0xff;
buzbeeca7a5e42012-08-20 11:12:18 -07003491 p->coreReg = (mapData >> 8) & 0xff;
3492 p->fpLocation = static_cast<RegLocationType>((mapData >> 4) & 0xf);
3493 if (p->fpLocation == kLocPhysReg) {
buzbee52a77fc2012-11-20 19:50:46 -08003494 RecordFpPromotion(cUnit, p->FpReg, i);
buzbeeca7a5e42012-08-20 11:12:18 -07003495 }
3496 p->coreLocation = static_cast<RegLocationType>(mapData & 0xf);
3497 if (p->coreLocation == kLocPhysReg) {
buzbee52a77fc2012-11-20 19:50:46 -08003498 RecordCorePromotion(cUnit, p->coreReg, i);
buzbeeca7a5e42012-08-20 11:12:18 -07003499 }
3500 }
3501 if (cUnit->printMe) {
buzbee52a77fc2012-11-20 19:50:46 -08003502 DumpPromotionMap(cUnit);
buzbeeca7a5e42012-08-20 11:12:18 -07003503 }
3504 }
3505 break;
3506 }
3507 }
3508 }
buzbee52a77fc2012-11-20 19:50:46 -08003509 AdjustSpillMask(cUnit);
3510 cUnit->frameSize = ComputeFrameSize(cUnit);
buzbeead8f15e2012-06-18 14:49:45 -07003511
3512 // Create RegLocations for arguments
3513 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3514 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3515 for (; it != it_end; ++it) {
3516 llvm::Value* val = it;
buzbee52a77fc2012-11-20 19:50:46 -08003517 CreateLocFromValue(cUnit, val);
buzbeead8f15e2012-06-18 14:49:45 -07003518 }
3519 // Create RegLocations for all non-argument defintions
3520 for (llvm::inst_iterator i = llvm::inst_begin(func),
3521 e = llvm::inst_end(func); i != e; ++i) {
3522 llvm::Value* val = &*i;
3523 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
buzbee52a77fc2012-11-20 19:50:46 -08003524 CreateLocFromValue(cUnit, val);
buzbeead8f15e2012-06-18 14:49:45 -07003525 }
3526 }
3527
buzbee2cfc6392012-05-07 14:51:40 -07003528 // Walk the blocks, generating code.
3529 for (llvm::Function::iterator i = cUnit->func->begin(),
3530 e = cUnit->func->end(); i != e; ++i) {
buzbee52a77fc2012-11-20 19:50:46 -08003531 MethodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
buzbee2cfc6392012-05-07 14:51:40 -07003532 }
3533
buzbee52a77fc2012-11-20 19:50:46 -08003534 HandleSuspendLaunchPads(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07003535
buzbee52a77fc2012-11-20 19:50:46 -08003536 HandleThrowLaunchPads(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07003537
buzbee52a77fc2012-11-20 19:50:46 -08003538 HandleIntrinsicLaunchPads(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07003539
buzbee692be802012-08-29 15:52:59 -07003540 cUnit->func->eraseFromParent();
3541 cUnit->func = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07003542}
3543
3544
3545} // namespace art