blob: cd4e1d3329e09c6a4b18d8d1725d315206a4adc0 [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
17#if defined(ART_USE_QUICK_COMPILER)
18
19#include "object_utils.h"
20
21#include <llvm/Support/ToolOutputFile.h>
22#include <llvm/Bitcode/ReaderWriter.h>
23#include <llvm/Analysis/Verifier.h>
24#include <llvm/Metadata.h>
25#include <llvm/ADT/DepthFirstIterator.h>
26#include <llvm/Instruction.h>
27#include <llvm/Type.h>
28#include <llvm/Instructions.h>
29#include <llvm/Support/Casting.h>
buzbeead8f15e2012-06-18 14:49:45 -070030#include <llvm/Support/InstIterator.h>
buzbee2cfc6392012-05-07 14:51:40 -070031
Elliott Hughes74847412012-06-20 18:10:21 -070032static const char* kLabelFormat = "L0x%x_%d";
buzbee2cfc6392012-05-07 14:51:40 -070033
34namespace art {
35extern const RegLocation badLoc;
buzbeeb03f4872012-06-11 15:22:11 -070036RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val);
buzbee2cfc6392012-05-07 14:51:40 -070037
38llvm::BasicBlock* getLLVMBlock(CompilationUnit* cUnit, int id)
39{
40 return cUnit->idToBlockMap.Get(id);
41}
42
43llvm::Value* getLLVMValue(CompilationUnit* cUnit, int sReg)
44{
45 return (llvm::Value*)oatGrowableListGetElement(&cUnit->llvmValues, sReg);
46}
47
48// Replace the placeholder value with the real definition
49void defineValue(CompilationUnit* cUnit, llvm::Value* val, int sReg)
50{
51 llvm::Value* placeholder = getLLVMValue(cUnit, sReg);
52 CHECK(placeholder != NULL) << "Null placeholder - shouldn't happen";
53 placeholder->replaceAllUsesWith(val);
54 val->takeName(placeholder);
55 cUnit->llvmValues.elemList[sReg] = (intptr_t)val;
56}
57
58llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
59{
60 llvm::Type* res = NULL;
61 if (loc.wide) {
62 if (loc.fp)
buzbee4f1181f2012-06-22 13:52:12 -070063 res = cUnit->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070064 else
buzbee4f1181f2012-06-22 13:52:12 -070065 res = cUnit->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070066 } else {
67 if (loc.fp) {
buzbee4f1181f2012-06-22 13:52:12 -070068 res = cUnit->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -070069 } else {
70 if (loc.ref)
71 res = cUnit->irb->GetJObjectTy();
72 else
buzbee4f1181f2012-06-22 13:52:12 -070073 res = cUnit->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -070074 }
75 }
76 return res;
77}
78
buzbeead8f15e2012-06-18 14:49:45 -070079/* Create an in-memory RegLocation from an llvm Value. */
80void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val)
81{
82 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
83 std::string s(val->getName().str());
84 const char* valName = s.c_str();
buzbeead8f15e2012-06-18 14:49:45 -070085 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
86 DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName;
87 int baseSReg = INVALID_SREG;
88 int subscript = -1;
89 sscanf(valName, "v%d_%d", &baseSReg, &subscript);
90 if ((baseSReg == INVALID_SREG) && (!strcmp(valName, "method"))) {
91 baseSReg = SSA_METHOD_BASEREG;
92 subscript = 0;
93 }
buzbeead8f15e2012-06-18 14:49:45 -070094 DCHECK_NE(baseSReg, INVALID_SREG);
95 DCHECK_NE(subscript, -1);
96 // TODO: redo during C++'ification
97 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
98 INVALID_REG, INVALID_SREG, INVALID_SREG};
99 llvm::Type* ty = val->getType();
100 loc.wide = ((ty == cUnit->irb->getInt64Ty()) ||
101 (ty == cUnit->irb->getDoubleTy()));
102 loc.defined = true;
103 if ((ty == cUnit->irb->getFloatTy()) ||
104 (ty == cUnit->irb->getDoubleTy())) {
105 loc.fp = true;
106 } else if (ty == cUnit->irb->GetJObjectTy()) {
107 loc.ref = true;
108 } else {
109 loc.core = true;
110 }
111 loc.home = false; // Will change during promotion
112 loc.sRegLow = baseSReg;
113 loc.origSReg = cUnit->locMap.size();
114 cUnit->locMap.Put(val, loc);
115}
116
buzbee2cfc6392012-05-07 14:51:40 -0700117void initIR(CompilationUnit* cUnit)
118{
119 cUnit->context = new llvm::LLVMContext();
120 cUnit->module = new llvm::Module("art", *cUnit->context);
121 llvm::StructType::create(*cUnit->context, "JavaObject");
122 llvm::StructType::create(*cUnit->context, "Method");
123 llvm::StructType::create(*cUnit->context, "Thread");
124 cUnit->intrinsic_helper =
125 new greenland::IntrinsicHelper(*cUnit->context, *cUnit->module);
126 cUnit->irb =
127 new greenland::IRBuilder(*cUnit->context, *cUnit->module,
128 *cUnit->intrinsic_helper);
129}
130
131void freeIR(CompilationUnit* cUnit)
132{
133 delete cUnit->irb;
134 delete cUnit->intrinsic_helper;
135 delete cUnit->module;
136 delete cUnit->context;
137}
138
139const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
140 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
141}
142
buzbee8fa0fda2012-06-27 15:44:52 -0700143void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
144 greenland::IntrinsicHelper::IntrinsicId id,
145 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700146{
buzbee8fa0fda2012-06-27 15:44:52 -0700147 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700148 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700149 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
150 defineValue(cUnit, res, rlDest.origSReg);
151}
152
153void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
154 greenland::IntrinsicHelper::IntrinsicId id,
155 RegLocation rlSrc)
156{
157 llvm::SmallVector<llvm::Value*, 2> args;
158 args.push_back(cUnit->irb->getInt32(fieldIndex));
159 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
160 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
161 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700162}
163
buzbee101305f2012-06-28 18:00:56 -0700164void convertFillArrayData(CompilationUnit* cUnit, int32_t offset,
165 RegLocation rlArray)
166{
167 greenland::IntrinsicHelper::IntrinsicId id;
168 id = greenland::IntrinsicHelper::FillArrayData;
169 llvm::SmallVector<llvm::Value*, 2> args;
170 args.push_back(cUnit->irb->getInt32(offset));
171 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
172 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
173 cUnit->irb->CreateCall(intr, args);
174}
175
buzbee2cfc6392012-05-07 14:51:40 -0700176llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
177 RegLocation loc)
178{
179 greenland::IntrinsicHelper::IntrinsicId id;
180 if (loc.wide) {
181 if (loc.fp) {
182 id = greenland::IntrinsicHelper::ConstDouble;
183 } else {
184 id = greenland::IntrinsicHelper::ConstLong;
185 }
186 } else {
187 if (loc.fp) {
188 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700189 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700190 id = greenland::IntrinsicHelper::ConstObj;
191 } else {
192 id = greenland::IntrinsicHelper::ConstInt;
193 }
194 }
195 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
196 return cUnit->irb->CreateCall(intr, src);
197}
buzbeeb03f4872012-06-11 15:22:11 -0700198
199void emitPopShadowFrame(CompilationUnit* cUnit)
200{
201 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
202 greenland::IntrinsicHelper::PopShadowFrame);
203 cUnit->irb->CreateCall(intr);
204}
205
buzbee2cfc6392012-05-07 14:51:40 -0700206llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
207 RegLocation loc)
208{
209 greenland::IntrinsicHelper::IntrinsicId id;
210 if (loc.wide) {
211 if (loc.fp) {
212 id = greenland::IntrinsicHelper::CopyDouble;
213 } else {
214 id = greenland::IntrinsicHelper::CopyLong;
215 }
216 } else {
217 if (loc.fp) {
218 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700219 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700220 id = greenland::IntrinsicHelper::CopyObj;
221 } else {
222 id = greenland::IntrinsicHelper::CopyInt;
223 }
224 }
225 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
226 return cUnit->irb->CreateCall(intr, src);
227}
228
buzbee32412962012-06-26 16:27:56 -0700229void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
230{
231 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
232 greenland::IntrinsicHelper::GetException);
233 llvm::Value* res = cUnit->irb->CreateCall(func);
234 defineValue(cUnit, res, rlDest.origSReg);
235}
236
237void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
238{
239 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
240 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
241 greenland::IntrinsicHelper::Throw);
242 cUnit->irb->CreateCall(func, src);
243 cUnit->irb->CreateUnreachable();
244}
245
buzbee8fa0fda2012-06-27 15:44:52 -0700246void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
247 greenland::IntrinsicHelper::IntrinsicId id,
248 RegLocation rlSrc)
249{
250 llvm::SmallVector<llvm::Value*, 2> args;
251 args.push_back(cUnit->irb->getInt32(optFlags));
252 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
253 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
254 cUnit->irb->CreateCall(func, args);
255}
256
buzbee76592632012-06-29 15:18:35 -0700257void convertArrayLength(CompilationUnit* cUnit, int optFlags,
258 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700259{
260 llvm::SmallVector<llvm::Value*, 2> args;
261 args.push_back(cUnit->irb->getInt32(optFlags));
262 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
263 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
264 greenland::IntrinsicHelper::ArrayLength);
buzbee76592632012-06-29 15:18:35 -0700265 llvm::Value* res = cUnit->irb->CreateCall(func, args);
266 defineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700267}
268
buzbee32412962012-06-26 16:27:56 -0700269void convertThrowVerificationError(CompilationUnit* cUnit, int info1, int info2)
270{
271 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
272 greenland::IntrinsicHelper::Throw);
273 llvm::SmallVector<llvm::Value*, 2> args;
274 args.push_back(cUnit->irb->getInt32(info1));
275 args.push_back(cUnit->irb->getInt32(info2));
276 cUnit->irb->CreateCall(func, args);
277 cUnit->irb->CreateUnreachable();
278}
279
buzbee2cfc6392012-05-07 14:51:40 -0700280void emitSuspendCheck(CompilationUnit* cUnit)
281{
282 greenland::IntrinsicHelper::IntrinsicId id =
283 greenland::IntrinsicHelper::CheckSuspend;
284 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
285 cUnit->irb->CreateCall(intr);
286}
287
288llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
289 llvm::Value* src1, llvm::Value* src2)
290{
291 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700292 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700293 switch(cc) {
294 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
295 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
296 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
297 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
298 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
299 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
300 default: LOG(FATAL) << "Unexpected cc value " << cc;
301 }
302 return res;
303}
304
305void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
306 ConditionCode cc, RegLocation rlSrc1,
307 RegLocation rlSrc2)
308{
309 if (bb->taken->startOffset <= mir->offset) {
310 emitSuspendCheck(cUnit);
311 }
312 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
313 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
314 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
315 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
316 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
317 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700318 // Don't redo the fallthrough branch in the BB driver
319 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700320}
321
322void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
323 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
324{
325 if (bb->taken->startOffset <= mir->offset) {
326 emitSuspendCheck(cUnit);
327 }
328 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
329 llvm::Value* src2;
330 if (rlSrc1.ref) {
331 src2 = cUnit->irb->GetJNull();
332 } else {
333 src2 = cUnit->irb->getInt32(0);
334 }
335 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
336 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
337 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
338 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700339 // Don't redo the fallthrough branch in the BB driver
340 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700341}
342
343llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
344 llvm::Value* src1, llvm::Value* src2)
345{
346 greenland::IntrinsicHelper::IntrinsicId id;
347 if (isLong) {
348 if (isDiv) {
349 id = greenland::IntrinsicHelper::DivLong;
350 } else {
351 id = greenland::IntrinsicHelper::RemLong;
352 }
353 } else if (isDiv) {
354 id = greenland::IntrinsicHelper::DivInt;
355 } else {
356 id = greenland::IntrinsicHelper::RemInt;
357 }
358 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
359 llvm::SmallVector<llvm::Value*, 2>args;
360 args.push_back(src1);
361 args.push_back(src2);
362 return cUnit->irb->CreateCall(intr, args);
363}
364
365llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
366 llvm::Value* src1, llvm::Value* src2)
367{
368 llvm::Value* res = NULL;
369 switch(op) {
370 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
371 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700372 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700373 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
374 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
375 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
376 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
377 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
378 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700379 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
380 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
381 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700382 default:
383 LOG(FATAL) << "Invalid op " << op;
384 }
385 return res;
386}
387
388void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
389 RegLocation rlSrc1, RegLocation rlSrc2)
390{
391 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
392 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
393 llvm::Value* res = NULL;
394 switch(op) {
395 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
396 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
397 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
398 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
399 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
400 default:
401 LOG(FATAL) << "Invalid op " << op;
402 }
403 defineValue(cUnit, res, rlDest.origSReg);
404}
405
buzbee4f1181f2012-06-22 13:52:12 -0700406void convertShift(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
407 RegLocation rlSrc1, RegLocation rlSrc2)
408{
409 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
buzbee101305f2012-06-28 18:00:56 -0700410 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
411 /*
412 * TODO: Figure out how best to handle constraining the shift
413 * amount to 31 for int and 63 for long. We take care of this
414 * inline for int and in the out-of-line handler for longs, so
415 * it's a bit of a waste to generate llvm bitcode for this.
416 * Yet more intrinsics?
417 */
418 UNIMPLEMENTED(WARNING) << "llvm shift mismatch";
buzbee4f1181f2012-06-22 13:52:12 -0700419 if (rlDest.wide) {
buzbee101305f2012-06-28 18:00:56 -0700420 // llvm thinks the shift could should be in 64 bits.
421 src2 = cUnit->irb->CreateZExt(src2, cUnit->irb->getInt64Ty());
buzbee4f1181f2012-06-22 13:52:12 -0700422 }
buzbee101305f2012-06-28 18:00:56 -0700423 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
buzbee4f1181f2012-06-22 13:52:12 -0700424 defineValue(cUnit, res, rlDest.origSReg);
425}
426
buzbee2cfc6392012-05-07 14:51:40 -0700427void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
428 RegLocation rlSrc1, RegLocation rlSrc2)
429{
430 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
431 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
432 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
433 defineValue(cUnit, res, rlDest.origSReg);
434}
435
buzbeeb03f4872012-06-11 15:22:11 -0700436void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
437{
438 int index = -1;
439 DCHECK(newVal != NULL);
440 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
441 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
442 if (cUnit->shadowMap[i] == vReg) {
443 index = i;
444 break;
445 }
446 }
Elliott Hughes74847412012-06-20 18:10:21 -0700447 DCHECK_NE(index, -1) << "Corrupt shadowMap";
buzbeeb03f4872012-06-11 15:22:11 -0700448 greenland::IntrinsicHelper::IntrinsicId id =
449 greenland::IntrinsicHelper::SetShadowFrameEntry;
450 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
451 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
452 llvm::Value* args[] = { newVal, tableSlot };
453 cUnit->irb->CreateCall(func, args);
454}
455
buzbee2cfc6392012-05-07 14:51:40 -0700456void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
457 RegLocation rlSrc1, int32_t imm)
458{
459 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
460 llvm::Value* src2 = cUnit->irb->getInt32(imm);
461 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
462 defineValue(cUnit, res, rlDest.origSReg);
463}
464
buzbee101305f2012-06-28 18:00:56 -0700465/*
466 * Process arguments for invoke. Note: this code is also used to
467 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
468 * The requirements are similar.
469 */
buzbee6969d502012-06-15 16:40:31 -0700470void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700471 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700472{
473 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
474 llvm::SmallVector<llvm::Value*, 10> args;
475 // Insert the invokeType
476 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
477 // Insert the method_idx
478 args.push_back(cUnit->irb->getInt32(info->index));
479 // Insert the optimization flags
480 args.push_back(cUnit->irb->getInt32(info->optFlags));
481 // Now, insert the actual arguments
482 if (cUnit->printMe) {
483 LOG(INFO) << "Building Invoke info";
484 }
485 for (int i = 0; i < info->numArgWords;) {
486 if (cUnit->printMe) {
487 oatDumpRegLoc(info->args[i]);
488 }
489 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
490 args.push_back(val);
491 i += info->args[i].wide ? 2 : 1;
492 }
493 /*
494 * Choose the invoke return type based on actual usage. Note: may
495 * be different than shorty. For example, if a function return value
496 * is not used, we'll treat this as a void invoke.
497 */
498 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700499 if (isFilledNewArray) {
500 id = greenland::IntrinsicHelper::FilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700501 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700502 id = greenland::IntrinsicHelper::HLInvokeVoid;
503 } else {
504 if (info->result.wide) {
505 if (info->result.fp) {
506 id = greenland::IntrinsicHelper::HLInvokeDouble;
507 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700508 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700509 }
510 } else if (info->result.ref) {
511 id = greenland::IntrinsicHelper::HLInvokeObj;
512 } else if (info->result.fp) {
513 id = greenland::IntrinsicHelper::HLInvokeFloat;
514 } else {
515 id = greenland::IntrinsicHelper::HLInvokeInt;
516 }
517 }
518 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
519 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
520 if (info->result.location != kLocInvalid) {
521 defineValue(cUnit, res, info->result.origSReg);
522 }
523}
524
buzbee101305f2012-06-28 18:00:56 -0700525void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
526 greenland::IntrinsicHelper::IntrinsicId id,
527 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700528{
buzbee6969d502012-06-15 16:40:31 -0700529 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700530 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700531 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
532 defineValue(cUnit, res, rlDest.origSReg);
533}
534
buzbee101305f2012-06-28 18:00:56 -0700535void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
536 RegLocation rlSrc)
537{
538 greenland::IntrinsicHelper::IntrinsicId id;
539 id = greenland::IntrinsicHelper::CheckCast;
540 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
541 llvm::SmallVector<llvm::Value*, 2> args;
542 args.push_back(cUnit->irb->getInt32(type_idx));
543 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
544 cUnit->irb->CreateCall(intr, args);
545}
546
buzbee8fa0fda2012-06-27 15:44:52 -0700547void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
548 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700549{
550 greenland::IntrinsicHelper::IntrinsicId id;
551 id = greenland::IntrinsicHelper::NewInstance;
552 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
553 llvm::Value* index = cUnit->irb->getInt32(type_idx);
554 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
555 defineValue(cUnit, res, rlDest.origSReg);
556}
557
buzbee8fa0fda2012-06-27 15:44:52 -0700558void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
559 RegLocation rlDest, RegLocation rlSrc)
560{
561 greenland::IntrinsicHelper::IntrinsicId id;
562 id = greenland::IntrinsicHelper::NewArray;
563 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
564 llvm::SmallVector<llvm::Value*, 2> args;
565 args.push_back(cUnit->irb->getInt32(type_idx));
566 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
567 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
568 defineValue(cUnit, res, rlDest.origSReg);
569}
570
571void convertAget(CompilationUnit* cUnit, int optFlags,
572 greenland::IntrinsicHelper::IntrinsicId id,
573 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
574{
575 llvm::SmallVector<llvm::Value*, 3> args;
576 args.push_back(cUnit->irb->getInt32(optFlags));
577 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
578 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
579 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
580 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
581 defineValue(cUnit, res, rlDest.origSReg);
582}
583
584void convertAput(CompilationUnit* cUnit, int optFlags,
585 greenland::IntrinsicHelper::IntrinsicId id,
586 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
587{
588 llvm::SmallVector<llvm::Value*, 4> args;
589 args.push_back(cUnit->irb->getInt32(optFlags));
590 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
591 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
592 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
593 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
594 cUnit->irb->CreateCall(intr, args);
595}
596
buzbee101305f2012-06-28 18:00:56 -0700597void convertIget(CompilationUnit* cUnit, int optFlags,
598 greenland::IntrinsicHelper::IntrinsicId id,
599 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
600{
601 llvm::SmallVector<llvm::Value*, 3> args;
602 args.push_back(cUnit->irb->getInt32(optFlags));
603 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
604 args.push_back(cUnit->irb->getInt32(fieldIndex));
605 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
606 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
607 defineValue(cUnit, res, rlDest.origSReg);
608}
609
610void convertIput(CompilationUnit* cUnit, int optFlags,
611 greenland::IntrinsicHelper::IntrinsicId id,
612 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
613{
614 llvm::SmallVector<llvm::Value*, 4> args;
615 args.push_back(cUnit->irb->getInt32(optFlags));
616 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
617 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
618 args.push_back(cUnit->irb->getInt32(fieldIndex));
619 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
620 cUnit->irb->CreateCall(intr, args);
621}
622
buzbee8fa0fda2012-06-27 15:44:52 -0700623void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
624 RegLocation rlDest, RegLocation rlSrc)
625{
626 greenland::IntrinsicHelper::IntrinsicId id;
627 id = greenland::IntrinsicHelper::InstanceOf;
628 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
629 llvm::SmallVector<llvm::Value*, 2> args;
630 args.push_back(cUnit->irb->getInt32(type_idx));
631 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
632 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
633 defineValue(cUnit, res, rlDest.origSReg);
634}
635
buzbee101305f2012-06-28 18:00:56 -0700636void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
637 RegLocation rlSrc)
638{
639 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
640 cUnit->irb->getInt64Ty());
641 defineValue(cUnit, res, rlDest.origSReg);
642}
643
buzbee76592632012-06-29 15:18:35 -0700644void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
645 RegLocation rlSrc)
646{
647 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
648 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
649 defineValue(cUnit, res, rlDest.origSReg);
650}
651
652void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
653 RegLocation rlSrc)
654{
655 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
656 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
657 defineValue(cUnit, res, rlDest.origSReg);
658}
659
660void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
661 RegLocation rlSrc)
662{
663 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
664 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
665 defineValue(cUnit, res, rlDest.origSReg);
666}
667
668void convertWideComparison(CompilationUnit* cUnit,
669 greenland::IntrinsicHelper::IntrinsicId id,
670 RegLocation rlDest, RegLocation rlSrc1,
671 RegLocation rlSrc2)
672{
673 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
674 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
675 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
676 llvm::SmallVector<llvm::Value*, 2> args;
677 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
678 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
679 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
680 defineValue(cUnit, res, rlDest.origSReg);
681}
682
buzbee101305f2012-06-28 18:00:56 -0700683void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
684 RegLocation rlSrc,
685 greenland::IntrinsicHelper::IntrinsicId id)
686{
687 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700688 llvm::Value* res =
689 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
690 defineValue(cUnit, res, rlDest.origSReg);
691}
692
693void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
694 RegLocation rlSrc)
695{
696 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
697 defineValue(cUnit, res, rlDest.origSReg);
698}
699
700void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
701 RegLocation rlSrc)
702{
703 llvm::Value* res =
704 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
705 defineValue(cUnit, res, rlDest.origSReg);
706}
707
708void convertFPToInt(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
709 RegLocation rlSrc)
710{
711 llvm::Value* res =
712 cUnit->irb->CreateFPToSI(getLLVMValue(cUnit, rlSrc.origSReg), ty);
713 defineValue(cUnit, res, rlDest.origSReg);
714}
715
716
717void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
718 RegLocation rlSrc)
719{
720 llvm::Value* res =
721 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
722 defineValue(cUnit, res, rlDest.origSReg);
723}
724
725void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
726 RegLocation rlSrc)
727{
728 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
729 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700730 defineValue(cUnit, res, rlDest.origSReg);
731}
732
buzbee2cfc6392012-05-07 14:51:40 -0700733/*
734 * Target-independent code generation. Use only high-level
735 * load/store utilities here, or target-dependent genXX() handlers
736 * when necessary.
737 */
738bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
739 llvm::BasicBlock* llvmBB, LIR* labelList)
740{
741 bool res = false; // Assume success
742 RegLocation rlSrc[3];
743 RegLocation rlDest = badLoc;
744 RegLocation rlResult = badLoc;
745 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee32412962012-06-26 16:27:56 -0700746 uint32_t vA = mir->dalvikInsn.vA;
buzbee6969d502012-06-15 16:40:31 -0700747 uint32_t vB = mir->dalvikInsn.vB;
748 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700749 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700750
buzbeeb03f4872012-06-11 15:22:11 -0700751 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700752
753 /* Prep Src and Dest locations */
754 int nextSreg = 0;
755 int nextLoc = 0;
756 int attrs = oatDataFlowAttributes[opcode];
757 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
758 if (attrs & DF_UA) {
759 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700760 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700761 nextSreg+= 2;
762 } else {
763 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
764 nextSreg++;
765 }
766 }
767 if (attrs & DF_UB) {
768 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700769 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700770 nextSreg+= 2;
771 } else {
772 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
773 nextSreg++;
774 }
775 }
776 if (attrs & DF_UC) {
777 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700778 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700779 } else {
780 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
781 }
782 }
783 if (attrs & DF_DA) {
784 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700785 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700786 } else {
buzbee15bf9802012-06-12 17:49:27 -0700787 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700788 if (rlDest.ref) {
789 objectDefinition = true;
790 }
buzbee2cfc6392012-05-07 14:51:40 -0700791 }
792 }
793
794 switch (opcode) {
795 case Instruction::NOP:
796 break;
797
798 case Instruction::MOVE:
799 case Instruction::MOVE_OBJECT:
800 case Instruction::MOVE_16:
801 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700802 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700803 case Instruction::MOVE_FROM16:
804 case Instruction::MOVE_WIDE:
805 case Instruction::MOVE_WIDE_16:
806 case Instruction::MOVE_WIDE_FROM16: {
807 /*
808 * Moves/copies are meaningless in pure SSA register form,
809 * but we need to preserve them for the conversion back into
810 * MIR (at least until we stop using the Dalvik register maps).
811 * Insert a dummy intrinsic copy call, which will be recognized
812 * by the quick path and removed by the portable path.
813 */
814 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
815 llvm::Value* res = emitCopy(cUnit, src, rlDest);
816 defineValue(cUnit, res, rlDest.origSReg);
817 }
818 break;
819
820 case Instruction::CONST:
821 case Instruction::CONST_4:
822 case Instruction::CONST_16: {
buzbee6969d502012-06-15 16:40:31 -0700823 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700824 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
825 defineValue(cUnit, res, rlDest.origSReg);
826 }
827 break;
828
829 case Instruction::CONST_WIDE_16:
830 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700831 // Sign extend to 64 bits
832 int64_t imm = static_cast<int32_t>(vB);
833 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700834 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
835 defineValue(cUnit, res, rlDest.origSReg);
836 }
837 break;
838
839 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700840 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700841 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
842 defineValue(cUnit, res, rlDest.origSReg);
843 }
844 break;
845
846 case Instruction::CONST_WIDE: {
847 llvm::Constant* immValue =
848 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
849 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
850 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700851 }
852 break;
buzbee2cfc6392012-05-07 14:51:40 -0700853 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700854 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700855 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
856 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
857 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700858 }
859 break;
860
buzbee8fa0fda2012-06-27 15:44:52 -0700861 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700862 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700863 rlSrc[0]);
864 break;
865 case Instruction::SPUT:
866 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700867 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700868 rlSrc[0]);
869 } else {
buzbee76592632012-06-29 15:18:35 -0700870 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700871 }
872 break;
873 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700874 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700875 rlSrc[0]);
876 break;
877 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700878 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700879 break;
880 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -0700881 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700882 break;
883 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -0700884 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700885 break;
886 case Instruction::SPUT_WIDE:
887 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700888 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -0700889 rlSrc[0]);
890 } else {
buzbee76592632012-06-29 15:18:35 -0700891 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -0700892 rlSrc[0]);
893 }
894 break;
895
896 case Instruction::SGET_OBJECT:
897 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
898 break;
899 case Instruction::SGET:
900 if (rlDest.fp) {
901 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
902 } else {
903 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
904 }
905 break;
906 case Instruction::SGET_BOOLEAN:
907 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
908 break;
909 case Instruction::SGET_BYTE:
910 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
911 break;
912 case Instruction::SGET_CHAR:
913 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
914 break;
915 case Instruction::SGET_SHORT:
916 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
917 break;
918 case Instruction::SGET_WIDE:
919 if (rlDest.fp) {
920 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
921 rlDest);
922 } else {
923 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -0700924 }
925 break;
buzbee2cfc6392012-05-07 14:51:40 -0700926
927 case Instruction::RETURN_WIDE:
928 case Instruction::RETURN:
929 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -0700930 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700931 emitSuspendCheck(cUnit);
932 }
buzbeeb03f4872012-06-11 15:22:11 -0700933 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700934 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
935 bb->hasReturn = true;
936 }
937 break;
938
939 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -0700940 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700941 emitSuspendCheck(cUnit);
942 }
buzbeeb03f4872012-06-11 15:22:11 -0700943 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700944 cUnit->irb->CreateRetVoid();
945 bb->hasReturn = true;
946 }
947 break;
948
949 case Instruction::IF_EQ:
950 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
951 break;
952 case Instruction::IF_NE:
953 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
954 break;
955 case Instruction::IF_LT:
956 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
957 break;
958 case Instruction::IF_GE:
959 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
960 break;
961 case Instruction::IF_GT:
962 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
963 break;
964 case Instruction::IF_LE:
965 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
966 break;
967 case Instruction::IF_EQZ:
968 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
969 break;
970 case Instruction::IF_NEZ:
971 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
972 break;
973 case Instruction::IF_LTZ:
974 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
975 break;
976 case Instruction::IF_GEZ:
977 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
978 break;
979 case Instruction::IF_GTZ:
980 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
981 break;
982 case Instruction::IF_LEZ:
983 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
984 break;
985
986 case Instruction::GOTO:
987 case Instruction::GOTO_16:
988 case Instruction::GOTO_32: {
989 if (bb->taken->startOffset <= bb->startOffset) {
990 emitSuspendCheck(cUnit);
991 }
992 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
993 }
994 break;
995
996 case Instruction::ADD_LONG:
997 case Instruction::ADD_LONG_2ADDR:
998 case Instruction::ADD_INT:
999 case Instruction::ADD_INT_2ADDR:
1000 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1001 break;
1002 case Instruction::SUB_LONG:
1003 case Instruction::SUB_LONG_2ADDR:
1004 case Instruction::SUB_INT:
1005 case Instruction::SUB_INT_2ADDR:
1006 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1007 break;
1008 case Instruction::MUL_LONG:
1009 case Instruction::MUL_LONG_2ADDR:
1010 case Instruction::MUL_INT:
1011 case Instruction::MUL_INT_2ADDR:
1012 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1013 break;
1014 case Instruction::DIV_LONG:
1015 case Instruction::DIV_LONG_2ADDR:
1016 case Instruction::DIV_INT:
1017 case Instruction::DIV_INT_2ADDR:
1018 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1019 break;
1020 case Instruction::REM_LONG:
1021 case Instruction::REM_LONG_2ADDR:
1022 case Instruction::REM_INT:
1023 case Instruction::REM_INT_2ADDR:
1024 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1025 break;
1026 case Instruction::AND_LONG:
1027 case Instruction::AND_LONG_2ADDR:
1028 case Instruction::AND_INT:
1029 case Instruction::AND_INT_2ADDR:
1030 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1031 break;
1032 case Instruction::OR_LONG:
1033 case Instruction::OR_LONG_2ADDR:
1034 case Instruction::OR_INT:
1035 case Instruction::OR_INT_2ADDR:
1036 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1037 break;
1038 case Instruction::XOR_LONG:
1039 case Instruction::XOR_LONG_2ADDR:
1040 case Instruction::XOR_INT:
1041 case Instruction::XOR_INT_2ADDR:
1042 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1043 break;
1044 case Instruction::SHL_LONG:
1045 case Instruction::SHL_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001046 convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
1047 break;
buzbee2cfc6392012-05-07 14:51:40 -07001048 case Instruction::SHL_INT:
1049 case Instruction::SHL_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001050 convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001051 break;
1052 case Instruction::SHR_LONG:
1053 case Instruction::SHR_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001054 convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
1055 break;
buzbee2cfc6392012-05-07 14:51:40 -07001056 case Instruction::SHR_INT:
1057 case Instruction::SHR_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001058 convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001059 break;
1060 case Instruction::USHR_LONG:
1061 case Instruction::USHR_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001062 convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
1063 break;
buzbee2cfc6392012-05-07 14:51:40 -07001064 case Instruction::USHR_INT:
1065 case Instruction::USHR_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001066 convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001067 break;
1068
1069 case Instruction::ADD_INT_LIT16:
1070 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001071 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001072 break;
1073 case Instruction::RSUB_INT:
1074 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001075 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001076 break;
1077 case Instruction::MUL_INT_LIT16:
1078 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001079 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001080 break;
1081 case Instruction::DIV_INT_LIT16:
1082 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001083 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001084 break;
1085 case Instruction::REM_INT_LIT16:
1086 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001087 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001088 break;
1089 case Instruction::AND_INT_LIT16:
1090 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001091 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001092 break;
1093 case Instruction::OR_INT_LIT16:
1094 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001095 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001096 break;
1097 case Instruction::XOR_INT_LIT16:
1098 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001099 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001100 break;
1101 case Instruction::SHL_INT_LIT8:
buzbee4f1181f2012-06-22 13:52:12 -07001102 convertArithOpLit(cUnit, kOpLsl, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001103 break;
1104 case Instruction::SHR_INT_LIT8:
buzbee101305f2012-06-28 18:00:56 -07001105 convertArithOpLit(cUnit, kOpAsr, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001106 break;
1107 case Instruction::USHR_INT_LIT8:
buzbee101305f2012-06-28 18:00:56 -07001108 convertArithOpLit(cUnit, kOpLsr, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001109 break;
1110
1111 case Instruction::ADD_FLOAT:
1112 case Instruction::ADD_FLOAT_2ADDR:
1113 case Instruction::ADD_DOUBLE:
1114 case Instruction::ADD_DOUBLE_2ADDR:
1115 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1116 break;
1117
1118 case Instruction::SUB_FLOAT:
1119 case Instruction::SUB_FLOAT_2ADDR:
1120 case Instruction::SUB_DOUBLE:
1121 case Instruction::SUB_DOUBLE_2ADDR:
1122 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1123 break;
1124
1125 case Instruction::MUL_FLOAT:
1126 case Instruction::MUL_FLOAT_2ADDR:
1127 case Instruction::MUL_DOUBLE:
1128 case Instruction::MUL_DOUBLE_2ADDR:
1129 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1130 break;
1131
1132 case Instruction::DIV_FLOAT:
1133 case Instruction::DIV_FLOAT_2ADDR:
1134 case Instruction::DIV_DOUBLE:
1135 case Instruction::DIV_DOUBLE_2ADDR:
1136 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1137 break;
1138
1139 case Instruction::REM_FLOAT:
1140 case Instruction::REM_FLOAT_2ADDR:
1141 case Instruction::REM_DOUBLE:
1142 case Instruction::REM_DOUBLE_2ADDR:
1143 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1144 break;
1145
buzbee6969d502012-06-15 16:40:31 -07001146 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001147 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1148 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001149 break;
1150 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001151 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1152 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001153 break;
1154
1155 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001156 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1157 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001158 break;
1159 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001160 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1161 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001162 break;
1163
1164 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001165 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1166 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001167 break;
1168 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001169 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1170 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001171 break;
1172
1173 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001174 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1175 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001176 break;
1177 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001178 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1179 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001180 break;
1181
1182 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001183 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1184 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001185 break;
1186 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001187 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1188 false /* NewFilledArray */);
1189 break;
1190 case Instruction::FILLED_NEW_ARRAY:
1191 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1192 true /* NewFilledArray */);
1193 break;
1194 case Instruction::FILLED_NEW_ARRAY_RANGE:
1195 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1196 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001197 break;
1198
1199 case Instruction::CONST_STRING:
1200 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001201 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1202 rlDest);
1203 break;
1204
1205 case Instruction::CONST_CLASS:
1206 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1207 rlDest);
1208 break;
1209
1210 case Instruction::CHECK_CAST:
1211 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001212 break;
1213
buzbee4f1181f2012-06-22 13:52:12 -07001214 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001215 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001216 break;
1217
buzbee32412962012-06-26 16:27:56 -07001218 case Instruction::MOVE_EXCEPTION:
1219 convertMoveException(cUnit, rlDest);
1220 break;
1221
1222 case Instruction::THROW:
1223 convertThrow(cUnit, rlSrc[0]);
1224 break;
1225
1226 case Instruction::THROW_VERIFICATION_ERROR:
1227 convertThrowVerificationError(cUnit, vA, vB);
1228 break;
buzbee6969d502012-06-15 16:40:31 -07001229
buzbee2cfc6392012-05-07 14:51:40 -07001230 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001231 case Instruction::MOVE_RESULT:
1232 case Instruction::MOVE_RESULT_OBJECT:
buzbee8fa0fda2012-06-27 15:44:52 -07001233 CHECK(false) << "Unexpected MOVE_RESULT";
buzbee2cfc6392012-05-07 14:51:40 -07001234 break;
1235
1236 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001237 convertMonitorEnterExit(cUnit, optFlags,
1238 greenland::IntrinsicHelper::MonitorEnter,
1239 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001240 break;
1241
1242 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001243 convertMonitorEnterExit(cUnit, optFlags,
1244 greenland::IntrinsicHelper::MonitorExit,
1245 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001246 break;
1247
1248 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001249 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001250 break;
1251
1252 case Instruction::NEW_ARRAY:
1253 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1254 break;
1255
1256 case Instruction::INSTANCE_OF:
1257 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1258 break;
1259
1260 case Instruction::AGET:
1261 if (rlDest.fp) {
1262 convertAget(cUnit, optFlags,
1263 greenland::IntrinsicHelper::HLArrayGetFloat,
1264 rlDest, rlSrc[0], rlSrc[1]);
1265 } else {
1266 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1267 rlDest, rlSrc[0], rlSrc[1]);
1268 }
1269 break;
1270 case Instruction::AGET_OBJECT:
1271 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1272 rlDest, rlSrc[0], rlSrc[1]);
1273 break;
1274 case Instruction::AGET_BOOLEAN:
1275 convertAget(cUnit, optFlags,
1276 greenland::IntrinsicHelper::HLArrayGetBoolean,
1277 rlDest, rlSrc[0], rlSrc[1]);
1278 break;
1279 case Instruction::AGET_BYTE:
1280 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1281 rlDest, rlSrc[0], rlSrc[1]);
1282 break;
1283 case Instruction::AGET_CHAR:
1284 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1285 rlDest, rlSrc[0], rlSrc[1]);
1286 break;
1287 case Instruction::AGET_SHORT:
1288 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1289 rlDest, rlSrc[0], rlSrc[1]);
1290 break;
1291 case Instruction::AGET_WIDE:
1292 if (rlDest.fp) {
1293 convertAget(cUnit, optFlags,
1294 greenland::IntrinsicHelper::HLArrayGetDouble,
1295 rlDest, rlSrc[0], rlSrc[1]);
1296 } else {
1297 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1298 rlDest, rlSrc[0], rlSrc[1]);
1299 }
1300 break;
1301
1302 case Instruction::APUT:
1303 if (rlSrc[0].fp) {
1304 convertAput(cUnit, optFlags,
1305 greenland::IntrinsicHelper::HLArrayPutFloat,
1306 rlSrc[0], rlSrc[1], rlSrc[2]);
1307 } else {
1308 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1309 rlSrc[0], rlSrc[1], rlSrc[2]);
1310 }
1311 break;
1312 case Instruction::APUT_OBJECT:
1313 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1314 rlSrc[0], rlSrc[1], rlSrc[2]);
1315 break;
1316 case Instruction::APUT_BOOLEAN:
1317 convertAput(cUnit, optFlags,
1318 greenland::IntrinsicHelper::HLArrayPutBoolean,
1319 rlSrc[0], rlSrc[1], rlSrc[2]);
1320 break;
1321 case Instruction::APUT_BYTE:
1322 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1323 rlSrc[0], rlSrc[1], rlSrc[2]);
1324 break;
1325 case Instruction::APUT_CHAR:
1326 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1327 rlSrc[0], rlSrc[1], rlSrc[2]);
1328 break;
1329 case Instruction::APUT_SHORT:
1330 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1331 rlSrc[0], rlSrc[1], rlSrc[2]);
1332 break;
1333 case Instruction::APUT_WIDE:
1334 if (rlSrc[0].fp) {
1335 convertAput(cUnit, optFlags,
1336 greenland::IntrinsicHelper::HLArrayPutDouble,
1337 rlSrc[0], rlSrc[1], rlSrc[2]);
1338 } else {
1339 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1340 rlSrc[0], rlSrc[1], rlSrc[2]);
1341 }
1342 break;
1343
buzbee101305f2012-06-28 18:00:56 -07001344 case Instruction::IGET:
1345 if (rlDest.fp) {
1346 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
1347 rlSrc[0], rlSrc[1], vC);
1348 } else {
1349 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
1350 rlSrc[0], rlSrc[1], vC);
1351 }
buzbee2cfc6392012-05-07 14:51:40 -07001352 break;
buzbee101305f2012-06-28 18:00:56 -07001353 case Instruction::IGET_OBJECT:
1354 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
1355 rlSrc[0], rlSrc[1], vC);
1356 break;
1357 case Instruction::IGET_BOOLEAN:
1358 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
1359 rlSrc[0], rlSrc[1], vC);
1360 break;
1361 case Instruction::IGET_BYTE:
1362 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
1363 rlSrc[0], rlSrc[1], vC);
1364 break;
1365 case Instruction::IGET_CHAR:
1366 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
1367 rlSrc[0], rlSrc[1], vC);
1368 break;
1369 case Instruction::IGET_SHORT:
1370 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
1371 rlSrc[0], rlSrc[1], vC);
1372 break;
1373 case Instruction::IGET_WIDE:
1374 if (rlDest.fp) {
1375 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
1376 rlSrc[0], rlSrc[1], vC);
1377 } else {
1378 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
1379 rlSrc[0], rlSrc[1], vC);
1380 }
1381 break;
1382 case Instruction::IPUT:
1383 if (rlDest.fp) {
1384 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1385 rlSrc[0], rlSrc[1], vC);
1386 } else {
1387 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1388 rlSrc[0], rlSrc[1], vC);
1389 }
1390 break;
1391 case Instruction::IPUT_OBJECT:
1392 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1393 rlSrc[0], rlSrc[1], vC);
1394 break;
1395 case Instruction::IPUT_BOOLEAN:
1396 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1397 rlSrc[0], rlSrc[1], vC);
1398 break;
1399 case Instruction::IPUT_BYTE:
1400 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1401 rlSrc[0], rlSrc[1], vC);
1402 break;
1403 case Instruction::IPUT_CHAR:
1404 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1405 rlSrc[0], rlSrc[1], vC);
1406 break;
1407 case Instruction::IPUT_SHORT:
1408 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1409 rlSrc[0], rlSrc[1], vC);
1410 break;
1411 case Instruction::IPUT_WIDE:
1412 if (rlDest.fp) {
1413 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1414 rlSrc[0], rlSrc[1], vC);
1415 } else {
1416 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1417 rlSrc[0], rlSrc[1], vC);
1418 }
buzbee2cfc6392012-05-07 14:51:40 -07001419 break;
1420
1421 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001422 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001423 break;
1424
buzbee76592632012-06-29 15:18:35 -07001425 case Instruction::LONG_TO_INT:
1426 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1427 break;
1428
buzbee101305f2012-06-28 18:00:56 -07001429 case Instruction::INT_TO_LONG:
1430 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001431 break;
1432
buzbee101305f2012-06-28 18:00:56 -07001433 case Instruction::INT_TO_CHAR:
1434 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1435 greenland::IntrinsicHelper::IntToChar);
1436 break;
1437 case Instruction::INT_TO_BYTE:
1438 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1439 greenland::IntrinsicHelper::IntToByte);
1440 break;
1441 case Instruction::INT_TO_SHORT:
1442 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1443 greenland::IntrinsicHelper::IntToShort);
1444 break;
1445
buzbee76592632012-06-29 15:18:35 -07001446 case Instruction::INT_TO_FLOAT:
1447 case Instruction::LONG_TO_FLOAT:
1448 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001449 break;
1450
buzbee76592632012-06-29 15:18:35 -07001451 case Instruction::INT_TO_DOUBLE:
1452 case Instruction::LONG_TO_DOUBLE:
1453 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001454 break;
1455
buzbee76592632012-06-29 15:18:35 -07001456 case Instruction::FLOAT_TO_DOUBLE:
1457 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001458 break;
1459
buzbee76592632012-06-29 15:18:35 -07001460 case Instruction::DOUBLE_TO_FLOAT:
1461 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001462 break;
1463
1464 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001465 case Instruction::NEG_INT:
1466 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001467 break;
1468
1469 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001470 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001471 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001472 break;
1473
buzbee76592632012-06-29 15:18:35 -07001474 case Instruction::NOT_LONG:
1475 case Instruction::NOT_INT:
1476 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001477 break;
1478
buzbee2cfc6392012-05-07 14:51:40 -07001479 case Instruction::FLOAT_TO_INT:
buzbee2cfc6392012-05-07 14:51:40 -07001480 case Instruction::DOUBLE_TO_INT:
buzbee76592632012-06-29 15:18:35 -07001481 convertFPToInt(cUnit, cUnit->irb->getInt32Ty(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001482 break;
1483
buzbee76592632012-06-29 15:18:35 -07001484 case Instruction::FLOAT_TO_LONG:
1485 case Instruction::DOUBLE_TO_LONG:
1486 convertFPToInt(cUnit, cUnit->irb->getInt64Ty(), rlDest, rlSrc[0]);
1487 break;
1488
1489 case Instruction::CMPL_FLOAT:
1490 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1491 rlDest, rlSrc[0], rlSrc[1]);
1492 break;
1493 case Instruction::CMPG_FLOAT:
1494 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1495 rlDest, rlSrc[0], rlSrc[1]);
1496 break;
1497 case Instruction::CMPL_DOUBLE:
1498 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1499 rlDest, rlSrc[0], rlSrc[1]);
1500 break;
1501 case Instruction::CMPG_DOUBLE:
1502 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1503 rlDest, rlSrc[0], rlSrc[1]);
1504 break;
1505 case Instruction::CMP_LONG:
1506 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1507 rlDest, rlSrc[0], rlSrc[1]);
1508 break;
1509
1510#if 0
1511 case Instruction::PACKED_SWITCH:
1512 genPackedSwitch(cUnit, vB, rlSrc[0]);
1513 break;
1514
1515 case Instruction::SPARSE_SWITCH:
1516 genSparseSwitch(cUnit, vB, rlSrc[0], labelList);
1517 break;
buzbee2cfc6392012-05-07 14:51:40 -07001518#endif
1519
1520 default:
buzbee32412962012-06-26 16:27:56 -07001521 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001522 res = true;
1523 }
buzbeeb03f4872012-06-11 15:22:11 -07001524 if (objectDefinition) {
1525 setShadowFrameEntry(cUnit, (llvm::Value*)
1526 cUnit->llvmValues.elemList[rlDest.origSReg]);
1527 }
buzbee2cfc6392012-05-07 14:51:40 -07001528 return res;
1529}
1530
1531/* Extended MIR instructions like PHI */
1532void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1533 llvm::BasicBlock* llvmBB)
1534{
1535
1536 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1537 case kMirOpPhi: {
1538 int* incoming = (int*)mir->dalvikInsn.vB;
1539 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
1540 llvm::Type* phiType =
1541 llvmTypeFromLocRec(cUnit, rlDest);
1542 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1543 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1544 RegLocation loc;
1545 if (rlDest.wide) {
buzbee15bf9802012-06-12 17:49:27 -07001546 loc = oatGetSrcWide(cUnit, mir, i);
buzbee2cfc6392012-05-07 14:51:40 -07001547 i++;
1548 } else {
1549 loc = oatGetSrc(cUnit, mir, i);
1550 }
1551 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
1552 getLLVMBlock(cUnit, incoming[i]));
1553 }
1554 defineValue(cUnit, phi, rlDest.origSReg);
1555 break;
1556 }
1557 case kMirOpCopy: {
1558 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1559 break;
1560 }
1561#if defined(TARGET_ARM)
1562 case kMirOpFusedCmplFloat:
1563 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1564 break;
1565 case kMirOpFusedCmpgFloat:
1566 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1567 break;
1568 case kMirOpFusedCmplDouble:
1569 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1570 break;
1571 case kMirOpFusedCmpgDouble:
1572 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1573 break;
1574 case kMirOpFusedCmpLong:
1575 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1576 break;
1577#endif
1578 default:
1579 break;
1580 }
1581}
1582
1583void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1584{
1585 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001586 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001587 arrayRef.push_back(cUnit->irb->getInt32(offset));
1588 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1589 cUnit->irb->SetDexOffset(node);
1590}
1591
1592// Attach method info as metadata to special intrinsic
1593void setMethodInfo(CompilationUnit* cUnit)
1594{
1595 // We don't want dex offset on this
1596 cUnit->irb->SetDexOffset(NULL);
1597 greenland::IntrinsicHelper::IntrinsicId id;
1598 id = greenland::IntrinsicHelper::MethodInfo;
1599 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1600 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1601 llvm::SmallVector<llvm::Value*, 2> regInfo;
1602 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1603 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1604 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1605 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1606 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1607 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1608 inst->setMetadata("RegInfo", regInfoNode);
1609 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1610 llvm::SmallVector<llvm::Value*, 50> pmap;
1611 for (int i = 0; i < promoSize; i++) {
1612 PromotionMap* p = &cUnit->promotionMap[i];
1613 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1614 ((p->fpReg & 0xff) << 16) |
1615 ((p->coreReg & 0xff) << 8) |
1616 ((p->fpLocation & 0xf) << 4) |
1617 (p->coreLocation & 0xf);
1618 pmap.push_back(cUnit->irb->getInt32(mapData));
1619 }
1620 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1621 inst->setMetadata("PromotionMap", mapNode);
1622 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1623}
1624
1625/* Handle the content in each basic block */
1626bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1627{
1628 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
1629 cUnit->irb->SetInsertPoint(llvmBB);
1630 setDexOffset(cUnit, bb->startOffset);
1631
1632 if (bb->blockType == kEntryBlock) {
1633 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001634 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1635 cUnit->numDalvikRegisters, true,
1636 kAllocMisc);
1637 for (int i = 0; i < cUnit->numSSARegs; i++) {
1638 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1639 }
1640 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1641 if (canBeRef[i]) {
1642 cUnit->numShadowFrameEntries++;
1643 }
1644 }
1645 if (cUnit->numShadowFrameEntries > 0) {
1646 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1647 cUnit->numShadowFrameEntries, true,
1648 kAllocMisc);
1649 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1650 if (canBeRef[i]) {
1651 cUnit->shadowMap[j++] = i;
1652 }
1653 }
1654 greenland::IntrinsicHelper::IntrinsicId id =
1655 greenland::IntrinsicHelper::AllocaShadowFrame;
1656 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1657 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1658 cUnit->irb->CreateCall(func, entries);
1659 }
buzbee2cfc6392012-05-07 14:51:40 -07001660 } else if (bb->blockType == kExitBlock) {
1661 /*
1662 * Because of the differences between how MIR/LIR and llvm handle exit
1663 * blocks, we won't explicitly covert them. On the llvm-to-lir
1664 * path, it will need to be regenereated.
1665 */
1666 return false;
buzbee6969d502012-06-15 16:40:31 -07001667 } else if (bb->blockType == kExceptionHandling) {
1668 /*
1669 * Because we're deferring null checking, delete the associated empty
1670 * exception block.
1671 * TODO: add new block type for exception blocks that we generate
1672 * greenland code for.
1673 */
1674 llvmBB->eraseFromParent();
1675 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001676 }
1677
1678 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1679
1680 setDexOffset(cUnit, mir->offset);
1681
1682 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
1683 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
1684
1685 /* If we're compiling for the debugger, generate an update callout */
1686 if (cUnit->genDebugger) {
1687 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1688 //genDebuggerUpdate(cUnit, mir->offset);
1689 }
1690
1691 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
1692 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1693 continue;
1694 }
1695
1696 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1697 NULL /* labelList */);
1698 if (notHandled) {
1699 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
1700 mir->offset, dalvikOpcode,
1701 Instruction::Name(dalvikOpcode),
1702 dalvikFormat);
1703 }
1704 }
1705
buzbee6969d502012-06-15 16:40:31 -07001706 if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001707 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1708 }
1709
1710 return false;
1711}
1712
1713llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1714
1715 // Get return type
1716 llvm::Type* ret_type = cUnit->irb->GetJType(cUnit->shorty[0],
1717 greenland::kAccurate);
1718
1719 // Get argument type
1720 std::vector<llvm::Type*> args_type;
1721
1722 // method object
1723 args_type.push_back(cUnit->irb->GetJMethodTy());
1724
1725 // Do we have a "this"?
1726 if ((cUnit->access_flags & kAccStatic) == 0) {
1727 args_type.push_back(cUnit->irb->GetJObjectTy());
1728 }
1729
1730 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
1731 args_type.push_back(cUnit->irb->GetJType(cUnit->shorty[i],
1732 greenland::kAccurate));
1733 }
1734
1735 return llvm::FunctionType::get(ret_type, args_type, false);
1736}
1737
1738bool createFunction(CompilationUnit* cUnit) {
1739 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1740 /* with_signature */ false));
1741 llvm::FunctionType* func_type = getFunctionType(cUnit);
1742
1743 if (func_type == NULL) {
1744 return false;
1745 }
1746
1747 cUnit->func = llvm::Function::Create(func_type,
1748 llvm::Function::ExternalLinkage,
1749 func_name, cUnit->module);
1750
1751 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1752 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1753
1754 arg_iter->setName("method");
1755 ++arg_iter;
1756
1757 int startSReg = cUnit->numRegs;
1758
1759 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1760 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1761 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1762 }
1763
1764 return true;
1765}
1766
1767bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1768{
1769 // Skip the exit block
1770 if (bb->blockType == kExitBlock) {
1771 cUnit->idToBlockMap.Put(bb->id, NULL);
1772 } else {
1773 int offset = bb->startOffset;
1774 bool entryBlock = (bb->blockType == kEntryBlock);
1775 llvm::BasicBlock* llvmBB =
1776 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
Elliott Hughes74847412012-06-20 18:10:21 -07001777 StringPrintf(kLabelFormat, offset, bb->id),
buzbee2cfc6392012-05-07 14:51:40 -07001778 cUnit->func);
1779 if (entryBlock) {
1780 cUnit->entryBB = llvmBB;
1781 cUnit->placeholderBB =
1782 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
1783 cUnit->func);
1784 }
1785 cUnit->idToBlockMap.Put(bb->id, llvmBB);
1786 }
1787 return false;
1788}
1789
1790
1791/*
1792 * Convert MIR to LLVM_IR
1793 * o For each ssa name, create LLVM named value. Type these
1794 * appropriately, and ignore high half of wide and double operands.
1795 * o For each MIR basic block, create an LLVM basic block.
1796 * o Iterate through the MIR a basic block at a time, setting arguments
1797 * to recovered ssa name.
1798 */
1799void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
1800{
1801 initIR(cUnit);
1802 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
1803
1804 // Create the function
1805 createFunction(cUnit);
1806
1807 // Create an LLVM basic block for each MIR block in dfs preorder
1808 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
1809 kPreOrderDFSTraversal, false /* isIterative */);
1810 /*
1811 * Create an llvm named value for each MIR SSA name. Note: we'll use
1812 * placeholders for all non-argument values (because we haven't seen
1813 * the definition yet).
1814 */
1815 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
1816 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1817 arg_iter++; /* Skip path method */
1818 for (int i = 0; i < cUnit->numSSARegs; i++) {
1819 llvm::Value* val;
1820 llvm::Type* ty = llvmTypeFromLocRec(cUnit, cUnit->regLocation[i]);
1821 if (i < cUnit->numRegs) {
1822 // Skip non-argument _0 names - should never be a use
1823 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)0);
1824 } else if (i >= (cUnit->numRegs + cUnit->numIns)) {
1825 // Handle SSA defs, skipping Method* and compiler temps
1826 if (SRegToVReg(cUnit, i) < 0) {
1827 val = NULL;
1828 } else {
1829 val = cUnit->irb->CreateLoad(cUnit->irb->CreateAlloca(ty, 0));
1830 val->setName(llvmSSAName(cUnit, i));
1831 }
1832 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
1833 if (cUnit->regLocation[i].wide) {
1834 // Skip high half of wide values
1835 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
1836 i++;
1837 }
1838 } else {
1839 // Recover previously-created argument values
1840 llvm::Value* argVal = arg_iter++;
1841 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
1842 }
1843 }
1844 cUnit->irb->CreateBr(cUnit->placeholderBB);
1845
1846 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
1847 kPreOrderDFSTraversal, false /* Iterative */);
1848
1849 cUnit->placeholderBB->eraseFromParent();
1850
1851 llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction);
1852
buzbeead8f15e2012-06-18 14:49:45 -07001853 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
1854 // Write bitcode to file
1855 std::string errmsg;
1856 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
1857 oatReplaceSpecialChars(fname);
1858 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07001859 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07001860
buzbeead8f15e2012-06-18 14:49:45 -07001861 llvm::OwningPtr<llvm::tool_output_file> out_file(
1862 new llvm::tool_output_file(fname.c_str(), errmsg,
1863 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07001864
buzbeead8f15e2012-06-18 14:49:45 -07001865 if (!errmsg.empty()) {
1866 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
1867 }
1868
1869 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
1870 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07001871 }
buzbee2cfc6392012-05-07 14:51:40 -07001872}
1873
1874RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
1875 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07001876 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001877 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
1878 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07001879 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07001880 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07001881 // FIXME: need to be more robust, handle FP and be in a position to
1882 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07001883 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
1884 memset(&res, 0, sizeof(res));
1885 res.location = kLocPhysReg;
1886 res.lowReg = oatAllocTemp(cUnit);
1887 res.home = true;
1888 res.sRegLow = INVALID_SREG;
1889 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07001890 llvm::Type* ty = val->getType();
1891 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
1892 (ty == cUnit->irb->getDoubleTy()));
1893 if (res.wide) {
1894 res.highReg = oatAllocTemp(cUnit);
1895 }
buzbee4f1181f2012-06-22 13:52:12 -07001896 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07001897 } else {
1898 DCHECK_EQ(valName[0], 'v');
1899 int baseSReg = INVALID_SREG;
1900 sscanf(valName.c_str(), "v%d_", &baseSReg);
1901 res = cUnit->regLocation[baseSReg];
1902 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07001903 }
1904 } else {
1905 res = it->second;
1906 }
1907 return res;
1908}
1909
1910Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
1911{
1912 Instruction::Code res = Instruction::NOP;
1913 if (isWide) {
1914 switch(op) {
1915 case kOpAdd: res = Instruction::ADD_LONG; break;
1916 case kOpSub: res = Instruction::SUB_LONG; break;
1917 case kOpMul: res = Instruction::MUL_LONG; break;
1918 case kOpDiv: res = Instruction::DIV_LONG; break;
1919 case kOpRem: res = Instruction::REM_LONG; break;
1920 case kOpAnd: res = Instruction::AND_LONG; break;
1921 case kOpOr: res = Instruction::OR_LONG; break;
1922 case kOpXor: res = Instruction::XOR_LONG; break;
1923 case kOpLsl: res = Instruction::SHL_LONG; break;
1924 case kOpLsr: res = Instruction::USHR_LONG; break;
1925 case kOpAsr: res = Instruction::SHR_LONG; break;
1926 default: LOG(FATAL) << "Unexpected OpKind " << op;
1927 }
1928 } else if (isConst){
1929 switch(op) {
1930 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
1931 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
1932 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
1933 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
1934 case kOpRem: res = Instruction::REM_INT_LIT16; break;
1935 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
1936 case kOpOr: res = Instruction::OR_INT_LIT16; break;
1937 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
1938 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
1939 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
1940 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
1941 default: LOG(FATAL) << "Unexpected OpKind " << op;
1942 }
1943 } else {
1944 switch(op) {
1945 case kOpAdd: res = Instruction::ADD_INT; break;
1946 case kOpSub: res = Instruction::SUB_INT; break;
1947 case kOpMul: res = Instruction::MUL_INT; break;
1948 case kOpDiv: res = Instruction::DIV_INT; break;
1949 case kOpRem: res = Instruction::REM_INT; break;
1950 case kOpAnd: res = Instruction::AND_INT; break;
1951 case kOpOr: res = Instruction::OR_INT; break;
1952 case kOpXor: res = Instruction::XOR_INT; break;
1953 case kOpLsl: res = Instruction::SHL_INT; break;
1954 case kOpLsr: res = Instruction::USHR_INT; break;
1955 case kOpAsr: res = Instruction::SHR_INT; break;
1956 default: LOG(FATAL) << "Unexpected OpKind " << op;
1957 }
1958 }
1959 return res;
1960}
1961
buzbee4f1181f2012-06-22 13:52:12 -07001962Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
1963{
1964 Instruction::Code res = Instruction::NOP;
1965 if (isWide) {
1966 switch(op) {
1967 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
1968 case kOpSub: res = Instruction::SUB_DOUBLE; break;
1969 case kOpMul: res = Instruction::MUL_DOUBLE; break;
1970 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
1971 case kOpRem: res = Instruction::REM_DOUBLE; break;
1972 default: LOG(FATAL) << "Unexpected OpKind " << op;
1973 }
1974 } else {
1975 switch(op) {
1976 case kOpAdd: res = Instruction::ADD_FLOAT; break;
1977 case kOpSub: res = Instruction::SUB_FLOAT; break;
1978 case kOpMul: res = Instruction::MUL_FLOAT; break;
1979 case kOpDiv: res = Instruction::DIV_FLOAT; break;
1980 case kOpRem: res = Instruction::REM_FLOAT; break;
1981 default: LOG(FATAL) << "Unexpected OpKind " << op;
1982 }
1983 }
1984 return res;
1985}
1986
1987void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
1988{
1989 RegLocation rlDest = getLoc(cUnit, inst);
1990 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
1991 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
1992 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
1993 if (rlDest.wide) {
1994 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1995 } else {
1996 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1997 }
1998}
1999
buzbee101305f2012-06-28 18:00:56 -07002000void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2001 Instruction::Code opcode)
2002{
2003 RegLocation rlDest = getLoc(cUnit, inst);
2004 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2005 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2006}
2007
buzbee76592632012-06-29 15:18:35 -07002008void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2009{
2010 RegLocation rlDest = getLoc(cUnit, inst);
2011 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2012 Instruction::Code opcode;
2013 if (rlDest.wide) {
2014 if (rlSrc.wide) {
2015 opcode = Instruction::LONG_TO_DOUBLE;
2016 } else {
2017 opcode = Instruction::INT_TO_DOUBLE;
2018 }
2019 } else {
2020 if (rlSrc.wide) {
2021 opcode = Instruction::LONG_TO_FLOAT;
2022 } else {
2023 opcode = Instruction::INT_TO_FLOAT;
2024 }
2025 }
2026 genConversion(cUnit, opcode, rlDest, rlSrc);
2027}
2028
2029void cvtFPToInt(CompilationUnit* cUnit, llvm::Instruction* inst)
2030{
2031 RegLocation rlDest = getLoc(cUnit, inst);
2032 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2033 Instruction::Code opcode;
2034 if (rlDest.wide) {
2035 if (rlSrc.wide) {
2036 opcode = Instruction::DOUBLE_TO_LONG;
2037 } else {
2038 opcode = Instruction::FLOAT_TO_LONG;
2039 }
2040 } else {
2041 if (rlSrc.wide) {
2042 opcode = Instruction::DOUBLE_TO_INT;
2043 } else {
2044 opcode = Instruction::FLOAT_TO_INT;
2045 }
2046 }
2047 genConversion(cUnit, opcode, rlDest, rlSrc);
2048}
2049
2050void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2051{
2052 RegLocation rlDest = getLoc(cUnit, inst);
2053 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2054 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2055}
2056
2057void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2058{
2059 RegLocation rlDest = getLoc(cUnit, inst);
2060 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2061 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2062 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2063 storeValue(cUnit, rlDest, rlSrc);
2064}
2065
2066void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2067{
2068 RegLocation rlDest = getLoc(cUnit, inst);
2069 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2070 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2071}
2072
2073
buzbee101305f2012-06-28 18:00:56 -07002074void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2075{
2076 // TODO: evaluate src/tgt types and add general support for more than int to long
2077 RegLocation rlDest = getLoc(cUnit, inst);
2078 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2079 DCHECK(rlDest.wide);
2080 DCHECK(!rlSrc.wide);
2081 DCHECK(!rlDest.fp);
2082 DCHECK(!rlSrc.fp);
2083 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2084 if (rlSrc.location == kLocPhysReg) {
2085 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2086 } else {
2087 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2088 }
2089 if (isSigned) {
2090 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2091 } else {
2092 loadConstant(cUnit, rlResult.highReg, 0);
2093 }
2094 storeValueWide(cUnit, rlDest, rlResult);
2095}
2096
buzbee2cfc6392012-05-07 14:51:40 -07002097void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2098{
2099 RegLocation rlDest = getLoc(cUnit, inst);
2100 llvm::Value* lhs = inst->getOperand(0);
buzbee4f1181f2012-06-22 13:52:12 -07002101 // Special-case RSUB
2102 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2103 if ((op == kOpSub) && (lhsImm != NULL)) {
2104 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
2105 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2106 lhsImm->getSExtValue());
2107 return;
2108 }
2109 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002110 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2111 llvm::Value* rhs = inst->getOperand(1);
2112 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2113 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
2114 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, src2->getSExtValue());
2115 } else {
2116 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
2117 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2118 if (rlDest.wide) {
2119 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2120 } else {
2121 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2122 }
2123 }
2124}
2125
buzbee101305f2012-06-28 18:00:56 -07002126void cvtShiftOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2127{
2128 if (inst->getType() == cUnit->irb->getInt64Ty()) {
2129 /*
2130 * llvm wants the shift amount to be 64 bits, whereas we've constained
2131 * it to be in 6 bits. It should always be held as an unnamed temp
2132 * at this point that was the result of a previous UExt. We'll backtrack
2133 * to find the pre-extension value and use that.
2134 * TODO: probably better to handle this in cvtIntExt() or just intrinsify
2135 */
2136 RegLocation rlDest = getLoc(cUnit, inst);
2137 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2138 RegLocation rlShift = getLoc(cUnit, inst->getOperand(1));
2139 DCHECK(rlShift.wide);
2140 DCHECK_EQ(rlShift.sRegLow, INVALID_SREG);
2141 // Now, free the temp registers - we won't need them.
2142 // TODO: kill the dead extend ops
2143 oatFreeTemp(cUnit, rlShift.lowReg);
2144 oatFreeTemp(cUnit, rlShift.highReg);
2145 // Get the pre-extend operand
2146 llvm::Instruction* extInst =
2147 llvm::dyn_cast<llvm::Instruction>(inst->getOperand(1));
2148 DCHECK(extInst != NULL);
2149 rlShift = getLoc(cUnit, extInst->getOperand(0));
2150 DCHECK(!rlShift.wide);
2151 Instruction::Code opcode;
2152 if (op == kOpLsl)
2153 opcode = Instruction::SHL_LONG;
2154 else if (op == kOpAsr)
2155 opcode = Instruction::SHR_LONG;
2156 else {
2157 DCHECK_EQ(op, kOpLsr);
2158 opcode = Instruction::USHR_LONG;
2159 }
2160 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2161 } else {
2162 cvtBinOp(cUnit, op, inst);
2163 }
2164}
2165
buzbee2cfc6392012-05-07 14:51:40 -07002166void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2167{
2168 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2169 DCHECK(brInst != NULL);
2170 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2171 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2172 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2173}
2174
2175void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2176{
2177 // Nop - these have already been processed
2178}
2179
2180void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2181{
2182 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2183 llvm::Value* retVal = retInst->getReturnValue();
2184 if (retVal != NULL) {
2185 RegLocation rlSrc = getLoc(cUnit, retVal);
2186 if (rlSrc.wide) {
2187 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2188 } else {
2189 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2190 }
2191 }
2192 genExitSequence(cUnit);
2193}
2194
2195ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2196{
2197 ConditionCode res = kCondAl;
2198 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002199 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002200 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2201 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2202 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002203 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002204 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002205 default: LOG(FATAL) << "Unexpected llvm condition";
2206 }
2207 return res;
2208}
2209
2210void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2211{
2212 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2213 UNIMPLEMENTED(FATAL);
2214}
2215
2216void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2217 llvm::BranchInst* brInst)
2218{
2219 // Get targets
2220 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2221 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2222 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2223 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2224 // Get comparison operands
2225 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2226 ConditionCode cond = getCond(iCmpInst->getPredicate());
2227 llvm::Value* lhs = iCmpInst->getOperand(0);
2228 // Not expecting a constant as 1st operand
2229 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2230 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2231 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2232 llvm::Value* rhs = inst->getOperand(1);
2233#if defined(TARGET_MIPS)
2234 // Compare and branch in one shot
2235 (void)taken;
2236 (void)cond;
2237 (void)rhs;
2238 UNIMPLEMENTED(FATAL);
2239#else
2240 //Compare, then branch
2241 // TODO: handle fused CMP_LONG/IF_xxZ case
2242 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2243 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
2244 } else {
2245 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2246 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2247 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2248 }
2249 opCondBranch(cUnit, cond, taken);
2250#endif
2251 // Fallthrough
2252 opUnconditionalBranch(cUnit, fallThrough);
2253}
2254
2255void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2256 llvm::Function* callee)
2257{
2258 UNIMPLEMENTED(FATAL);
2259}
2260
buzbee2cfc6392012-05-07 14:51:40 -07002261void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2262{
buzbee4f1181f2012-06-22 13:52:12 -07002263 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002264 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2265 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002266 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2267 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002268 if (rlSrc.wide) {
2269 storeValueWide(cUnit, rlDest, rlSrc);
2270 } else {
2271 storeValue(cUnit, rlDest, rlSrc);
2272 }
2273}
2274
2275// Note: Immediate arg is a ConstantInt regardless of result type
2276void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2277{
buzbee4f1181f2012-06-22 13:52:12 -07002278 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002279 llvm::ConstantInt* src =
2280 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2281 uint64_t immval = src->getZExtValue();
2282 RegLocation rlDest = getLoc(cUnit, callInst);
2283 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2284 if (rlDest.wide) {
2285 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2286 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2287 storeValueWide(cUnit, rlDest, rlResult);
2288 } else {
2289 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2290 storeValue(cUnit, rlDest, rlResult);
2291 }
2292}
2293
buzbee101305f2012-06-28 18:00:56 -07002294void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2295 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002296{
buzbee4f1181f2012-06-22 13:52:12 -07002297 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002298 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002299 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002300 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002301 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002302 if (isString) {
2303 genConstString(cUnit, index, rlDest);
2304 } else {
2305 genConstClass(cUnit, index, rlDest);
2306 }
2307}
2308
2309void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2310{
2311 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2312 llvm::ConstantInt* offsetVal =
2313 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2314 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2315 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002316}
2317
buzbee4f1181f2012-06-22 13:52:12 -07002318void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2319{
buzbee32412962012-06-26 16:27:56 -07002320 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002321 llvm::ConstantInt* typeIdxVal =
2322 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2323 uint32_t typeIdx = typeIdxVal->getZExtValue();
2324 RegLocation rlDest = getLoc(cUnit, callInst);
2325 genNewInstance(cUnit, typeIdx, rlDest);
2326}
2327
buzbee8fa0fda2012-06-27 15:44:52 -07002328void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2329{
2330 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2331 llvm::ConstantInt* typeIdxVal =
2332 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2333 uint32_t typeIdx = typeIdxVal->getZExtValue();
2334 llvm::Value* len = callInst->getArgOperand(1);
2335 RegLocation rlLen = getLoc(cUnit, len);
2336 RegLocation rlDest = getLoc(cUnit, callInst);
2337 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2338}
2339
2340void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2341{
2342 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2343 llvm::ConstantInt* typeIdxVal =
2344 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2345 uint32_t typeIdx = typeIdxVal->getZExtValue();
2346 llvm::Value* src = callInst->getArgOperand(1);
2347 RegLocation rlSrc = getLoc(cUnit, src);
2348 RegLocation rlDest = getLoc(cUnit, callInst);
2349 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2350}
2351
buzbee32412962012-06-26 16:27:56 -07002352void cvtThrowVerificationError(CompilationUnit* cUnit, llvm::CallInst* callInst)
2353{
2354 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2355 llvm::ConstantInt* info1 =
2356 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2357 llvm::ConstantInt* info2 =
2358 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2359 genThrowVerificationError(cUnit, info1->getZExtValue(), info2->getZExtValue());
2360}
2361
2362void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2363{
2364 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2365 llvm::Value* src = callInst->getArgOperand(0);
2366 RegLocation rlSrc = getLoc(cUnit, src);
2367 genThrow(cUnit, rlSrc);
2368}
2369
buzbee8fa0fda2012-06-27 15:44:52 -07002370void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2371 llvm::CallInst* callInst)
2372{
2373 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2374 llvm::ConstantInt* optFlags =
2375 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2376 llvm::Value* src = callInst->getArgOperand(1);
2377 RegLocation rlSrc = getLoc(cUnit, src);
2378 if (isEnter) {
2379 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2380 } else {
2381 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2382 }
2383}
2384
buzbee76592632012-06-29 15:18:35 -07002385void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002386{
2387 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2388 llvm::ConstantInt* optFlags =
2389 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2390 llvm::Value* src = callInst->getArgOperand(1);
2391 RegLocation rlSrc = getLoc(cUnit, src);
2392 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2393 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2394 RegLocation rlDest = getLoc(cUnit, callInst);
2395 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2396 int lenOffset = Array::LengthOffset().Int32Value();
2397 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2398 storeValue(cUnit, rlDest, rlResult);
2399}
2400
buzbee32412962012-06-26 16:27:56 -07002401void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2402{
2403 DCHECK_EQ(callInst->getNumArgOperands(), 0U);
2404 int exOffset = Thread::ExceptionOffset().Int32Value();
2405 RegLocation rlDest = getLoc(cUnit, callInst);
2406 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2407#if defined(TARGET_X86)
2408 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
2409 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
2410#else
2411 int resetReg = oatAllocTemp(cUnit);
2412 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
2413 loadConstant(cUnit, resetReg, 0);
2414 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
2415 oatFreeTemp(cUnit, resetReg);
2416#endif
2417 storeValue(cUnit, rlDest, rlResult);
2418}
2419
buzbee4f1181f2012-06-22 13:52:12 -07002420void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2421 bool isObject)
2422{
buzbee32412962012-06-26 16:27:56 -07002423 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002424 llvm::ConstantInt* typeIdxVal =
2425 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2426 uint32_t typeIdx = typeIdxVal->getZExtValue();
2427 RegLocation rlDest = getLoc(cUnit, callInst);
2428 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2429}
2430
buzbee8fa0fda2012-06-27 15:44:52 -07002431void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2432 bool isObject)
2433{
2434 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2435 llvm::ConstantInt* typeIdxVal =
2436 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2437 uint32_t typeIdx = typeIdxVal->getZExtValue();
2438 llvm::Value* src = callInst->getArgOperand(1);
2439 RegLocation rlSrc = getLoc(cUnit, src);
2440 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2441}
2442
2443void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2444 int scale)
2445{
2446 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2447 llvm::ConstantInt* optFlags =
2448 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2449 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2450 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2451 RegLocation rlDest = getLoc(cUnit, callInst);
2452 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2453 rlDest, scale);
2454}
2455
2456void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2457 int scale)
2458{
2459 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2460 llvm::ConstantInt* optFlags =
2461 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2462 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2463 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2464 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
2465 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2466 rlSrc, scale);
2467}
2468
buzbee101305f2012-06-28 18:00:56 -07002469void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2470 bool isWide, bool isObj)
2471{
2472 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2473 llvm::ConstantInt* optFlags =
2474 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2475 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2476 llvm::ConstantInt* fieldIdx =
2477 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2478 RegLocation rlDest = getLoc(cUnit, callInst);
2479 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2480 size, rlDest, rlObj, isWide, isObj);
2481}
2482
2483void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2484 bool isWide, bool isObj)
2485{
2486 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2487 llvm::ConstantInt* optFlags =
2488 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2489 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2490 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2491 llvm::ConstantInt* fieldIdx =
2492 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2493 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2494 size, rlSrc, rlObj, isWide, isObj);
2495}
2496
2497void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2498{
2499 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2500 llvm::ConstantInt* typeIdx =
2501 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2502 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2503 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2504}
2505
buzbee76592632012-06-29 15:18:35 -07002506void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2507 Instruction::Code opcode)
2508{
2509 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2510 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2511 RegLocation rlDest = getLoc(cUnit, callInst);
2512 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2513}
2514
2515void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2516{
2517 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2518 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2519 RegLocation rlDest = getLoc(cUnit, callInst);
2520 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2521}
2522
buzbee6969d502012-06-15 16:40:31 -07002523void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002524 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002525{
2526 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2527 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002528 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002529 info->result.location = kLocInvalid;
2530 } else {
2531 info->result = getLoc(cUnit, callInst);
2532 }
2533 llvm::ConstantInt* invokeTypeVal =
2534 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2535 llvm::ConstantInt* methodIndexVal =
2536 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2537 llvm::ConstantInt* optFlagsVal =
2538 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2539 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2540 info->index = methodIndexVal->getZExtValue();
2541 info->optFlags = optFlagsVal->getZExtValue();
2542 info->offset = cUnit->currentDalvikOffset;
2543
2544 // FIXME - rework such that we no longer need isRange
2545 info->isRange = false;
2546
2547 // Count the argument words, and then build argument array.
2548 info->numArgWords = 0;
2549 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2550 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2551 info->numArgWords += tLoc.wide ? 2 : 1;
2552 }
2553 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2554 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2555 // Now, fill in the location records, synthesizing high loc of wide vals
2556 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002557 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002558 if (cUnit->printMe) {
2559 oatDumpRegLoc(info->args[next]);
2560 }
2561 if (info->args[next].wide) {
2562 next++;
2563 // TODO: Might make sense to mark this as an invalid loc
2564 info->args[next].origSReg = info->args[next-1].origSReg+1;
2565 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2566 }
2567 next++;
2568 }
buzbee76592632012-06-29 15:18:35 -07002569 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002570 genFilledNewArray(cUnit, info);
2571 } else {
2572 genInvoke(cUnit, info);
2573 }
buzbee6969d502012-06-15 16:40:31 -07002574}
2575
buzbeead8f15e2012-06-18 14:49:45 -07002576/* Look up the RegLocation associated with a Value. Must already be defined */
2577RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2578{
2579 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2580 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2581 return it->second;
2582}
2583
buzbee2cfc6392012-05-07 14:51:40 -07002584bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2585{
2586 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2587 // Define the starting label
2588 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2589 // Extract the starting offset from the block's name
2590 if (!isEntry) {
2591 const char* blockName = bb->getName().str().c_str();
2592 int dummy;
Elliott Hughes74847412012-06-20 18:10:21 -07002593 sscanf(blockName, kLabelFormat, &blockLabel->operands[0], &dummy);
buzbee2cfc6392012-05-07 14:51:40 -07002594 }
2595 // Set the label kind
2596 blockLabel->opcode = kPseudoNormalBlockLabel;
2597 // Insert the label
2598 oatAppendLIR(cUnit, blockLabel);
2599
2600 // Free temp registers and reset redundant store tracking */
2601 oatResetRegPool(cUnit);
2602 oatResetDefTracking(cUnit);
2603
2604 //TODO: restore oat incoming liveness optimization
2605 oatClobberAllRegs(cUnit);
2606
buzbee6969d502012-06-15 16:40:31 -07002607 LIR* headLIR = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07002608
2609 if (isEntry) {
2610 cUnit->currentDalvikOffset = 0;
buzbeead8f15e2012-06-18 14:49:45 -07002611 RegLocation* argLocs = (RegLocation*)
2612 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2613 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2614 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2615 for (unsigned i = 0; it != it_end; ++it) {
2616 llvm::Value* val = it;
2617 argLocs[i++] = valToLoc(cUnit, val);
2618 llvm::Type* ty = val->getType();
2619 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2620 argLocs[i++].sRegLow = INVALID_SREG;
2621 }
2622 }
2623 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
buzbee2cfc6392012-05-07 14:51:40 -07002624 }
2625
2626 // Visit all of the instructions in the block
2627 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2628 llvm::Instruction* inst = it;
2629 llvm::BasicBlock::iterator nextIt = ++it;
2630 // Extract the Dalvik offset from the instruction
2631 uint32_t opcode = inst->getOpcode();
2632 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2633 if (dexOffsetNode != NULL) {
2634 llvm::ConstantInt* dexOffsetValue =
2635 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2636 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2637 }
2638
buzbee6969d502012-06-15 16:40:31 -07002639 oatResetRegPool(cUnit);
2640 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2641 oatClobberAllRegs(cUnit);
2642 }
2643
2644 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2645 oatResetDefTracking(cUnit);
2646 }
2647
2648#ifndef NDEBUG
2649 /* Reset temp tracking sanity check */
2650 cUnit->liveSReg = INVALID_SREG;
2651#endif
2652
2653 LIR* boundaryLIR;
2654 const char* instStr = "boundary";
2655 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
2656 (intptr_t) instStr);
2657 cUnit->boundaryMap.Overwrite(cUnit->currentDalvikOffset, boundaryLIR);
2658
2659 /* Remember the first LIR for thisl block*/
2660 if (headLIR == NULL) {
2661 headLIR = boundaryLIR;
2662 headLIR->defMask = ENCODE_ALL;
2663 }
2664
buzbee2cfc6392012-05-07 14:51:40 -07002665 switch(opcode) {
2666
2667 case llvm::Instruction::ICmp: {
2668 llvm::Instruction* nextInst = nextIt;
2669 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2670 if (brInst != NULL /* and... */) {
2671 cvtICmpBr(cUnit, inst, brInst);
2672 ++it;
2673 } else {
2674 cvtICmp(cUnit, inst);
2675 }
2676 }
2677 break;
2678
2679 case llvm::Instruction::Call: {
2680 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2681 llvm::Function* callee = callInst->getCalledFunction();
2682 greenland::IntrinsicHelper::IntrinsicId id =
2683 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2684 switch (id) {
buzbeeb03f4872012-06-11 15:22:11 -07002685 case greenland::IntrinsicHelper::AllocaShadowFrame:
2686 case greenland::IntrinsicHelper::SetShadowFrameEntry:
buzbee6969d502012-06-15 16:40:31 -07002687 case greenland::IntrinsicHelper::PopShadowFrame:
buzbeeb03f4872012-06-11 15:22:11 -07002688 // Ignore shadow frame stuff for quick compiler
2689 break;
buzbee2cfc6392012-05-07 14:51:40 -07002690 case greenland::IntrinsicHelper::CopyInt:
2691 case greenland::IntrinsicHelper::CopyObj:
2692 case greenland::IntrinsicHelper::CopyFloat:
2693 case greenland::IntrinsicHelper::CopyLong:
2694 case greenland::IntrinsicHelper::CopyDouble:
2695 cvtCopy(cUnit, callInst);
2696 break;
2697 case greenland::IntrinsicHelper::ConstInt:
2698 case greenland::IntrinsicHelper::ConstObj:
2699 case greenland::IntrinsicHelper::ConstLong:
2700 case greenland::IntrinsicHelper::ConstFloat:
2701 case greenland::IntrinsicHelper::ConstDouble:
2702 cvtConst(cUnit, callInst);
2703 break;
buzbee4f1181f2012-06-22 13:52:12 -07002704 case greenland::IntrinsicHelper::DivInt:
2705 case greenland::IntrinsicHelper::DivLong:
2706 cvtBinOp(cUnit, kOpDiv, inst);
2707 break;
2708 case greenland::IntrinsicHelper::RemInt:
2709 case greenland::IntrinsicHelper::RemLong:
2710 cvtBinOp(cUnit, kOpRem, inst);
2711 break;
buzbee2cfc6392012-05-07 14:51:40 -07002712 case greenland::IntrinsicHelper::MethodInfo:
buzbeead8f15e2012-06-18 14:49:45 -07002713 // Already dealt with - just ignore it here.
buzbee2cfc6392012-05-07 14:51:40 -07002714 break;
2715 case greenland::IntrinsicHelper::CheckSuspend:
2716 genSuspendTest(cUnit, 0 /* optFlags already applied */);
2717 break;
buzbee4f1181f2012-06-22 13:52:12 -07002718 case greenland::IntrinsicHelper::HLInvokeObj:
buzbee8fa0fda2012-06-27 15:44:52 -07002719 case greenland::IntrinsicHelper::HLInvokeFloat:
2720 case greenland::IntrinsicHelper::HLInvokeDouble:
2721 case greenland::IntrinsicHelper::HLInvokeLong:
2722 case greenland::IntrinsicHelper::HLInvokeInt:
buzbee101305f2012-06-28 18:00:56 -07002723 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
buzbee4f1181f2012-06-22 13:52:12 -07002724 break;
buzbee6969d502012-06-15 16:40:31 -07002725 case greenland::IntrinsicHelper::HLInvokeVoid:
buzbee101305f2012-06-28 18:00:56 -07002726 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
2727 break;
2728 case greenland::IntrinsicHelper::FilledNewArray:
2729 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
2730 break;
2731 case greenland::IntrinsicHelper::FillArrayData:
2732 cvtFillArrayData(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07002733 break;
2734 case greenland::IntrinsicHelper::ConstString:
buzbee101305f2012-06-28 18:00:56 -07002735 cvtConstObject(cUnit, callInst, true /* isString */);
2736 break;
2737 case greenland::IntrinsicHelper::ConstClass:
2738 cvtConstObject(cUnit, callInst, false /* isString */);
2739 break;
2740 case greenland::IntrinsicHelper::CheckCast:
2741 cvtCheckCast(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07002742 break;
buzbee4f1181f2012-06-22 13:52:12 -07002743 case greenland::IntrinsicHelper::NewInstance:
2744 cvtNewInstance(cUnit, callInst);
2745 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002746 case greenland::IntrinsicHelper::HLSgetObject:
buzbee4f1181f2012-06-22 13:52:12 -07002747 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
2748 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002749 case greenland::IntrinsicHelper::HLSget:
2750 case greenland::IntrinsicHelper::HLSgetFloat:
2751 case greenland::IntrinsicHelper::HLSgetBoolean:
2752 case greenland::IntrinsicHelper::HLSgetByte:
2753 case greenland::IntrinsicHelper::HLSgetChar:
2754 case greenland::IntrinsicHelper::HLSgetShort:
2755 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
2756 break;
2757 case greenland::IntrinsicHelper::HLSgetWide:
2758 case greenland::IntrinsicHelper::HLSgetDouble:
2759 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
2760 break;
buzbee76592632012-06-29 15:18:35 -07002761 case greenland::IntrinsicHelper::HLSput:
2762 case greenland::IntrinsicHelper::HLSputFloat:
2763 case greenland::IntrinsicHelper::HLSputBoolean:
2764 case greenland::IntrinsicHelper::HLSputByte:
2765 case greenland::IntrinsicHelper::HLSputChar:
2766 case greenland::IntrinsicHelper::HLSputShort:
2767 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
2768 break;
2769 case greenland::IntrinsicHelper::HLSputWide:
2770 case greenland::IntrinsicHelper::HLSputDouble:
2771 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
2772 break;
buzbee32412962012-06-26 16:27:56 -07002773 case greenland::IntrinsicHelper::GetException:
2774 cvtMoveException(cUnit, callInst);
2775 break;
2776 case greenland::IntrinsicHelper::Throw:
2777 cvtThrow(cUnit, callInst);
2778 break;
2779 case greenland::IntrinsicHelper::ThrowVerificationError:
buzbee8fa0fda2012-06-27 15:44:52 -07002780 cvtThrowVerificationError(cUnit, callInst);
buzbee32412962012-06-26 16:27:56 -07002781 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002782 case greenland::IntrinsicHelper::MonitorEnter:
2783 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
2784 break;
2785 case greenland::IntrinsicHelper::MonitorExit:
2786 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
2787 break;
2788 case greenland::IntrinsicHelper::ArrayLength:
buzbee76592632012-06-29 15:18:35 -07002789 cvtArrayLength(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07002790 break;
2791 case greenland::IntrinsicHelper::NewArray:
2792 cvtNewArray(cUnit, callInst);
2793 break;
2794 case greenland::IntrinsicHelper::InstanceOf:
2795 cvtInstanceOf(cUnit, callInst);
2796 break;
2797
2798 case greenland::IntrinsicHelper::HLArrayGet:
2799 case greenland::IntrinsicHelper::HLArrayGetObject:
2800 case greenland::IntrinsicHelper::HLArrayGetFloat:
2801 cvtAget(cUnit, callInst, kWord, 2);
2802 break;
2803 case greenland::IntrinsicHelper::HLArrayGetWide:
2804 case greenland::IntrinsicHelper::HLArrayGetDouble:
2805 cvtAget(cUnit, callInst, kLong, 3);
2806 break;
2807 case greenland::IntrinsicHelper::HLArrayGetBoolean:
2808 cvtAget(cUnit, callInst, kUnsignedByte, 0);
2809 break;
2810 case greenland::IntrinsicHelper::HLArrayGetByte:
2811 cvtAget(cUnit, callInst, kSignedByte, 0);
2812 break;
2813 case greenland::IntrinsicHelper::HLArrayGetChar:
2814 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
2815 break;
2816 case greenland::IntrinsicHelper::HLArrayGetShort:
2817 cvtAget(cUnit, callInst, kSignedHalf, 1);
2818 break;
2819
2820 case greenland::IntrinsicHelper::HLArrayPut:
2821 case greenland::IntrinsicHelper::HLArrayPutObject:
2822 case greenland::IntrinsicHelper::HLArrayPutFloat:
2823 cvtAput(cUnit, callInst, kWord, 2);
2824 break;
2825 case greenland::IntrinsicHelper::HLArrayPutWide:
2826 case greenland::IntrinsicHelper::HLArrayPutDouble:
2827 cvtAput(cUnit, callInst, kLong, 3);
2828 break;
2829 case greenland::IntrinsicHelper::HLArrayPutBoolean:
2830 cvtAput(cUnit, callInst, kUnsignedByte, 0);
2831 break;
2832 case greenland::IntrinsicHelper::HLArrayPutByte:
2833 cvtAput(cUnit, callInst, kSignedByte, 0);
2834 break;
2835 case greenland::IntrinsicHelper::HLArrayPutChar:
2836 cvtAput(cUnit, callInst, kUnsignedHalf, 1);
2837 break;
2838 case greenland::IntrinsicHelper::HLArrayPutShort:
2839 cvtAput(cUnit, callInst, kSignedHalf, 1);
2840 break;
2841
buzbee101305f2012-06-28 18:00:56 -07002842 case greenland::IntrinsicHelper::HLIGet:
2843 case greenland::IntrinsicHelper::HLIGetFloat:
2844 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
2845 break;
2846 case greenland::IntrinsicHelper::HLIGetObject:
2847 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
2848 break;
2849 case greenland::IntrinsicHelper::HLIGetWide:
2850 case greenland::IntrinsicHelper::HLIGetDouble:
2851 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
2852 break;
2853 case greenland::IntrinsicHelper::HLIGetBoolean:
2854 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
2855 false /* obj */);
2856 break;
2857 case greenland::IntrinsicHelper::HLIGetByte:
2858 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
2859 false /* obj */);
2860 break;
2861 case greenland::IntrinsicHelper::HLIGetChar:
2862 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
2863 false /* obj */);
2864 break;
2865 case greenland::IntrinsicHelper::HLIGetShort:
2866 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
2867 false /* obj */);
2868 break;
2869
2870 case greenland::IntrinsicHelper::HLIPut:
2871 case greenland::IntrinsicHelper::HLIPutFloat:
2872 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
2873 break;
2874 case greenland::IntrinsicHelper::HLIPutObject:
2875 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
2876 break;
2877 case greenland::IntrinsicHelper::HLIPutWide:
2878 case greenland::IntrinsicHelper::HLIPutDouble:
2879 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
2880 break;
2881 case greenland::IntrinsicHelper::HLIPutBoolean:
2882 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
2883 false /* obj */);
2884 break;
2885 case greenland::IntrinsicHelper::HLIPutByte:
2886 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
2887 false /* obj */);
2888 break;
2889 case greenland::IntrinsicHelper::HLIPutChar:
2890 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
2891 false /* obj */);
2892 break;
2893 case greenland::IntrinsicHelper::HLIPutShort:
2894 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
2895 false /* obj */);
2896 break;
2897
2898 case greenland::IntrinsicHelper::IntToChar:
2899 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
2900 break;
2901 case greenland::IntrinsicHelper::IntToShort:
2902 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
2903 break;
2904 case greenland::IntrinsicHelper::IntToByte:
2905 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
2906 break;
2907
buzbee76592632012-06-29 15:18:35 -07002908 case greenland::IntrinsicHelper::CmplFloat:
2909 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
2910 break;
2911 case greenland::IntrinsicHelper::CmpgFloat:
2912 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
2913 break;
2914 case greenland::IntrinsicHelper::CmplDouble:
2915 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
2916 break;
2917 case greenland::IntrinsicHelper::CmpgDouble:
2918 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
2919 break;
2920
2921 case greenland::IntrinsicHelper::CmpLong:
2922 cvtLongCompare(cUnit, callInst);
2923 break;
2924
buzbee2cfc6392012-05-07 14:51:40 -07002925 case greenland::IntrinsicHelper::UnknownId:
2926 cvtCall(cUnit, callInst, callee);
2927 break;
2928 default:
2929 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
2930 << cUnit->intrinsic_helper->GetName(id);
2931 }
2932 }
2933 break;
2934
2935 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
2936 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
2937 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
2938 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
2939 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
2940 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
2941 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
2942 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
2943 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
buzbee101305f2012-06-28 18:00:56 -07002944 case llvm::Instruction::Shl: cvtShiftOp(cUnit, kOpLsl, inst); break;
2945 case llvm::Instruction::LShr: cvtShiftOp(cUnit, kOpLsr, inst); break;
2946 case llvm::Instruction::AShr: cvtShiftOp(cUnit, kOpAsr, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07002947 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
2948 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
buzbee4f1181f2012-06-22 13:52:12 -07002949 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
2950 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
2951 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
2952 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
2953 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
buzbee76592632012-06-29 15:18:35 -07002954 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
2955 case llvm::Instruction::FPToSI: cvtFPToInt(cUnit, inst); break;
2956 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
2957 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
2958 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07002959
buzbee101305f2012-06-28 18:00:56 -07002960 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
2961 break;
2962 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
2963 break;
2964
buzbee32412962012-06-26 16:27:56 -07002965 case llvm::Instruction::Unreachable:
2966 break; // FIXME: can we really ignore these?
2967
buzbee2cfc6392012-05-07 14:51:40 -07002968 case llvm::Instruction::Invoke:
buzbee2cfc6392012-05-07 14:51:40 -07002969 case llvm::Instruction::FPToUI:
buzbee2cfc6392012-05-07 14:51:40 -07002970 case llvm::Instruction::UIToFP:
buzbee2cfc6392012-05-07 14:51:40 -07002971 case llvm::Instruction::PtrToInt:
2972 case llvm::Instruction::IntToPtr:
2973 case llvm::Instruction::Switch:
2974 case llvm::Instruction::FCmp:
buzbee2cfc6392012-05-07 14:51:40 -07002975 case llvm::Instruction::URem:
2976 case llvm::Instruction::UDiv:
2977 case llvm::Instruction::Resume:
buzbee2cfc6392012-05-07 14:51:40 -07002978 case llvm::Instruction::Alloca:
2979 case llvm::Instruction::GetElementPtr:
2980 case llvm::Instruction::Fence:
2981 case llvm::Instruction::AtomicCmpXchg:
2982 case llvm::Instruction::AtomicRMW:
2983 case llvm::Instruction::BitCast:
2984 case llvm::Instruction::VAArg:
2985 case llvm::Instruction::Select:
2986 case llvm::Instruction::UserOp1:
2987 case llvm::Instruction::UserOp2:
2988 case llvm::Instruction::ExtractElement:
2989 case llvm::Instruction::InsertElement:
2990 case llvm::Instruction::ShuffleVector:
2991 case llvm::Instruction::ExtractValue:
2992 case llvm::Instruction::InsertValue:
2993 case llvm::Instruction::LandingPad:
2994 case llvm::Instruction::IndirectBr:
2995 case llvm::Instruction::Load:
2996 case llvm::Instruction::Store:
2997 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
2998
2999 default:
3000 LOG(FATAL) << "Unknown llvm opcode: " << opcode; break;
3001 }
3002 }
buzbee6969d502012-06-15 16:40:31 -07003003
3004 if (headLIR != NULL) {
3005 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
3006 }
buzbee2cfc6392012-05-07 14:51:40 -07003007 return false;
3008}
3009
3010/*
3011 * Convert LLVM_IR to MIR:
3012 * o Iterate through the LLVM_IR and construct a graph using
3013 * standard MIR building blocks.
3014 * o Perform a basic-block optimization pass to remove unnecessary
3015 * store/load sequences.
3016 * o Convert the LLVM Value operands into RegLocations where applicable.
3017 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3018 * o Perform register promotion
3019 * o Iterate through the graph a basic block at a time, generating
3020 * LIR.
3021 * o Assemble LIR as usual.
3022 * o Profit.
3023 */
3024void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3025{
buzbeead8f15e2012-06-18 14:49:45 -07003026 llvm::Function* func = cUnit->func;
3027 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003028 // Allocate a list for LIR basic block labels
3029 cUnit->blockLabelList =
3030 (void*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3031 LIR* labelList = (LIR*)cUnit->blockLabelList;
3032 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003033 for (llvm::Function::iterator i = func->begin(),
3034 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003035 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3036 &labelList[nextLabel++]);
3037 }
buzbeead8f15e2012-06-18 14:49:45 -07003038
3039 /*
3040 * Keep honest - clear regLocations, Value => RegLocation,
3041 * promotion map and VmapTables.
3042 */
3043 cUnit->locMap.clear(); // Start fresh
3044 cUnit->regLocation = NULL;
3045 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3046 i++) {
3047 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3048 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3049 }
3050 cUnit->coreSpillMask = 0;
3051 cUnit->numCoreSpills = 0;
3052 cUnit->fpSpillMask = 0;
3053 cUnit->numFPSpills = 0;
3054 cUnit->coreVmapTable.clear();
3055 cUnit->fpVmapTable.clear();
3056 oatAdjustSpillMask(cUnit);
3057 cUnit->frameSize = oatComputeFrameSize(cUnit);
3058
3059 /*
3060 * At this point, we've lost all knowledge of register promotion.
3061 * Rebuild that info from the MethodInfo intrinsic (if it
3062 * exists - not required for correctness).
3063 */
3064 // TODO: find and recover MethodInfo.
3065
3066 // Create RegLocations for arguments
3067 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3068 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3069 for (; it != it_end; ++it) {
3070 llvm::Value* val = it;
3071 createLocFromValue(cUnit, val);
3072 }
3073 // Create RegLocations for all non-argument defintions
3074 for (llvm::inst_iterator i = llvm::inst_begin(func),
3075 e = llvm::inst_end(func); i != e; ++i) {
3076 llvm::Value* val = &*i;
3077 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3078 createLocFromValue(cUnit, val);
3079 }
3080 }
3081
buzbee2cfc6392012-05-07 14:51:40 -07003082 // Walk the blocks, generating code.
3083 for (llvm::Function::iterator i = cUnit->func->begin(),
3084 e = cUnit->func->end(); i != e; ++i) {
3085 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3086 }
3087
3088 handleSuspendLaunchpads(cUnit);
3089
3090 handleThrowLaunchpads(cUnit);
3091
3092 handleIntrinsicLaunchpads(cUnit);
3093
3094 freeIR(cUnit);
3095}
3096
3097
3098} // namespace art
3099
3100#endif // ART_USE_QUICK_COMPILER