blob: a4521bbd8075a0166333c728c2c7cc10998fc132 [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);
buzbee2cfc6392012-05-07 14:51:40 -0700336 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
337 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700338 // Don't redo the fallthrough branch in the BB driver
339 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700340}
341
342llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
343 llvm::Value* src1, llvm::Value* src2)
344{
345 greenland::IntrinsicHelper::IntrinsicId id;
346 if (isLong) {
347 if (isDiv) {
348 id = greenland::IntrinsicHelper::DivLong;
349 } else {
350 id = greenland::IntrinsicHelper::RemLong;
351 }
352 } else if (isDiv) {
353 id = greenland::IntrinsicHelper::DivInt;
354 } else {
355 id = greenland::IntrinsicHelper::RemInt;
356 }
357 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
358 llvm::SmallVector<llvm::Value*, 2>args;
359 args.push_back(src1);
360 args.push_back(src2);
361 return cUnit->irb->CreateCall(intr, args);
362}
363
364llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
365 llvm::Value* src1, llvm::Value* src2)
366{
367 llvm::Value* res = NULL;
368 switch(op) {
369 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
370 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700371 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700372 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
373 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
374 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
375 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
376 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
377 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700378 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
379 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
380 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700381 default:
382 LOG(FATAL) << "Invalid op " << op;
383 }
384 return res;
385}
386
387void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
388 RegLocation rlSrc1, RegLocation rlSrc2)
389{
390 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
391 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
392 llvm::Value* res = NULL;
393 switch(op) {
394 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
395 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
396 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
397 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
398 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
399 default:
400 LOG(FATAL) << "Invalid op " << op;
401 }
402 defineValue(cUnit, res, rlDest.origSReg);
403}
404
buzbee4f1181f2012-06-22 13:52:12 -0700405void convertShift(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
406 RegLocation rlSrc1, RegLocation rlSrc2)
407{
408 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
buzbee101305f2012-06-28 18:00:56 -0700409 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
410 /*
411 * TODO: Figure out how best to handle constraining the shift
412 * amount to 31 for int and 63 for long. We take care of this
413 * inline for int and in the out-of-line handler for longs, so
414 * it's a bit of a waste to generate llvm bitcode for this.
415 * Yet more intrinsics?
416 */
417 UNIMPLEMENTED(WARNING) << "llvm shift mismatch";
buzbee4f1181f2012-06-22 13:52:12 -0700418 if (rlDest.wide) {
buzbee101305f2012-06-28 18:00:56 -0700419 // llvm thinks the shift could should be in 64 bits.
420 src2 = cUnit->irb->CreateZExt(src2, cUnit->irb->getInt64Ty());
buzbee4f1181f2012-06-22 13:52:12 -0700421 }
buzbee101305f2012-06-28 18:00:56 -0700422 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
buzbee4f1181f2012-06-22 13:52:12 -0700423 defineValue(cUnit, res, rlDest.origSReg);
424}
425
buzbee2cfc6392012-05-07 14:51:40 -0700426void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
427 RegLocation rlSrc1, RegLocation rlSrc2)
428{
429 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
430 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700431 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700432 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
buzbee6969d502012-06-15 16:40:31 -0700482 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700483 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
484 args.push_back(val);
485 i += info->args[i].wide ? 2 : 1;
486 }
487 /*
488 * Choose the invoke return type based on actual usage. Note: may
489 * be different than shorty. For example, if a function return value
490 * is not used, we'll treat this as a void invoke.
491 */
492 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700493 if (isFilledNewArray) {
494 id = greenland::IntrinsicHelper::FilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700495 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700496 id = greenland::IntrinsicHelper::HLInvokeVoid;
497 } else {
498 if (info->result.wide) {
499 if (info->result.fp) {
500 id = greenland::IntrinsicHelper::HLInvokeDouble;
501 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700502 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700503 }
504 } else if (info->result.ref) {
505 id = greenland::IntrinsicHelper::HLInvokeObj;
506 } else if (info->result.fp) {
507 id = greenland::IntrinsicHelper::HLInvokeFloat;
508 } else {
509 id = greenland::IntrinsicHelper::HLInvokeInt;
510 }
511 }
512 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
513 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
514 if (info->result.location != kLocInvalid) {
515 defineValue(cUnit, res, info->result.origSReg);
516 }
517}
518
buzbee101305f2012-06-28 18:00:56 -0700519void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
520 greenland::IntrinsicHelper::IntrinsicId id,
521 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700522{
buzbee6969d502012-06-15 16:40:31 -0700523 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700524 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700525 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
526 defineValue(cUnit, res, rlDest.origSReg);
527}
528
buzbee101305f2012-06-28 18:00:56 -0700529void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
530 RegLocation rlSrc)
531{
532 greenland::IntrinsicHelper::IntrinsicId id;
533 id = greenland::IntrinsicHelper::CheckCast;
534 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
535 llvm::SmallVector<llvm::Value*, 2> args;
536 args.push_back(cUnit->irb->getInt32(type_idx));
537 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
538 cUnit->irb->CreateCall(intr, args);
539}
540
buzbee8fa0fda2012-06-27 15:44:52 -0700541void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
542 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700543{
544 greenland::IntrinsicHelper::IntrinsicId id;
545 id = greenland::IntrinsicHelper::NewInstance;
546 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
547 llvm::Value* index = cUnit->irb->getInt32(type_idx);
548 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
549 defineValue(cUnit, res, rlDest.origSReg);
550}
551
buzbee8fa0fda2012-06-27 15:44:52 -0700552void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
553 RegLocation rlDest, RegLocation rlSrc)
554{
555 greenland::IntrinsicHelper::IntrinsicId id;
556 id = greenland::IntrinsicHelper::NewArray;
557 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
558 llvm::SmallVector<llvm::Value*, 2> args;
559 args.push_back(cUnit->irb->getInt32(type_idx));
560 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
561 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
562 defineValue(cUnit, res, rlDest.origSReg);
563}
564
565void convertAget(CompilationUnit* cUnit, int optFlags,
566 greenland::IntrinsicHelper::IntrinsicId id,
567 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
568{
569 llvm::SmallVector<llvm::Value*, 3> args;
570 args.push_back(cUnit->irb->getInt32(optFlags));
571 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
572 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
573 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
574 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
575 defineValue(cUnit, res, rlDest.origSReg);
576}
577
578void convertAput(CompilationUnit* cUnit, int optFlags,
579 greenland::IntrinsicHelper::IntrinsicId id,
580 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
581{
582 llvm::SmallVector<llvm::Value*, 4> args;
583 args.push_back(cUnit->irb->getInt32(optFlags));
584 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
585 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
586 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
587 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
588 cUnit->irb->CreateCall(intr, args);
589}
590
buzbee101305f2012-06-28 18:00:56 -0700591void convertIget(CompilationUnit* cUnit, int optFlags,
592 greenland::IntrinsicHelper::IntrinsicId id,
593 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
594{
595 llvm::SmallVector<llvm::Value*, 3> args;
596 args.push_back(cUnit->irb->getInt32(optFlags));
597 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
598 args.push_back(cUnit->irb->getInt32(fieldIndex));
599 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
600 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
601 defineValue(cUnit, res, rlDest.origSReg);
602}
603
604void convertIput(CompilationUnit* cUnit, int optFlags,
605 greenland::IntrinsicHelper::IntrinsicId id,
606 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
607{
608 llvm::SmallVector<llvm::Value*, 4> args;
609 args.push_back(cUnit->irb->getInt32(optFlags));
610 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
611 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
612 args.push_back(cUnit->irb->getInt32(fieldIndex));
613 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
614 cUnit->irb->CreateCall(intr, args);
615}
616
buzbee8fa0fda2012-06-27 15:44:52 -0700617void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
618 RegLocation rlDest, RegLocation rlSrc)
619{
620 greenland::IntrinsicHelper::IntrinsicId id;
621 id = greenland::IntrinsicHelper::InstanceOf;
622 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
623 llvm::SmallVector<llvm::Value*, 2> args;
624 args.push_back(cUnit->irb->getInt32(type_idx));
625 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
626 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
627 defineValue(cUnit, res, rlDest.origSReg);
628}
629
buzbee101305f2012-06-28 18:00:56 -0700630void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
631 RegLocation rlSrc)
632{
633 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
634 cUnit->irb->getInt64Ty());
635 defineValue(cUnit, res, rlDest.origSReg);
636}
637
buzbee76592632012-06-29 15:18:35 -0700638void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
639 RegLocation rlSrc)
640{
641 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
642 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
643 defineValue(cUnit, res, rlDest.origSReg);
644}
645
646void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
647 RegLocation rlSrc)
648{
649 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
650 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
651 defineValue(cUnit, res, rlDest.origSReg);
652}
653
654void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
655 RegLocation rlSrc)
656{
657 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
658 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
659 defineValue(cUnit, res, rlDest.origSReg);
660}
661
662void convertWideComparison(CompilationUnit* cUnit,
663 greenland::IntrinsicHelper::IntrinsicId id,
664 RegLocation rlDest, RegLocation rlSrc1,
665 RegLocation rlSrc2)
666{
667 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
668 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
669 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
670 llvm::SmallVector<llvm::Value*, 2> args;
671 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
672 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
673 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
674 defineValue(cUnit, res, rlDest.origSReg);
675}
676
buzbee101305f2012-06-28 18:00:56 -0700677void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
678 RegLocation rlSrc,
679 greenland::IntrinsicHelper::IntrinsicId id)
680{
681 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700682 llvm::Value* res =
683 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
684 defineValue(cUnit, res, rlDest.origSReg);
685}
686
687void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
688 RegLocation rlSrc)
689{
690 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
691 defineValue(cUnit, res, rlDest.origSReg);
692}
693
694void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
695 RegLocation rlSrc)
696{
697 llvm::Value* res =
698 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
699 defineValue(cUnit, res, rlDest.origSReg);
700}
701
702void convertFPToInt(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
703 RegLocation rlSrc)
704{
705 llvm::Value* res =
706 cUnit->irb->CreateFPToSI(getLLVMValue(cUnit, rlSrc.origSReg), ty);
707 defineValue(cUnit, res, rlDest.origSReg);
708}
709
710
711void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
712 RegLocation rlSrc)
713{
714 llvm::Value* res =
715 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
716 defineValue(cUnit, res, rlDest.origSReg);
717}
718
719void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
720 RegLocation rlSrc)
721{
722 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
723 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700724 defineValue(cUnit, res, rlDest.origSReg);
725}
726
buzbee2cfc6392012-05-07 14:51:40 -0700727/*
728 * Target-independent code generation. Use only high-level
729 * load/store utilities here, or target-dependent genXX() handlers
730 * when necessary.
731 */
732bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
733 llvm::BasicBlock* llvmBB, LIR* labelList)
734{
735 bool res = false; // Assume success
736 RegLocation rlSrc[3];
737 RegLocation rlDest = badLoc;
738 RegLocation rlResult = badLoc;
739 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee32412962012-06-26 16:27:56 -0700740 uint32_t vA = mir->dalvikInsn.vA;
buzbee6969d502012-06-15 16:40:31 -0700741 uint32_t vB = mir->dalvikInsn.vB;
742 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700743 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700744
buzbeeb03f4872012-06-11 15:22:11 -0700745 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700746
747 /* Prep Src and Dest locations */
748 int nextSreg = 0;
749 int nextLoc = 0;
750 int attrs = oatDataFlowAttributes[opcode];
751 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
752 if (attrs & DF_UA) {
753 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700754 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700755 nextSreg+= 2;
756 } else {
757 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
758 nextSreg++;
759 }
760 }
761 if (attrs & DF_UB) {
762 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700763 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700764 nextSreg+= 2;
765 } else {
766 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
767 nextSreg++;
768 }
769 }
770 if (attrs & DF_UC) {
771 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700772 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700773 } else {
774 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
775 }
776 }
777 if (attrs & DF_DA) {
778 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700779 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700780 } else {
buzbee15bf9802012-06-12 17:49:27 -0700781 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700782 if (rlDest.ref) {
783 objectDefinition = true;
784 }
buzbee2cfc6392012-05-07 14:51:40 -0700785 }
786 }
787
788 switch (opcode) {
789 case Instruction::NOP:
790 break;
791
792 case Instruction::MOVE:
793 case Instruction::MOVE_OBJECT:
794 case Instruction::MOVE_16:
795 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700796 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700797 case Instruction::MOVE_FROM16:
798 case Instruction::MOVE_WIDE:
799 case Instruction::MOVE_WIDE_16:
800 case Instruction::MOVE_WIDE_FROM16: {
801 /*
802 * Moves/copies are meaningless in pure SSA register form,
803 * but we need to preserve them for the conversion back into
804 * MIR (at least until we stop using the Dalvik register maps).
805 * Insert a dummy intrinsic copy call, which will be recognized
806 * by the quick path and removed by the portable path.
807 */
808 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
809 llvm::Value* res = emitCopy(cUnit, src, rlDest);
810 defineValue(cUnit, res, rlDest.origSReg);
811 }
812 break;
813
814 case Instruction::CONST:
815 case Instruction::CONST_4:
816 case Instruction::CONST_16: {
buzbee6969d502012-06-15 16:40:31 -0700817 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700818 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
819 defineValue(cUnit, res, rlDest.origSReg);
820 }
821 break;
822
823 case Instruction::CONST_WIDE_16:
824 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700825 // Sign extend to 64 bits
826 int64_t imm = static_cast<int32_t>(vB);
827 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700828 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
829 defineValue(cUnit, res, rlDest.origSReg);
830 }
831 break;
832
833 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700834 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700835 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
836 defineValue(cUnit, res, rlDest.origSReg);
837 }
838 break;
839
840 case Instruction::CONST_WIDE: {
841 llvm::Constant* immValue =
842 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
843 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
844 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700845 }
846 break;
buzbee2cfc6392012-05-07 14:51:40 -0700847 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700848 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700849 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
850 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
851 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700852 }
853 break;
854
buzbee8fa0fda2012-06-27 15:44:52 -0700855 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700856 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700857 rlSrc[0]);
858 break;
859 case Instruction::SPUT:
860 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700861 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700862 rlSrc[0]);
863 } else {
buzbee76592632012-06-29 15:18:35 -0700864 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700865 }
866 break;
867 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700868 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700869 rlSrc[0]);
870 break;
871 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700872 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700873 break;
874 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -0700875 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700876 break;
877 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -0700878 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700879 break;
880 case Instruction::SPUT_WIDE:
881 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700882 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -0700883 rlSrc[0]);
884 } else {
buzbee76592632012-06-29 15:18:35 -0700885 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -0700886 rlSrc[0]);
887 }
888 break;
889
890 case Instruction::SGET_OBJECT:
891 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
892 break;
893 case Instruction::SGET:
894 if (rlDest.fp) {
895 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
896 } else {
897 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
898 }
899 break;
900 case Instruction::SGET_BOOLEAN:
901 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
902 break;
903 case Instruction::SGET_BYTE:
904 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
905 break;
906 case Instruction::SGET_CHAR:
907 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
908 break;
909 case Instruction::SGET_SHORT:
910 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
911 break;
912 case Instruction::SGET_WIDE:
913 if (rlDest.fp) {
914 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
915 rlDest);
916 } else {
917 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -0700918 }
919 break;
buzbee2cfc6392012-05-07 14:51:40 -0700920
921 case Instruction::RETURN_WIDE:
922 case Instruction::RETURN:
923 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -0700924 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700925 emitSuspendCheck(cUnit);
926 }
buzbeeb03f4872012-06-11 15:22:11 -0700927 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700928 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
929 bb->hasReturn = true;
930 }
931 break;
932
933 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -0700934 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700935 emitSuspendCheck(cUnit);
936 }
buzbeeb03f4872012-06-11 15:22:11 -0700937 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700938 cUnit->irb->CreateRetVoid();
939 bb->hasReturn = true;
940 }
941 break;
942
943 case Instruction::IF_EQ:
944 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
945 break;
946 case Instruction::IF_NE:
947 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
948 break;
949 case Instruction::IF_LT:
950 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
951 break;
952 case Instruction::IF_GE:
953 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
954 break;
955 case Instruction::IF_GT:
956 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
957 break;
958 case Instruction::IF_LE:
959 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
960 break;
961 case Instruction::IF_EQZ:
962 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
963 break;
964 case Instruction::IF_NEZ:
965 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
966 break;
967 case Instruction::IF_LTZ:
968 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
969 break;
970 case Instruction::IF_GEZ:
971 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
972 break;
973 case Instruction::IF_GTZ:
974 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
975 break;
976 case Instruction::IF_LEZ:
977 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
978 break;
979
980 case Instruction::GOTO:
981 case Instruction::GOTO_16:
982 case Instruction::GOTO_32: {
983 if (bb->taken->startOffset <= bb->startOffset) {
984 emitSuspendCheck(cUnit);
985 }
986 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
987 }
988 break;
989
990 case Instruction::ADD_LONG:
991 case Instruction::ADD_LONG_2ADDR:
992 case Instruction::ADD_INT:
993 case Instruction::ADD_INT_2ADDR:
994 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
995 break;
996 case Instruction::SUB_LONG:
997 case Instruction::SUB_LONG_2ADDR:
998 case Instruction::SUB_INT:
999 case Instruction::SUB_INT_2ADDR:
1000 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1001 break;
1002 case Instruction::MUL_LONG:
1003 case Instruction::MUL_LONG_2ADDR:
1004 case Instruction::MUL_INT:
1005 case Instruction::MUL_INT_2ADDR:
1006 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1007 break;
1008 case Instruction::DIV_LONG:
1009 case Instruction::DIV_LONG_2ADDR:
1010 case Instruction::DIV_INT:
1011 case Instruction::DIV_INT_2ADDR:
1012 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1013 break;
1014 case Instruction::REM_LONG:
1015 case Instruction::REM_LONG_2ADDR:
1016 case Instruction::REM_INT:
1017 case Instruction::REM_INT_2ADDR:
1018 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1019 break;
1020 case Instruction::AND_LONG:
1021 case Instruction::AND_LONG_2ADDR:
1022 case Instruction::AND_INT:
1023 case Instruction::AND_INT_2ADDR:
1024 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1025 break;
1026 case Instruction::OR_LONG:
1027 case Instruction::OR_LONG_2ADDR:
1028 case Instruction::OR_INT:
1029 case Instruction::OR_INT_2ADDR:
1030 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1031 break;
1032 case Instruction::XOR_LONG:
1033 case Instruction::XOR_LONG_2ADDR:
1034 case Instruction::XOR_INT:
1035 case Instruction::XOR_INT_2ADDR:
1036 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1037 break;
1038 case Instruction::SHL_LONG:
1039 case Instruction::SHL_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001040 convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
1041 break;
buzbee2cfc6392012-05-07 14:51:40 -07001042 case Instruction::SHL_INT:
1043 case Instruction::SHL_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001044 convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001045 break;
1046 case Instruction::SHR_LONG:
1047 case Instruction::SHR_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001048 convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
1049 break;
buzbee2cfc6392012-05-07 14:51:40 -07001050 case Instruction::SHR_INT:
1051 case Instruction::SHR_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001052 convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001053 break;
1054 case Instruction::USHR_LONG:
1055 case Instruction::USHR_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001056 convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
1057 break;
buzbee2cfc6392012-05-07 14:51:40 -07001058 case Instruction::USHR_INT:
1059 case Instruction::USHR_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001060 convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001061 break;
1062
1063 case Instruction::ADD_INT_LIT16:
1064 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001065 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001066 break;
1067 case Instruction::RSUB_INT:
1068 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001069 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001070 break;
1071 case Instruction::MUL_INT_LIT16:
1072 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001073 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001074 break;
1075 case Instruction::DIV_INT_LIT16:
1076 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001077 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001078 break;
1079 case Instruction::REM_INT_LIT16:
1080 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001081 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001082 break;
1083 case Instruction::AND_INT_LIT16:
1084 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001085 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001086 break;
1087 case Instruction::OR_INT_LIT16:
1088 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001089 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001090 break;
1091 case Instruction::XOR_INT_LIT16:
1092 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001093 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001094 break;
1095 case Instruction::SHL_INT_LIT8:
buzbee4f1181f2012-06-22 13:52:12 -07001096 convertArithOpLit(cUnit, kOpLsl, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001097 break;
1098 case Instruction::SHR_INT_LIT8:
buzbee101305f2012-06-28 18:00:56 -07001099 convertArithOpLit(cUnit, kOpAsr, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001100 break;
1101 case Instruction::USHR_INT_LIT8:
buzbee101305f2012-06-28 18:00:56 -07001102 convertArithOpLit(cUnit, kOpLsr, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001103 break;
1104
1105 case Instruction::ADD_FLOAT:
1106 case Instruction::ADD_FLOAT_2ADDR:
1107 case Instruction::ADD_DOUBLE:
1108 case Instruction::ADD_DOUBLE_2ADDR:
1109 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1110 break;
1111
1112 case Instruction::SUB_FLOAT:
1113 case Instruction::SUB_FLOAT_2ADDR:
1114 case Instruction::SUB_DOUBLE:
1115 case Instruction::SUB_DOUBLE_2ADDR:
1116 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1117 break;
1118
1119 case Instruction::MUL_FLOAT:
1120 case Instruction::MUL_FLOAT_2ADDR:
1121 case Instruction::MUL_DOUBLE:
1122 case Instruction::MUL_DOUBLE_2ADDR:
1123 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1124 break;
1125
1126 case Instruction::DIV_FLOAT:
1127 case Instruction::DIV_FLOAT_2ADDR:
1128 case Instruction::DIV_DOUBLE:
1129 case Instruction::DIV_DOUBLE_2ADDR:
1130 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1131 break;
1132
1133 case Instruction::REM_FLOAT:
1134 case Instruction::REM_FLOAT_2ADDR:
1135 case Instruction::REM_DOUBLE:
1136 case Instruction::REM_DOUBLE_2ADDR:
1137 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1138 break;
1139
buzbee6969d502012-06-15 16:40:31 -07001140 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001141 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1142 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001143 break;
1144 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001145 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1146 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001147 break;
1148
1149 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001150 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1151 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001152 break;
1153 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001154 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1155 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001156 break;
1157
1158 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001159 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1160 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001161 break;
1162 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001163 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1164 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001165 break;
1166
1167 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001168 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1169 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001170 break;
1171 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001172 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1173 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001174 break;
1175
1176 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001177 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1178 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001179 break;
1180 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001181 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1182 false /* NewFilledArray */);
1183 break;
1184 case Instruction::FILLED_NEW_ARRAY:
1185 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1186 true /* NewFilledArray */);
1187 break;
1188 case Instruction::FILLED_NEW_ARRAY_RANGE:
1189 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1190 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001191 break;
1192
1193 case Instruction::CONST_STRING:
1194 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001195 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1196 rlDest);
1197 break;
1198
1199 case Instruction::CONST_CLASS:
1200 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1201 rlDest);
1202 break;
1203
1204 case Instruction::CHECK_CAST:
1205 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001206 break;
1207
buzbee4f1181f2012-06-22 13:52:12 -07001208 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001209 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001210 break;
1211
buzbee32412962012-06-26 16:27:56 -07001212 case Instruction::MOVE_EXCEPTION:
1213 convertMoveException(cUnit, rlDest);
1214 break;
1215
1216 case Instruction::THROW:
1217 convertThrow(cUnit, rlSrc[0]);
1218 break;
1219
1220 case Instruction::THROW_VERIFICATION_ERROR:
1221 convertThrowVerificationError(cUnit, vA, vB);
1222 break;
buzbee6969d502012-06-15 16:40:31 -07001223
buzbee2cfc6392012-05-07 14:51:40 -07001224 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001225 case Instruction::MOVE_RESULT:
1226 case Instruction::MOVE_RESULT_OBJECT:
buzbee8fa0fda2012-06-27 15:44:52 -07001227 CHECK(false) << "Unexpected MOVE_RESULT";
buzbee2cfc6392012-05-07 14:51:40 -07001228 break;
1229
1230 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001231 convertMonitorEnterExit(cUnit, optFlags,
1232 greenland::IntrinsicHelper::MonitorEnter,
1233 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001234 break;
1235
1236 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001237 convertMonitorEnterExit(cUnit, optFlags,
1238 greenland::IntrinsicHelper::MonitorExit,
1239 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001240 break;
1241
1242 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001243 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001244 break;
1245
1246 case Instruction::NEW_ARRAY:
1247 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1248 break;
1249
1250 case Instruction::INSTANCE_OF:
1251 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1252 break;
1253
1254 case Instruction::AGET:
1255 if (rlDest.fp) {
1256 convertAget(cUnit, optFlags,
1257 greenland::IntrinsicHelper::HLArrayGetFloat,
1258 rlDest, rlSrc[0], rlSrc[1]);
1259 } else {
1260 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1261 rlDest, rlSrc[0], rlSrc[1]);
1262 }
1263 break;
1264 case Instruction::AGET_OBJECT:
1265 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1266 rlDest, rlSrc[0], rlSrc[1]);
1267 break;
1268 case Instruction::AGET_BOOLEAN:
1269 convertAget(cUnit, optFlags,
1270 greenland::IntrinsicHelper::HLArrayGetBoolean,
1271 rlDest, rlSrc[0], rlSrc[1]);
1272 break;
1273 case Instruction::AGET_BYTE:
1274 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1275 rlDest, rlSrc[0], rlSrc[1]);
1276 break;
1277 case Instruction::AGET_CHAR:
1278 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1279 rlDest, rlSrc[0], rlSrc[1]);
1280 break;
1281 case Instruction::AGET_SHORT:
1282 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1283 rlDest, rlSrc[0], rlSrc[1]);
1284 break;
1285 case Instruction::AGET_WIDE:
1286 if (rlDest.fp) {
1287 convertAget(cUnit, optFlags,
1288 greenland::IntrinsicHelper::HLArrayGetDouble,
1289 rlDest, rlSrc[0], rlSrc[1]);
1290 } else {
1291 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1292 rlDest, rlSrc[0], rlSrc[1]);
1293 }
1294 break;
1295
1296 case Instruction::APUT:
1297 if (rlSrc[0].fp) {
1298 convertAput(cUnit, optFlags,
1299 greenland::IntrinsicHelper::HLArrayPutFloat,
1300 rlSrc[0], rlSrc[1], rlSrc[2]);
1301 } else {
1302 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1303 rlSrc[0], rlSrc[1], rlSrc[2]);
1304 }
1305 break;
1306 case Instruction::APUT_OBJECT:
1307 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1308 rlSrc[0], rlSrc[1], rlSrc[2]);
1309 break;
1310 case Instruction::APUT_BOOLEAN:
1311 convertAput(cUnit, optFlags,
1312 greenland::IntrinsicHelper::HLArrayPutBoolean,
1313 rlSrc[0], rlSrc[1], rlSrc[2]);
1314 break;
1315 case Instruction::APUT_BYTE:
1316 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1317 rlSrc[0], rlSrc[1], rlSrc[2]);
1318 break;
1319 case Instruction::APUT_CHAR:
1320 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1321 rlSrc[0], rlSrc[1], rlSrc[2]);
1322 break;
1323 case Instruction::APUT_SHORT:
1324 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1325 rlSrc[0], rlSrc[1], rlSrc[2]);
1326 break;
1327 case Instruction::APUT_WIDE:
1328 if (rlSrc[0].fp) {
1329 convertAput(cUnit, optFlags,
1330 greenland::IntrinsicHelper::HLArrayPutDouble,
1331 rlSrc[0], rlSrc[1], rlSrc[2]);
1332 } else {
1333 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1334 rlSrc[0], rlSrc[1], rlSrc[2]);
1335 }
1336 break;
1337
buzbee101305f2012-06-28 18:00:56 -07001338 case Instruction::IGET:
1339 if (rlDest.fp) {
1340 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001341 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001342 } else {
1343 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001344 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001345 }
buzbee2cfc6392012-05-07 14:51:40 -07001346 break;
buzbee101305f2012-06-28 18:00:56 -07001347 case Instruction::IGET_OBJECT:
1348 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001349 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001350 break;
1351 case Instruction::IGET_BOOLEAN:
1352 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001353 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001354 break;
1355 case Instruction::IGET_BYTE:
1356 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001357 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001358 break;
1359 case Instruction::IGET_CHAR:
1360 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001361 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001362 break;
1363 case Instruction::IGET_SHORT:
1364 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001365 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001366 break;
1367 case Instruction::IGET_WIDE:
1368 if (rlDest.fp) {
1369 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001370 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001371 } else {
1372 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001373 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001374 }
1375 break;
1376 case Instruction::IPUT:
1377 if (rlDest.fp) {
1378 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1379 rlSrc[0], rlSrc[1], vC);
1380 } else {
1381 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1382 rlSrc[0], rlSrc[1], vC);
1383 }
1384 break;
1385 case Instruction::IPUT_OBJECT:
1386 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1387 rlSrc[0], rlSrc[1], vC);
1388 break;
1389 case Instruction::IPUT_BOOLEAN:
1390 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1391 rlSrc[0], rlSrc[1], vC);
1392 break;
1393 case Instruction::IPUT_BYTE:
1394 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1395 rlSrc[0], rlSrc[1], vC);
1396 break;
1397 case Instruction::IPUT_CHAR:
1398 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1399 rlSrc[0], rlSrc[1], vC);
1400 break;
1401 case Instruction::IPUT_SHORT:
1402 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1403 rlSrc[0], rlSrc[1], vC);
1404 break;
1405 case Instruction::IPUT_WIDE:
1406 if (rlDest.fp) {
1407 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1408 rlSrc[0], rlSrc[1], vC);
1409 } else {
1410 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1411 rlSrc[0], rlSrc[1], vC);
1412 }
buzbee2cfc6392012-05-07 14:51:40 -07001413 break;
1414
1415 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001416 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001417 break;
1418
buzbee76592632012-06-29 15:18:35 -07001419 case Instruction::LONG_TO_INT:
1420 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1421 break;
1422
buzbee101305f2012-06-28 18:00:56 -07001423 case Instruction::INT_TO_LONG:
1424 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001425 break;
1426
buzbee101305f2012-06-28 18:00:56 -07001427 case Instruction::INT_TO_CHAR:
1428 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1429 greenland::IntrinsicHelper::IntToChar);
1430 break;
1431 case Instruction::INT_TO_BYTE:
1432 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1433 greenland::IntrinsicHelper::IntToByte);
1434 break;
1435 case Instruction::INT_TO_SHORT:
1436 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1437 greenland::IntrinsicHelper::IntToShort);
1438 break;
1439
buzbee76592632012-06-29 15:18:35 -07001440 case Instruction::INT_TO_FLOAT:
1441 case Instruction::LONG_TO_FLOAT:
1442 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001443 break;
1444
buzbee76592632012-06-29 15:18:35 -07001445 case Instruction::INT_TO_DOUBLE:
1446 case Instruction::LONG_TO_DOUBLE:
1447 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001448 break;
1449
buzbee76592632012-06-29 15:18:35 -07001450 case Instruction::FLOAT_TO_DOUBLE:
1451 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001452 break;
1453
buzbee76592632012-06-29 15:18:35 -07001454 case Instruction::DOUBLE_TO_FLOAT:
1455 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001456 break;
1457
1458 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001459 case Instruction::NEG_INT:
1460 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001461 break;
1462
1463 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001464 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001465 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001466 break;
1467
buzbee76592632012-06-29 15:18:35 -07001468 case Instruction::NOT_LONG:
1469 case Instruction::NOT_INT:
1470 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001471 break;
1472
buzbee2cfc6392012-05-07 14:51:40 -07001473 case Instruction::FLOAT_TO_INT:
buzbee2cfc6392012-05-07 14:51:40 -07001474 case Instruction::DOUBLE_TO_INT:
buzbee76592632012-06-29 15:18:35 -07001475 convertFPToInt(cUnit, cUnit->irb->getInt32Ty(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001476 break;
1477
buzbee76592632012-06-29 15:18:35 -07001478 case Instruction::FLOAT_TO_LONG:
1479 case Instruction::DOUBLE_TO_LONG:
1480 convertFPToInt(cUnit, cUnit->irb->getInt64Ty(), rlDest, rlSrc[0]);
1481 break;
1482
1483 case Instruction::CMPL_FLOAT:
1484 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1485 rlDest, rlSrc[0], rlSrc[1]);
1486 break;
1487 case Instruction::CMPG_FLOAT:
1488 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1489 rlDest, rlSrc[0], rlSrc[1]);
1490 break;
1491 case Instruction::CMPL_DOUBLE:
1492 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1493 rlDest, rlSrc[0], rlSrc[1]);
1494 break;
1495 case Instruction::CMPG_DOUBLE:
1496 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1497 rlDest, rlSrc[0], rlSrc[1]);
1498 break;
1499 case Instruction::CMP_LONG:
1500 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1501 rlDest, rlSrc[0], rlSrc[1]);
1502 break;
1503
1504#if 0
1505 case Instruction::PACKED_SWITCH:
1506 genPackedSwitch(cUnit, vB, rlSrc[0]);
1507 break;
1508
1509 case Instruction::SPARSE_SWITCH:
1510 genSparseSwitch(cUnit, vB, rlSrc[0], labelList);
1511 break;
buzbee2cfc6392012-05-07 14:51:40 -07001512#endif
1513
1514 default:
buzbee32412962012-06-26 16:27:56 -07001515 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001516 res = true;
1517 }
buzbeeb03f4872012-06-11 15:22:11 -07001518 if (objectDefinition) {
1519 setShadowFrameEntry(cUnit, (llvm::Value*)
1520 cUnit->llvmValues.elemList[rlDest.origSReg]);
1521 }
buzbee2cfc6392012-05-07 14:51:40 -07001522 return res;
1523}
1524
1525/* Extended MIR instructions like PHI */
1526void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1527 llvm::BasicBlock* llvmBB)
1528{
1529
1530 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1531 case kMirOpPhi: {
1532 int* incoming = (int*)mir->dalvikInsn.vB;
1533 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
1534 llvm::Type* phiType =
1535 llvmTypeFromLocRec(cUnit, rlDest);
1536 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1537 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1538 RegLocation loc;
1539 if (rlDest.wide) {
buzbee15bf9802012-06-12 17:49:27 -07001540 loc = oatGetSrcWide(cUnit, mir, i);
buzbee2cfc6392012-05-07 14:51:40 -07001541 i++;
1542 } else {
1543 loc = oatGetSrc(cUnit, mir, i);
1544 }
1545 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
1546 getLLVMBlock(cUnit, incoming[i]));
1547 }
1548 defineValue(cUnit, phi, rlDest.origSReg);
1549 break;
1550 }
1551 case kMirOpCopy: {
1552 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1553 break;
1554 }
1555#if defined(TARGET_ARM)
1556 case kMirOpFusedCmplFloat:
1557 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1558 break;
1559 case kMirOpFusedCmpgFloat:
1560 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1561 break;
1562 case kMirOpFusedCmplDouble:
1563 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1564 break;
1565 case kMirOpFusedCmpgDouble:
1566 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1567 break;
1568 case kMirOpFusedCmpLong:
1569 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1570 break;
1571#endif
1572 default:
1573 break;
1574 }
1575}
1576
1577void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1578{
1579 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001580 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001581 arrayRef.push_back(cUnit->irb->getInt32(offset));
1582 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1583 cUnit->irb->SetDexOffset(node);
1584}
1585
1586// Attach method info as metadata to special intrinsic
1587void setMethodInfo(CompilationUnit* cUnit)
1588{
1589 // We don't want dex offset on this
1590 cUnit->irb->SetDexOffset(NULL);
1591 greenland::IntrinsicHelper::IntrinsicId id;
1592 id = greenland::IntrinsicHelper::MethodInfo;
1593 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1594 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1595 llvm::SmallVector<llvm::Value*, 2> regInfo;
1596 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1597 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1598 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1599 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1600 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1601 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1602 inst->setMetadata("RegInfo", regInfoNode);
1603 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1604 llvm::SmallVector<llvm::Value*, 50> pmap;
1605 for (int i = 0; i < promoSize; i++) {
1606 PromotionMap* p = &cUnit->promotionMap[i];
1607 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1608 ((p->fpReg & 0xff) << 16) |
1609 ((p->coreReg & 0xff) << 8) |
1610 ((p->fpLocation & 0xf) << 4) |
1611 (p->coreLocation & 0xf);
1612 pmap.push_back(cUnit->irb->getInt32(mapData));
1613 }
1614 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1615 inst->setMetadata("PromotionMap", mapNode);
1616 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1617}
1618
1619/* Handle the content in each basic block */
1620bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1621{
1622 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
1623 cUnit->irb->SetInsertPoint(llvmBB);
1624 setDexOffset(cUnit, bb->startOffset);
1625
1626 if (bb->blockType == kEntryBlock) {
1627 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001628 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1629 cUnit->numDalvikRegisters, true,
1630 kAllocMisc);
1631 for (int i = 0; i < cUnit->numSSARegs; i++) {
1632 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1633 }
1634 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1635 if (canBeRef[i]) {
1636 cUnit->numShadowFrameEntries++;
1637 }
1638 }
1639 if (cUnit->numShadowFrameEntries > 0) {
1640 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1641 cUnit->numShadowFrameEntries, true,
1642 kAllocMisc);
1643 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1644 if (canBeRef[i]) {
1645 cUnit->shadowMap[j++] = i;
1646 }
1647 }
1648 greenland::IntrinsicHelper::IntrinsicId id =
1649 greenland::IntrinsicHelper::AllocaShadowFrame;
1650 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1651 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1652 cUnit->irb->CreateCall(func, entries);
1653 }
buzbee2cfc6392012-05-07 14:51:40 -07001654 } else if (bb->blockType == kExitBlock) {
1655 /*
1656 * Because of the differences between how MIR/LIR and llvm handle exit
1657 * blocks, we won't explicitly covert them. On the llvm-to-lir
1658 * path, it will need to be regenereated.
1659 */
1660 return false;
buzbee6969d502012-06-15 16:40:31 -07001661 } else if (bb->blockType == kExceptionHandling) {
1662 /*
1663 * Because we're deferring null checking, delete the associated empty
1664 * exception block.
1665 * TODO: add new block type for exception blocks that we generate
1666 * greenland code for.
1667 */
1668 llvmBB->eraseFromParent();
1669 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001670 }
1671
1672 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1673
1674 setDexOffset(cUnit, mir->offset);
1675
1676 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
1677 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
1678
1679 /* If we're compiling for the debugger, generate an update callout */
1680 if (cUnit->genDebugger) {
1681 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1682 //genDebuggerUpdate(cUnit, mir->offset);
1683 }
1684
1685 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
1686 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1687 continue;
1688 }
1689
1690 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1691 NULL /* labelList */);
1692 if (notHandled) {
1693 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
1694 mir->offset, dalvikOpcode,
1695 Instruction::Name(dalvikOpcode),
1696 dalvikFormat);
1697 }
1698 }
1699
buzbee6969d502012-06-15 16:40:31 -07001700 if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001701 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1702 }
1703
1704 return false;
1705}
1706
buzbee4f4dfc72012-07-02 14:54:44 -07001707char remapShorty(char shortyType) {
1708 /*
1709 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1710 * and longs/doubles are represented as a pair of registers. When sub-word
1711 * arguments (and method results) are passed, they are extended to Dalvik
1712 * virtual register containers. Because llvm is picky about type consistency,
1713 * we must either cast the "real" type to 32-bit container multiple Dalvik
1714 * register types, or always use the expanded values.
1715 * Here, we're doing the latter. We map the shorty signature to container
1716 * types (which is valid so long as we always do a real expansion of passed
1717 * arguments and field loads).
1718 */
1719 switch(shortyType) {
1720 case 'Z' : shortyType = 'I'; break;
1721 case 'B' : shortyType = 'I'; break;
1722 case 'S' : shortyType = 'I'; break;
1723 case 'C' : shortyType = 'I'; break;
1724 default: break;
1725 }
1726 return shortyType;
1727}
1728
buzbee2cfc6392012-05-07 14:51:40 -07001729llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1730
1731 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001732 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001733 greenland::kAccurate);
1734
1735 // Get argument type
1736 std::vector<llvm::Type*> args_type;
1737
1738 // method object
1739 args_type.push_back(cUnit->irb->GetJMethodTy());
1740
1741 // Do we have a "this"?
1742 if ((cUnit->access_flags & kAccStatic) == 0) {
1743 args_type.push_back(cUnit->irb->GetJObjectTy());
1744 }
1745
1746 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001747 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001748 greenland::kAccurate));
1749 }
1750
1751 return llvm::FunctionType::get(ret_type, args_type, false);
1752}
1753
1754bool createFunction(CompilationUnit* cUnit) {
1755 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1756 /* with_signature */ false));
1757 llvm::FunctionType* func_type = getFunctionType(cUnit);
1758
1759 if (func_type == NULL) {
1760 return false;
1761 }
1762
1763 cUnit->func = llvm::Function::Create(func_type,
1764 llvm::Function::ExternalLinkage,
1765 func_name, cUnit->module);
1766
1767 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1768 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1769
1770 arg_iter->setName("method");
1771 ++arg_iter;
1772
1773 int startSReg = cUnit->numRegs;
1774
1775 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1776 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1777 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1778 }
1779
1780 return true;
1781}
1782
1783bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1784{
1785 // Skip the exit block
1786 if (bb->blockType == kExitBlock) {
1787 cUnit->idToBlockMap.Put(bb->id, NULL);
1788 } else {
1789 int offset = bb->startOffset;
1790 bool entryBlock = (bb->blockType == kEntryBlock);
1791 llvm::BasicBlock* llvmBB =
1792 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
Elliott Hughes74847412012-06-20 18:10:21 -07001793 StringPrintf(kLabelFormat, offset, bb->id),
buzbee2cfc6392012-05-07 14:51:40 -07001794 cUnit->func);
1795 if (entryBlock) {
1796 cUnit->entryBB = llvmBB;
1797 cUnit->placeholderBB =
1798 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
1799 cUnit->func);
1800 }
1801 cUnit->idToBlockMap.Put(bb->id, llvmBB);
1802 }
1803 return false;
1804}
1805
1806
1807/*
1808 * Convert MIR to LLVM_IR
1809 * o For each ssa name, create LLVM named value. Type these
1810 * appropriately, and ignore high half of wide and double operands.
1811 * o For each MIR basic block, create an LLVM basic block.
1812 * o Iterate through the MIR a basic block at a time, setting arguments
1813 * to recovered ssa name.
1814 */
1815void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
1816{
1817 initIR(cUnit);
1818 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
1819
1820 // Create the function
1821 createFunction(cUnit);
1822
1823 // Create an LLVM basic block for each MIR block in dfs preorder
1824 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
1825 kPreOrderDFSTraversal, false /* isIterative */);
1826 /*
1827 * Create an llvm named value for each MIR SSA name. Note: we'll use
1828 * placeholders for all non-argument values (because we haven't seen
1829 * the definition yet).
1830 */
1831 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
1832 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1833 arg_iter++; /* Skip path method */
1834 for (int i = 0; i < cUnit->numSSARegs; i++) {
1835 llvm::Value* val;
1836 llvm::Type* ty = llvmTypeFromLocRec(cUnit, cUnit->regLocation[i]);
1837 if (i < cUnit->numRegs) {
1838 // Skip non-argument _0 names - should never be a use
1839 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)0);
1840 } else if (i >= (cUnit->numRegs + cUnit->numIns)) {
1841 // Handle SSA defs, skipping Method* and compiler temps
1842 if (SRegToVReg(cUnit, i) < 0) {
1843 val = NULL;
1844 } else {
1845 val = cUnit->irb->CreateLoad(cUnit->irb->CreateAlloca(ty, 0));
1846 val->setName(llvmSSAName(cUnit, i));
1847 }
1848 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
1849 if (cUnit->regLocation[i].wide) {
1850 // Skip high half of wide values
1851 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
1852 i++;
1853 }
1854 } else {
1855 // Recover previously-created argument values
1856 llvm::Value* argVal = arg_iter++;
1857 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
buzbee4f4dfc72012-07-02 14:54:44 -07001858 if (cUnit->regLocation[i].wide) {
1859 // Skip high half of wide values.
1860 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
1861 i++;
1862 }
buzbee2cfc6392012-05-07 14:51:40 -07001863 }
1864 }
1865 cUnit->irb->CreateBr(cUnit->placeholderBB);
1866
1867 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
1868 kPreOrderDFSTraversal, false /* Iterative */);
1869
1870 cUnit->placeholderBB->eraseFromParent();
1871
1872 llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction);
1873
buzbeead8f15e2012-06-18 14:49:45 -07001874 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
1875 // Write bitcode to file
1876 std::string errmsg;
1877 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
1878 oatReplaceSpecialChars(fname);
1879 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07001880 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07001881
buzbeead8f15e2012-06-18 14:49:45 -07001882 llvm::OwningPtr<llvm::tool_output_file> out_file(
1883 new llvm::tool_output_file(fname.c_str(), errmsg,
1884 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07001885
buzbeead8f15e2012-06-18 14:49:45 -07001886 if (!errmsg.empty()) {
1887 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
1888 }
1889
1890 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
1891 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07001892 }
buzbee2cfc6392012-05-07 14:51:40 -07001893}
1894
1895RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
1896 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07001897 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001898 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
1899 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07001900 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07001901 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07001902 // FIXME: need to be more robust, handle FP and be in a position to
1903 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07001904 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
1905 memset(&res, 0, sizeof(res));
1906 res.location = kLocPhysReg;
1907 res.lowReg = oatAllocTemp(cUnit);
1908 res.home = true;
1909 res.sRegLow = INVALID_SREG;
1910 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07001911 llvm::Type* ty = val->getType();
1912 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
1913 (ty == cUnit->irb->getDoubleTy()));
1914 if (res.wide) {
1915 res.highReg = oatAllocTemp(cUnit);
1916 }
buzbee4f1181f2012-06-22 13:52:12 -07001917 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07001918 } else {
1919 DCHECK_EQ(valName[0], 'v');
1920 int baseSReg = INVALID_SREG;
1921 sscanf(valName.c_str(), "v%d_", &baseSReg);
1922 res = cUnit->regLocation[baseSReg];
1923 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07001924 }
1925 } else {
1926 res = it->second;
1927 }
1928 return res;
1929}
1930
1931Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
1932{
1933 Instruction::Code res = Instruction::NOP;
1934 if (isWide) {
1935 switch(op) {
1936 case kOpAdd: res = Instruction::ADD_LONG; break;
1937 case kOpSub: res = Instruction::SUB_LONG; break;
1938 case kOpMul: res = Instruction::MUL_LONG; break;
1939 case kOpDiv: res = Instruction::DIV_LONG; break;
1940 case kOpRem: res = Instruction::REM_LONG; break;
1941 case kOpAnd: res = Instruction::AND_LONG; break;
1942 case kOpOr: res = Instruction::OR_LONG; break;
1943 case kOpXor: res = Instruction::XOR_LONG; break;
1944 case kOpLsl: res = Instruction::SHL_LONG; break;
1945 case kOpLsr: res = Instruction::USHR_LONG; break;
1946 case kOpAsr: res = Instruction::SHR_LONG; break;
1947 default: LOG(FATAL) << "Unexpected OpKind " << op;
1948 }
1949 } else if (isConst){
1950 switch(op) {
1951 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
1952 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
1953 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
1954 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
1955 case kOpRem: res = Instruction::REM_INT_LIT16; break;
1956 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
1957 case kOpOr: res = Instruction::OR_INT_LIT16; break;
1958 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
1959 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
1960 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
1961 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
1962 default: LOG(FATAL) << "Unexpected OpKind " << op;
1963 }
1964 } else {
1965 switch(op) {
1966 case kOpAdd: res = Instruction::ADD_INT; break;
1967 case kOpSub: res = Instruction::SUB_INT; break;
1968 case kOpMul: res = Instruction::MUL_INT; break;
1969 case kOpDiv: res = Instruction::DIV_INT; break;
1970 case kOpRem: res = Instruction::REM_INT; break;
1971 case kOpAnd: res = Instruction::AND_INT; break;
1972 case kOpOr: res = Instruction::OR_INT; break;
1973 case kOpXor: res = Instruction::XOR_INT; break;
1974 case kOpLsl: res = Instruction::SHL_INT; break;
1975 case kOpLsr: res = Instruction::USHR_INT; break;
1976 case kOpAsr: res = Instruction::SHR_INT; break;
1977 default: LOG(FATAL) << "Unexpected OpKind " << op;
1978 }
1979 }
1980 return res;
1981}
1982
buzbee4f1181f2012-06-22 13:52:12 -07001983Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
1984{
1985 Instruction::Code res = Instruction::NOP;
1986 if (isWide) {
1987 switch(op) {
1988 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
1989 case kOpSub: res = Instruction::SUB_DOUBLE; break;
1990 case kOpMul: res = Instruction::MUL_DOUBLE; break;
1991 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
1992 case kOpRem: res = Instruction::REM_DOUBLE; break;
1993 default: LOG(FATAL) << "Unexpected OpKind " << op;
1994 }
1995 } else {
1996 switch(op) {
1997 case kOpAdd: res = Instruction::ADD_FLOAT; break;
1998 case kOpSub: res = Instruction::SUB_FLOAT; break;
1999 case kOpMul: res = Instruction::MUL_FLOAT; break;
2000 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2001 case kOpRem: res = Instruction::REM_FLOAT; break;
2002 default: LOG(FATAL) << "Unexpected OpKind " << op;
2003 }
2004 }
2005 return res;
2006}
2007
2008void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2009{
2010 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002011 /*
2012 * Normally, we won't ever generate an FP operation with an immediate
2013 * operand (not supported in Dex instruction set). However, the IR builder
2014 * may insert them - in particular for createNegFP. Recognize this case
2015 * and deal with it.
2016 */
2017 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2018 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2019 DCHECK(op2C == NULL);
2020 if ((op1C != NULL) && (op == kOpSub)) {
2021 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2022 if (rlDest.wide) {
2023 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2024 } else {
2025 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2026 }
buzbee4f1181f2012-06-22 13:52:12 -07002027 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002028 DCHECK(op1C == NULL);
2029 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2030 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2031 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2032 if (rlDest.wide) {
2033 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2034 } else {
2035 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2036 }
buzbee4f1181f2012-06-22 13:52:12 -07002037 }
2038}
2039
buzbee101305f2012-06-28 18:00:56 -07002040void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2041 Instruction::Code opcode)
2042{
2043 RegLocation rlDest = getLoc(cUnit, inst);
2044 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2045 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2046}
2047
buzbee76592632012-06-29 15:18:35 -07002048void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2049{
2050 RegLocation rlDest = getLoc(cUnit, inst);
2051 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2052 Instruction::Code opcode;
2053 if (rlDest.wide) {
2054 if (rlSrc.wide) {
2055 opcode = Instruction::LONG_TO_DOUBLE;
2056 } else {
2057 opcode = Instruction::INT_TO_DOUBLE;
2058 }
2059 } else {
2060 if (rlSrc.wide) {
2061 opcode = Instruction::LONG_TO_FLOAT;
2062 } else {
2063 opcode = Instruction::INT_TO_FLOAT;
2064 }
2065 }
2066 genConversion(cUnit, opcode, rlDest, rlSrc);
2067}
2068
2069void cvtFPToInt(CompilationUnit* cUnit, llvm::Instruction* inst)
2070{
2071 RegLocation rlDest = getLoc(cUnit, inst);
2072 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2073 Instruction::Code opcode;
2074 if (rlDest.wide) {
2075 if (rlSrc.wide) {
2076 opcode = Instruction::DOUBLE_TO_LONG;
2077 } else {
2078 opcode = Instruction::FLOAT_TO_LONG;
2079 }
2080 } else {
2081 if (rlSrc.wide) {
2082 opcode = Instruction::DOUBLE_TO_INT;
2083 } else {
2084 opcode = Instruction::FLOAT_TO_INT;
2085 }
2086 }
2087 genConversion(cUnit, opcode, rlDest, rlSrc);
2088}
2089
2090void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2091{
2092 RegLocation rlDest = getLoc(cUnit, inst);
2093 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2094 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2095}
2096
2097void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2098{
2099 RegLocation rlDest = getLoc(cUnit, inst);
2100 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2101 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2102 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2103 storeValue(cUnit, rlDest, rlSrc);
2104}
2105
2106void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2107{
2108 RegLocation rlDest = getLoc(cUnit, inst);
2109 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2110 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2111}
2112
2113
buzbee101305f2012-06-28 18:00:56 -07002114void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2115{
2116 // TODO: evaluate src/tgt types and add general support for more than int to long
2117 RegLocation rlDest = getLoc(cUnit, inst);
2118 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2119 DCHECK(rlDest.wide);
2120 DCHECK(!rlSrc.wide);
2121 DCHECK(!rlDest.fp);
2122 DCHECK(!rlSrc.fp);
2123 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2124 if (rlSrc.location == kLocPhysReg) {
2125 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2126 } else {
2127 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2128 }
2129 if (isSigned) {
2130 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2131 } else {
2132 loadConstant(cUnit, rlResult.highReg, 0);
2133 }
2134 storeValueWide(cUnit, rlDest, rlResult);
2135}
2136
buzbee2cfc6392012-05-07 14:51:40 -07002137void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2138{
2139 RegLocation rlDest = getLoc(cUnit, inst);
2140 llvm::Value* lhs = inst->getOperand(0);
buzbee4f1181f2012-06-22 13:52:12 -07002141 // Special-case RSUB
2142 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2143 if ((op == kOpSub) && (lhsImm != NULL)) {
2144 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
2145 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2146 lhsImm->getSExtValue());
2147 return;
2148 }
2149 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002150 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2151 llvm::Value* rhs = inst->getOperand(1);
2152 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2153 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
2154 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, src2->getSExtValue());
2155 } else {
2156 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
2157 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2158 if (rlDest.wide) {
2159 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2160 } else {
2161 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2162 }
2163 }
2164}
2165
buzbee101305f2012-06-28 18:00:56 -07002166void cvtShiftOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2167{
2168 if (inst->getType() == cUnit->irb->getInt64Ty()) {
2169 /*
2170 * llvm wants the shift amount to be 64 bits, whereas we've constained
2171 * it to be in 6 bits. It should always be held as an unnamed temp
2172 * at this point that was the result of a previous UExt. We'll backtrack
2173 * to find the pre-extension value and use that.
2174 * TODO: probably better to handle this in cvtIntExt() or just intrinsify
2175 */
2176 RegLocation rlDest = getLoc(cUnit, inst);
2177 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2178 RegLocation rlShift = getLoc(cUnit, inst->getOperand(1));
2179 DCHECK(rlShift.wide);
2180 DCHECK_EQ(rlShift.sRegLow, INVALID_SREG);
2181 // Now, free the temp registers - we won't need them.
2182 // TODO: kill the dead extend ops
2183 oatFreeTemp(cUnit, rlShift.lowReg);
2184 oatFreeTemp(cUnit, rlShift.highReg);
2185 // Get the pre-extend operand
2186 llvm::Instruction* extInst =
2187 llvm::dyn_cast<llvm::Instruction>(inst->getOperand(1));
2188 DCHECK(extInst != NULL);
2189 rlShift = getLoc(cUnit, extInst->getOperand(0));
2190 DCHECK(!rlShift.wide);
2191 Instruction::Code opcode;
2192 if (op == kOpLsl)
2193 opcode = Instruction::SHL_LONG;
2194 else if (op == kOpAsr)
2195 opcode = Instruction::SHR_LONG;
2196 else {
2197 DCHECK_EQ(op, kOpLsr);
2198 opcode = Instruction::USHR_LONG;
2199 }
2200 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2201 } else {
2202 cvtBinOp(cUnit, op, inst);
2203 }
2204}
2205
buzbee2cfc6392012-05-07 14:51:40 -07002206void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2207{
2208 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2209 DCHECK(brInst != NULL);
2210 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2211 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2212 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2213}
2214
2215void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2216{
2217 // Nop - these have already been processed
2218}
2219
2220void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2221{
2222 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2223 llvm::Value* retVal = retInst->getReturnValue();
2224 if (retVal != NULL) {
2225 RegLocation rlSrc = getLoc(cUnit, retVal);
2226 if (rlSrc.wide) {
2227 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2228 } else {
2229 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2230 }
2231 }
2232 genExitSequence(cUnit);
2233}
2234
2235ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2236{
2237 ConditionCode res = kCondAl;
2238 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002239 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002240 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2241 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2242 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002243 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002244 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002245 default: LOG(FATAL) << "Unexpected llvm condition";
2246 }
2247 return res;
2248}
2249
2250void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2251{
2252 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2253 UNIMPLEMENTED(FATAL);
2254}
2255
2256void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2257 llvm::BranchInst* brInst)
2258{
2259 // Get targets
2260 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2261 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2262 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2263 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2264 // Get comparison operands
2265 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2266 ConditionCode cond = getCond(iCmpInst->getPredicate());
2267 llvm::Value* lhs = iCmpInst->getOperand(0);
2268 // Not expecting a constant as 1st operand
2269 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2270 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2271 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2272 llvm::Value* rhs = inst->getOperand(1);
2273#if defined(TARGET_MIPS)
2274 // Compare and branch in one shot
2275 (void)taken;
2276 (void)cond;
2277 (void)rhs;
2278 UNIMPLEMENTED(FATAL);
2279#else
2280 //Compare, then branch
2281 // TODO: handle fused CMP_LONG/IF_xxZ case
2282 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2283 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
2284 } else {
2285 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2286 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2287 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2288 }
2289 opCondBranch(cUnit, cond, taken);
2290#endif
2291 // Fallthrough
2292 opUnconditionalBranch(cUnit, fallThrough);
2293}
2294
2295void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2296 llvm::Function* callee)
2297{
2298 UNIMPLEMENTED(FATAL);
2299}
2300
buzbee2cfc6392012-05-07 14:51:40 -07002301void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2302{
buzbee4f1181f2012-06-22 13:52:12 -07002303 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002304 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2305 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002306 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2307 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002308 if (rlSrc.wide) {
2309 storeValueWide(cUnit, rlDest, rlSrc);
2310 } else {
2311 storeValue(cUnit, rlDest, rlSrc);
2312 }
2313}
2314
2315// Note: Immediate arg is a ConstantInt regardless of result type
2316void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2317{
buzbee4f1181f2012-06-22 13:52:12 -07002318 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002319 llvm::ConstantInt* src =
2320 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2321 uint64_t immval = src->getZExtValue();
2322 RegLocation rlDest = getLoc(cUnit, callInst);
2323 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2324 if (rlDest.wide) {
2325 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2326 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2327 storeValueWide(cUnit, rlDest, rlResult);
2328 } else {
2329 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2330 storeValue(cUnit, rlDest, rlResult);
2331 }
2332}
2333
buzbee101305f2012-06-28 18:00:56 -07002334void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2335 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002336{
buzbee4f1181f2012-06-22 13:52:12 -07002337 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002338 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002339 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002340 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002341 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002342 if (isString) {
2343 genConstString(cUnit, index, rlDest);
2344 } else {
2345 genConstClass(cUnit, index, rlDest);
2346 }
2347}
2348
2349void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2350{
2351 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2352 llvm::ConstantInt* offsetVal =
2353 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2354 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2355 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002356}
2357
buzbee4f1181f2012-06-22 13:52:12 -07002358void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2359{
buzbee32412962012-06-26 16:27:56 -07002360 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002361 llvm::ConstantInt* typeIdxVal =
2362 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2363 uint32_t typeIdx = typeIdxVal->getZExtValue();
2364 RegLocation rlDest = getLoc(cUnit, callInst);
2365 genNewInstance(cUnit, typeIdx, rlDest);
2366}
2367
buzbee8fa0fda2012-06-27 15:44:52 -07002368void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2369{
2370 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2371 llvm::ConstantInt* typeIdxVal =
2372 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2373 uint32_t typeIdx = typeIdxVal->getZExtValue();
2374 llvm::Value* len = callInst->getArgOperand(1);
2375 RegLocation rlLen = getLoc(cUnit, len);
2376 RegLocation rlDest = getLoc(cUnit, callInst);
2377 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2378}
2379
2380void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2381{
2382 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2383 llvm::ConstantInt* typeIdxVal =
2384 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2385 uint32_t typeIdx = typeIdxVal->getZExtValue();
2386 llvm::Value* src = callInst->getArgOperand(1);
2387 RegLocation rlSrc = getLoc(cUnit, src);
2388 RegLocation rlDest = getLoc(cUnit, callInst);
2389 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2390}
2391
buzbee32412962012-06-26 16:27:56 -07002392void cvtThrowVerificationError(CompilationUnit* cUnit, llvm::CallInst* callInst)
2393{
2394 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2395 llvm::ConstantInt* info1 =
2396 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2397 llvm::ConstantInt* info2 =
2398 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2399 genThrowVerificationError(cUnit, info1->getZExtValue(), info2->getZExtValue());
2400}
2401
2402void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2403{
2404 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2405 llvm::Value* src = callInst->getArgOperand(0);
2406 RegLocation rlSrc = getLoc(cUnit, src);
2407 genThrow(cUnit, rlSrc);
2408}
2409
buzbee8fa0fda2012-06-27 15:44:52 -07002410void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2411 llvm::CallInst* callInst)
2412{
2413 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2414 llvm::ConstantInt* optFlags =
2415 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2416 llvm::Value* src = callInst->getArgOperand(1);
2417 RegLocation rlSrc = getLoc(cUnit, src);
2418 if (isEnter) {
2419 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2420 } else {
2421 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2422 }
2423}
2424
buzbee76592632012-06-29 15:18:35 -07002425void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002426{
2427 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2428 llvm::ConstantInt* optFlags =
2429 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2430 llvm::Value* src = callInst->getArgOperand(1);
2431 RegLocation rlSrc = getLoc(cUnit, src);
2432 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2433 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2434 RegLocation rlDest = getLoc(cUnit, callInst);
2435 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2436 int lenOffset = Array::LengthOffset().Int32Value();
2437 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2438 storeValue(cUnit, rlDest, rlResult);
2439}
2440
buzbee32412962012-06-26 16:27:56 -07002441void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2442{
2443 DCHECK_EQ(callInst->getNumArgOperands(), 0U);
2444 int exOffset = Thread::ExceptionOffset().Int32Value();
2445 RegLocation rlDest = getLoc(cUnit, callInst);
2446 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2447#if defined(TARGET_X86)
2448 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
2449 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
2450#else
2451 int resetReg = oatAllocTemp(cUnit);
2452 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
2453 loadConstant(cUnit, resetReg, 0);
2454 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
2455 oatFreeTemp(cUnit, resetReg);
2456#endif
2457 storeValue(cUnit, rlDest, rlResult);
2458}
2459
buzbee4f1181f2012-06-22 13:52:12 -07002460void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2461 bool isObject)
2462{
buzbee32412962012-06-26 16:27:56 -07002463 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002464 llvm::ConstantInt* typeIdxVal =
2465 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2466 uint32_t typeIdx = typeIdxVal->getZExtValue();
2467 RegLocation rlDest = getLoc(cUnit, callInst);
2468 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2469}
2470
buzbee8fa0fda2012-06-27 15:44:52 -07002471void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2472 bool isObject)
2473{
2474 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2475 llvm::ConstantInt* typeIdxVal =
2476 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2477 uint32_t typeIdx = typeIdxVal->getZExtValue();
2478 llvm::Value* src = callInst->getArgOperand(1);
2479 RegLocation rlSrc = getLoc(cUnit, src);
2480 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2481}
2482
2483void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2484 int scale)
2485{
2486 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2487 llvm::ConstantInt* optFlags =
2488 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2489 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2490 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2491 RegLocation rlDest = getLoc(cUnit, callInst);
2492 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2493 rlDest, scale);
2494}
2495
2496void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2497 int scale)
2498{
2499 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2500 llvm::ConstantInt* optFlags =
2501 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2502 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2503 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2504 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
2505 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2506 rlSrc, scale);
2507}
2508
buzbee101305f2012-06-28 18:00:56 -07002509void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2510 bool isWide, bool isObj)
2511{
2512 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2513 llvm::ConstantInt* optFlags =
2514 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2515 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2516 llvm::ConstantInt* fieldIdx =
2517 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2518 RegLocation rlDest = getLoc(cUnit, callInst);
2519 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2520 size, rlDest, rlObj, isWide, isObj);
2521}
2522
2523void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2524 bool isWide, bool isObj)
2525{
2526 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2527 llvm::ConstantInt* optFlags =
2528 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2529 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2530 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2531 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002532 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002533 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2534 size, rlSrc, rlObj, isWide, isObj);
2535}
2536
2537void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2538{
2539 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2540 llvm::ConstantInt* typeIdx =
2541 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2542 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2543 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2544}
2545
buzbee76592632012-06-29 15:18:35 -07002546void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2547 Instruction::Code opcode)
2548{
2549 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2550 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2551 RegLocation rlDest = getLoc(cUnit, callInst);
2552 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2553}
2554
2555void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2556{
2557 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2558 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2559 RegLocation rlDest = getLoc(cUnit, callInst);
2560 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2561}
2562
buzbee6969d502012-06-15 16:40:31 -07002563void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002564 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002565{
2566 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2567 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002568 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002569 info->result.location = kLocInvalid;
2570 } else {
2571 info->result = getLoc(cUnit, callInst);
2572 }
2573 llvm::ConstantInt* invokeTypeVal =
2574 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2575 llvm::ConstantInt* methodIndexVal =
2576 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2577 llvm::ConstantInt* optFlagsVal =
2578 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2579 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2580 info->index = methodIndexVal->getZExtValue();
2581 info->optFlags = optFlagsVal->getZExtValue();
2582 info->offset = cUnit->currentDalvikOffset;
2583
buzbee6969d502012-06-15 16:40:31 -07002584 // Count the argument words, and then build argument array.
2585 info->numArgWords = 0;
2586 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2587 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2588 info->numArgWords += tLoc.wide ? 2 : 1;
2589 }
2590 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2591 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2592 // Now, fill in the location records, synthesizing high loc of wide vals
2593 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002594 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002595 if (info->args[next].wide) {
2596 next++;
2597 // TODO: Might make sense to mark this as an invalid loc
2598 info->args[next].origSReg = info->args[next-1].origSReg+1;
2599 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2600 }
2601 next++;
2602 }
buzbee4f4dfc72012-07-02 14:54:44 -07002603 // TODO - rework such that we no longer need isRange
2604 info->isRange = (info->numArgWords > 5);
2605
buzbee76592632012-06-29 15:18:35 -07002606 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002607 genFilledNewArray(cUnit, info);
2608 } else {
2609 genInvoke(cUnit, info);
2610 }
buzbee6969d502012-06-15 16:40:31 -07002611}
2612
buzbeead8f15e2012-06-18 14:49:45 -07002613/* Look up the RegLocation associated with a Value. Must already be defined */
2614RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2615{
2616 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2617 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2618 return it->second;
2619}
2620
buzbee2cfc6392012-05-07 14:51:40 -07002621bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2622{
2623 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2624 // Define the starting label
2625 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2626 // Extract the starting offset from the block's name
2627 if (!isEntry) {
2628 const char* blockName = bb->getName().str().c_str();
2629 int dummy;
Elliott Hughes74847412012-06-20 18:10:21 -07002630 sscanf(blockName, kLabelFormat, &blockLabel->operands[0], &dummy);
buzbee2cfc6392012-05-07 14:51:40 -07002631 }
2632 // Set the label kind
2633 blockLabel->opcode = kPseudoNormalBlockLabel;
2634 // Insert the label
2635 oatAppendLIR(cUnit, blockLabel);
2636
2637 // Free temp registers and reset redundant store tracking */
2638 oatResetRegPool(cUnit);
2639 oatResetDefTracking(cUnit);
2640
2641 //TODO: restore oat incoming liveness optimization
2642 oatClobberAllRegs(cUnit);
2643
buzbee6969d502012-06-15 16:40:31 -07002644 LIR* headLIR = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07002645
2646 if (isEntry) {
2647 cUnit->currentDalvikOffset = 0;
buzbeead8f15e2012-06-18 14:49:45 -07002648 RegLocation* argLocs = (RegLocation*)
2649 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2650 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2651 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2652 for (unsigned i = 0; it != it_end; ++it) {
2653 llvm::Value* val = it;
2654 argLocs[i++] = valToLoc(cUnit, val);
2655 llvm::Type* ty = val->getType();
2656 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2657 argLocs[i++].sRegLow = INVALID_SREG;
2658 }
2659 }
2660 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
buzbee2cfc6392012-05-07 14:51:40 -07002661 }
2662
2663 // Visit all of the instructions in the block
2664 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2665 llvm::Instruction* inst = it;
2666 llvm::BasicBlock::iterator nextIt = ++it;
2667 // Extract the Dalvik offset from the instruction
2668 uint32_t opcode = inst->getOpcode();
2669 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2670 if (dexOffsetNode != NULL) {
2671 llvm::ConstantInt* dexOffsetValue =
2672 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2673 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2674 }
2675
buzbee6969d502012-06-15 16:40:31 -07002676 oatResetRegPool(cUnit);
2677 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2678 oatClobberAllRegs(cUnit);
2679 }
2680
2681 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2682 oatResetDefTracking(cUnit);
2683 }
2684
2685#ifndef NDEBUG
2686 /* Reset temp tracking sanity check */
2687 cUnit->liveSReg = INVALID_SREG;
2688#endif
2689
2690 LIR* boundaryLIR;
2691 const char* instStr = "boundary";
2692 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
2693 (intptr_t) instStr);
2694 cUnit->boundaryMap.Overwrite(cUnit->currentDalvikOffset, boundaryLIR);
2695
2696 /* Remember the first LIR for thisl block*/
2697 if (headLIR == NULL) {
2698 headLIR = boundaryLIR;
2699 headLIR->defMask = ENCODE_ALL;
2700 }
2701
buzbee2cfc6392012-05-07 14:51:40 -07002702 switch(opcode) {
2703
2704 case llvm::Instruction::ICmp: {
2705 llvm::Instruction* nextInst = nextIt;
2706 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2707 if (brInst != NULL /* and... */) {
2708 cvtICmpBr(cUnit, inst, brInst);
2709 ++it;
2710 } else {
2711 cvtICmp(cUnit, inst);
2712 }
2713 }
2714 break;
2715
2716 case llvm::Instruction::Call: {
2717 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2718 llvm::Function* callee = callInst->getCalledFunction();
2719 greenland::IntrinsicHelper::IntrinsicId id =
2720 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2721 switch (id) {
buzbeeb03f4872012-06-11 15:22:11 -07002722 case greenland::IntrinsicHelper::AllocaShadowFrame:
2723 case greenland::IntrinsicHelper::SetShadowFrameEntry:
buzbee6969d502012-06-15 16:40:31 -07002724 case greenland::IntrinsicHelper::PopShadowFrame:
buzbeeb03f4872012-06-11 15:22:11 -07002725 // Ignore shadow frame stuff for quick compiler
2726 break;
buzbee2cfc6392012-05-07 14:51:40 -07002727 case greenland::IntrinsicHelper::CopyInt:
2728 case greenland::IntrinsicHelper::CopyObj:
2729 case greenland::IntrinsicHelper::CopyFloat:
2730 case greenland::IntrinsicHelper::CopyLong:
2731 case greenland::IntrinsicHelper::CopyDouble:
2732 cvtCopy(cUnit, callInst);
2733 break;
2734 case greenland::IntrinsicHelper::ConstInt:
2735 case greenland::IntrinsicHelper::ConstObj:
2736 case greenland::IntrinsicHelper::ConstLong:
2737 case greenland::IntrinsicHelper::ConstFloat:
2738 case greenland::IntrinsicHelper::ConstDouble:
2739 cvtConst(cUnit, callInst);
2740 break;
buzbee4f1181f2012-06-22 13:52:12 -07002741 case greenland::IntrinsicHelper::DivInt:
2742 case greenland::IntrinsicHelper::DivLong:
2743 cvtBinOp(cUnit, kOpDiv, inst);
2744 break;
2745 case greenland::IntrinsicHelper::RemInt:
2746 case greenland::IntrinsicHelper::RemLong:
2747 cvtBinOp(cUnit, kOpRem, inst);
2748 break;
buzbee2cfc6392012-05-07 14:51:40 -07002749 case greenland::IntrinsicHelper::MethodInfo:
buzbeead8f15e2012-06-18 14:49:45 -07002750 // Already dealt with - just ignore it here.
buzbee2cfc6392012-05-07 14:51:40 -07002751 break;
2752 case greenland::IntrinsicHelper::CheckSuspend:
2753 genSuspendTest(cUnit, 0 /* optFlags already applied */);
2754 break;
buzbee4f1181f2012-06-22 13:52:12 -07002755 case greenland::IntrinsicHelper::HLInvokeObj:
buzbee8fa0fda2012-06-27 15:44:52 -07002756 case greenland::IntrinsicHelper::HLInvokeFloat:
2757 case greenland::IntrinsicHelper::HLInvokeDouble:
2758 case greenland::IntrinsicHelper::HLInvokeLong:
2759 case greenland::IntrinsicHelper::HLInvokeInt:
buzbee101305f2012-06-28 18:00:56 -07002760 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
buzbee4f1181f2012-06-22 13:52:12 -07002761 break;
buzbee6969d502012-06-15 16:40:31 -07002762 case greenland::IntrinsicHelper::HLInvokeVoid:
buzbee101305f2012-06-28 18:00:56 -07002763 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
2764 break;
2765 case greenland::IntrinsicHelper::FilledNewArray:
2766 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
2767 break;
2768 case greenland::IntrinsicHelper::FillArrayData:
2769 cvtFillArrayData(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07002770 break;
2771 case greenland::IntrinsicHelper::ConstString:
buzbee101305f2012-06-28 18:00:56 -07002772 cvtConstObject(cUnit, callInst, true /* isString */);
2773 break;
2774 case greenland::IntrinsicHelper::ConstClass:
2775 cvtConstObject(cUnit, callInst, false /* isString */);
2776 break;
2777 case greenland::IntrinsicHelper::CheckCast:
2778 cvtCheckCast(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07002779 break;
buzbee4f1181f2012-06-22 13:52:12 -07002780 case greenland::IntrinsicHelper::NewInstance:
2781 cvtNewInstance(cUnit, callInst);
2782 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002783 case greenland::IntrinsicHelper::HLSgetObject:
buzbee4f1181f2012-06-22 13:52:12 -07002784 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
2785 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002786 case greenland::IntrinsicHelper::HLSget:
2787 case greenland::IntrinsicHelper::HLSgetFloat:
2788 case greenland::IntrinsicHelper::HLSgetBoolean:
2789 case greenland::IntrinsicHelper::HLSgetByte:
2790 case greenland::IntrinsicHelper::HLSgetChar:
2791 case greenland::IntrinsicHelper::HLSgetShort:
2792 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
2793 break;
2794 case greenland::IntrinsicHelper::HLSgetWide:
2795 case greenland::IntrinsicHelper::HLSgetDouble:
2796 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
2797 break;
buzbee76592632012-06-29 15:18:35 -07002798 case greenland::IntrinsicHelper::HLSput:
2799 case greenland::IntrinsicHelper::HLSputFloat:
2800 case greenland::IntrinsicHelper::HLSputBoolean:
2801 case greenland::IntrinsicHelper::HLSputByte:
2802 case greenland::IntrinsicHelper::HLSputChar:
2803 case greenland::IntrinsicHelper::HLSputShort:
2804 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
2805 break;
2806 case greenland::IntrinsicHelper::HLSputWide:
2807 case greenland::IntrinsicHelper::HLSputDouble:
2808 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
2809 break;
buzbee32412962012-06-26 16:27:56 -07002810 case greenland::IntrinsicHelper::GetException:
2811 cvtMoveException(cUnit, callInst);
2812 break;
2813 case greenland::IntrinsicHelper::Throw:
2814 cvtThrow(cUnit, callInst);
2815 break;
2816 case greenland::IntrinsicHelper::ThrowVerificationError:
buzbee8fa0fda2012-06-27 15:44:52 -07002817 cvtThrowVerificationError(cUnit, callInst);
buzbee32412962012-06-26 16:27:56 -07002818 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002819 case greenland::IntrinsicHelper::MonitorEnter:
2820 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
2821 break;
2822 case greenland::IntrinsicHelper::MonitorExit:
2823 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
2824 break;
2825 case greenland::IntrinsicHelper::ArrayLength:
buzbee76592632012-06-29 15:18:35 -07002826 cvtArrayLength(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07002827 break;
2828 case greenland::IntrinsicHelper::NewArray:
2829 cvtNewArray(cUnit, callInst);
2830 break;
2831 case greenland::IntrinsicHelper::InstanceOf:
2832 cvtInstanceOf(cUnit, callInst);
2833 break;
2834
2835 case greenland::IntrinsicHelper::HLArrayGet:
2836 case greenland::IntrinsicHelper::HLArrayGetObject:
2837 case greenland::IntrinsicHelper::HLArrayGetFloat:
2838 cvtAget(cUnit, callInst, kWord, 2);
2839 break;
2840 case greenland::IntrinsicHelper::HLArrayGetWide:
2841 case greenland::IntrinsicHelper::HLArrayGetDouble:
2842 cvtAget(cUnit, callInst, kLong, 3);
2843 break;
2844 case greenland::IntrinsicHelper::HLArrayGetBoolean:
2845 cvtAget(cUnit, callInst, kUnsignedByte, 0);
2846 break;
2847 case greenland::IntrinsicHelper::HLArrayGetByte:
2848 cvtAget(cUnit, callInst, kSignedByte, 0);
2849 break;
2850 case greenland::IntrinsicHelper::HLArrayGetChar:
2851 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
2852 break;
2853 case greenland::IntrinsicHelper::HLArrayGetShort:
2854 cvtAget(cUnit, callInst, kSignedHalf, 1);
2855 break;
2856
2857 case greenland::IntrinsicHelper::HLArrayPut:
2858 case greenland::IntrinsicHelper::HLArrayPutObject:
2859 case greenland::IntrinsicHelper::HLArrayPutFloat:
2860 cvtAput(cUnit, callInst, kWord, 2);
2861 break;
2862 case greenland::IntrinsicHelper::HLArrayPutWide:
2863 case greenland::IntrinsicHelper::HLArrayPutDouble:
2864 cvtAput(cUnit, callInst, kLong, 3);
2865 break;
2866 case greenland::IntrinsicHelper::HLArrayPutBoolean:
2867 cvtAput(cUnit, callInst, kUnsignedByte, 0);
2868 break;
2869 case greenland::IntrinsicHelper::HLArrayPutByte:
2870 cvtAput(cUnit, callInst, kSignedByte, 0);
2871 break;
2872 case greenland::IntrinsicHelper::HLArrayPutChar:
2873 cvtAput(cUnit, callInst, kUnsignedHalf, 1);
2874 break;
2875 case greenland::IntrinsicHelper::HLArrayPutShort:
2876 cvtAput(cUnit, callInst, kSignedHalf, 1);
2877 break;
2878
buzbee101305f2012-06-28 18:00:56 -07002879 case greenland::IntrinsicHelper::HLIGet:
2880 case greenland::IntrinsicHelper::HLIGetFloat:
2881 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
2882 break;
2883 case greenland::IntrinsicHelper::HLIGetObject:
2884 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
2885 break;
2886 case greenland::IntrinsicHelper::HLIGetWide:
2887 case greenland::IntrinsicHelper::HLIGetDouble:
2888 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
2889 break;
2890 case greenland::IntrinsicHelper::HLIGetBoolean:
2891 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
2892 false /* obj */);
2893 break;
2894 case greenland::IntrinsicHelper::HLIGetByte:
2895 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
2896 false /* obj */);
2897 break;
2898 case greenland::IntrinsicHelper::HLIGetChar:
2899 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
2900 false /* obj */);
2901 break;
2902 case greenland::IntrinsicHelper::HLIGetShort:
2903 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
2904 false /* obj */);
2905 break;
2906
2907 case greenland::IntrinsicHelper::HLIPut:
2908 case greenland::IntrinsicHelper::HLIPutFloat:
2909 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
2910 break;
2911 case greenland::IntrinsicHelper::HLIPutObject:
2912 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
2913 break;
2914 case greenland::IntrinsicHelper::HLIPutWide:
2915 case greenland::IntrinsicHelper::HLIPutDouble:
2916 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
2917 break;
2918 case greenland::IntrinsicHelper::HLIPutBoolean:
2919 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
2920 false /* obj */);
2921 break;
2922 case greenland::IntrinsicHelper::HLIPutByte:
2923 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
2924 false /* obj */);
2925 break;
2926 case greenland::IntrinsicHelper::HLIPutChar:
2927 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
2928 false /* obj */);
2929 break;
2930 case greenland::IntrinsicHelper::HLIPutShort:
2931 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
2932 false /* obj */);
2933 break;
2934
2935 case greenland::IntrinsicHelper::IntToChar:
2936 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
2937 break;
2938 case greenland::IntrinsicHelper::IntToShort:
2939 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
2940 break;
2941 case greenland::IntrinsicHelper::IntToByte:
2942 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
2943 break;
2944
buzbee76592632012-06-29 15:18:35 -07002945 case greenland::IntrinsicHelper::CmplFloat:
2946 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
2947 break;
2948 case greenland::IntrinsicHelper::CmpgFloat:
2949 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
2950 break;
2951 case greenland::IntrinsicHelper::CmplDouble:
2952 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
2953 break;
2954 case greenland::IntrinsicHelper::CmpgDouble:
2955 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
2956 break;
2957
2958 case greenland::IntrinsicHelper::CmpLong:
2959 cvtLongCompare(cUnit, callInst);
2960 break;
2961
buzbee2cfc6392012-05-07 14:51:40 -07002962 case greenland::IntrinsicHelper::UnknownId:
2963 cvtCall(cUnit, callInst, callee);
2964 break;
2965 default:
2966 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
2967 << cUnit->intrinsic_helper->GetName(id);
2968 }
2969 }
2970 break;
2971
2972 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
2973 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
2974 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
2975 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
2976 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
2977 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
2978 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
2979 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
2980 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
buzbee101305f2012-06-28 18:00:56 -07002981 case llvm::Instruction::Shl: cvtShiftOp(cUnit, kOpLsl, inst); break;
2982 case llvm::Instruction::LShr: cvtShiftOp(cUnit, kOpLsr, inst); break;
2983 case llvm::Instruction::AShr: cvtShiftOp(cUnit, kOpAsr, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07002984 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
2985 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
buzbee4f1181f2012-06-22 13:52:12 -07002986 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
2987 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
2988 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
2989 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
2990 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
buzbee76592632012-06-29 15:18:35 -07002991 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
2992 case llvm::Instruction::FPToSI: cvtFPToInt(cUnit, inst); break;
2993 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
2994 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
2995 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07002996
buzbee101305f2012-06-28 18:00:56 -07002997 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
2998 break;
2999 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3000 break;
3001
buzbee32412962012-06-26 16:27:56 -07003002 case llvm::Instruction::Unreachable:
3003 break; // FIXME: can we really ignore these?
3004
buzbee2cfc6392012-05-07 14:51:40 -07003005 case llvm::Instruction::Invoke:
buzbee2cfc6392012-05-07 14:51:40 -07003006 case llvm::Instruction::FPToUI:
buzbee2cfc6392012-05-07 14:51:40 -07003007 case llvm::Instruction::UIToFP:
buzbee2cfc6392012-05-07 14:51:40 -07003008 case llvm::Instruction::PtrToInt:
3009 case llvm::Instruction::IntToPtr:
3010 case llvm::Instruction::Switch:
3011 case llvm::Instruction::FCmp:
buzbee2cfc6392012-05-07 14:51:40 -07003012 case llvm::Instruction::URem:
3013 case llvm::Instruction::UDiv:
3014 case llvm::Instruction::Resume:
buzbee2cfc6392012-05-07 14:51:40 -07003015 case llvm::Instruction::Alloca:
3016 case llvm::Instruction::GetElementPtr:
3017 case llvm::Instruction::Fence:
3018 case llvm::Instruction::AtomicCmpXchg:
3019 case llvm::Instruction::AtomicRMW:
3020 case llvm::Instruction::BitCast:
3021 case llvm::Instruction::VAArg:
3022 case llvm::Instruction::Select:
3023 case llvm::Instruction::UserOp1:
3024 case llvm::Instruction::UserOp2:
3025 case llvm::Instruction::ExtractElement:
3026 case llvm::Instruction::InsertElement:
3027 case llvm::Instruction::ShuffleVector:
3028 case llvm::Instruction::ExtractValue:
3029 case llvm::Instruction::InsertValue:
3030 case llvm::Instruction::LandingPad:
3031 case llvm::Instruction::IndirectBr:
3032 case llvm::Instruction::Load:
3033 case llvm::Instruction::Store:
3034 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3035
3036 default:
3037 LOG(FATAL) << "Unknown llvm opcode: " << opcode; break;
3038 }
3039 }
buzbee6969d502012-06-15 16:40:31 -07003040
3041 if (headLIR != NULL) {
3042 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
3043 }
buzbee2cfc6392012-05-07 14:51:40 -07003044 return false;
3045}
3046
3047/*
3048 * Convert LLVM_IR to MIR:
3049 * o Iterate through the LLVM_IR and construct a graph using
3050 * standard MIR building blocks.
3051 * o Perform a basic-block optimization pass to remove unnecessary
3052 * store/load sequences.
3053 * o Convert the LLVM Value operands into RegLocations where applicable.
3054 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3055 * o Perform register promotion
3056 * o Iterate through the graph a basic block at a time, generating
3057 * LIR.
3058 * o Assemble LIR as usual.
3059 * o Profit.
3060 */
3061void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3062{
buzbeead8f15e2012-06-18 14:49:45 -07003063 llvm::Function* func = cUnit->func;
3064 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003065 // Allocate a list for LIR basic block labels
3066 cUnit->blockLabelList =
3067 (void*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3068 LIR* labelList = (LIR*)cUnit->blockLabelList;
3069 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003070 for (llvm::Function::iterator i = func->begin(),
3071 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003072 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3073 &labelList[nextLabel++]);
3074 }
buzbeead8f15e2012-06-18 14:49:45 -07003075
3076 /*
3077 * Keep honest - clear regLocations, Value => RegLocation,
3078 * promotion map and VmapTables.
3079 */
3080 cUnit->locMap.clear(); // Start fresh
3081 cUnit->regLocation = NULL;
3082 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3083 i++) {
3084 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3085 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3086 }
3087 cUnit->coreSpillMask = 0;
3088 cUnit->numCoreSpills = 0;
3089 cUnit->fpSpillMask = 0;
3090 cUnit->numFPSpills = 0;
3091 cUnit->coreVmapTable.clear();
3092 cUnit->fpVmapTable.clear();
3093 oatAdjustSpillMask(cUnit);
3094 cUnit->frameSize = oatComputeFrameSize(cUnit);
3095
3096 /*
3097 * At this point, we've lost all knowledge of register promotion.
3098 * Rebuild that info from the MethodInfo intrinsic (if it
3099 * exists - not required for correctness).
3100 */
3101 // TODO: find and recover MethodInfo.
3102
3103 // Create RegLocations for arguments
3104 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3105 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3106 for (; it != it_end; ++it) {
3107 llvm::Value* val = it;
3108 createLocFromValue(cUnit, val);
3109 }
3110 // Create RegLocations for all non-argument defintions
3111 for (llvm::inst_iterator i = llvm::inst_begin(func),
3112 e = llvm::inst_end(func); i != e; ++i) {
3113 llvm::Value* val = &*i;
3114 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3115 createLocFromValue(cUnit, val);
3116 }
3117 }
3118
buzbee2cfc6392012-05-07 14:51:40 -07003119 // Walk the blocks, generating code.
3120 for (llvm::Function::iterator i = cUnit->func->begin(),
3121 e = cUnit->func->end(); i != e; ++i) {
3122 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3123 }
3124
3125 handleSuspendLaunchpads(cUnit);
3126
3127 handleThrowLaunchpads(cUnit);
3128
3129 handleIntrinsicLaunchpads(cUnit);
3130
3131 freeIR(cUnit);
3132}
3133
3134
3135} // namespace art
3136
3137#endif // ART_USE_QUICK_COMPILER