blob: 690f022bddc19e518c1c4ef05b3dfceebc5b9f40 [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
buzbee2cfc6392012-05-07 14:51:40 -0700164llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
165 RegLocation loc)
166{
167 greenland::IntrinsicHelper::IntrinsicId id;
168 if (loc.wide) {
169 if (loc.fp) {
170 id = greenland::IntrinsicHelper::ConstDouble;
171 } else {
172 id = greenland::IntrinsicHelper::ConstLong;
173 }
174 } else {
175 if (loc.fp) {
176 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700177 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700178 id = greenland::IntrinsicHelper::ConstObj;
179 } else {
180 id = greenland::IntrinsicHelper::ConstInt;
181 }
182 }
183 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
184 return cUnit->irb->CreateCall(intr, src);
185}
buzbeeb03f4872012-06-11 15:22:11 -0700186
187void emitPopShadowFrame(CompilationUnit* cUnit)
188{
189 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
190 greenland::IntrinsicHelper::PopShadowFrame);
191 cUnit->irb->CreateCall(intr);
192}
193
buzbee2cfc6392012-05-07 14:51:40 -0700194llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
195 RegLocation loc)
196{
197 greenland::IntrinsicHelper::IntrinsicId id;
198 if (loc.wide) {
199 if (loc.fp) {
200 id = greenland::IntrinsicHelper::CopyDouble;
201 } else {
202 id = greenland::IntrinsicHelper::CopyLong;
203 }
204 } else {
205 if (loc.fp) {
206 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700207 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700208 id = greenland::IntrinsicHelper::CopyObj;
209 } else {
210 id = greenland::IntrinsicHelper::CopyInt;
211 }
212 }
213 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
214 return cUnit->irb->CreateCall(intr, src);
215}
216
buzbee32412962012-06-26 16:27:56 -0700217void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
218{
219 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
220 greenland::IntrinsicHelper::GetException);
221 llvm::Value* res = cUnit->irb->CreateCall(func);
222 defineValue(cUnit, res, rlDest.origSReg);
223}
224
225void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
226{
227 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
228 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
229 greenland::IntrinsicHelper::Throw);
230 cUnit->irb->CreateCall(func, src);
231 cUnit->irb->CreateUnreachable();
232}
233
buzbee8fa0fda2012-06-27 15:44:52 -0700234void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
235 greenland::IntrinsicHelper::IntrinsicId id,
236 RegLocation rlSrc)
237{
238 llvm::SmallVector<llvm::Value*, 2> args;
239 args.push_back(cUnit->irb->getInt32(optFlags));
240 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
241 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
242 cUnit->irb->CreateCall(func, args);
243}
244
245void convertArrayLength(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
246{
247 llvm::SmallVector<llvm::Value*, 2> args;
248 args.push_back(cUnit->irb->getInt32(optFlags));
249 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
250 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
251 greenland::IntrinsicHelper::ArrayLength);
252 cUnit->irb->CreateCall(func, args);
253}
254
buzbee32412962012-06-26 16:27:56 -0700255void convertThrowVerificationError(CompilationUnit* cUnit, int info1, int info2)
256{
257 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
258 greenland::IntrinsicHelper::Throw);
259 llvm::SmallVector<llvm::Value*, 2> args;
260 args.push_back(cUnit->irb->getInt32(info1));
261 args.push_back(cUnit->irb->getInt32(info2));
262 cUnit->irb->CreateCall(func, args);
263 cUnit->irb->CreateUnreachable();
264}
265
buzbee2cfc6392012-05-07 14:51:40 -0700266void emitSuspendCheck(CompilationUnit* cUnit)
267{
268 greenland::IntrinsicHelper::IntrinsicId id =
269 greenland::IntrinsicHelper::CheckSuspend;
270 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
271 cUnit->irb->CreateCall(intr);
272}
273
274llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
275 llvm::Value* src1, llvm::Value* src2)
276{
277 llvm::Value* res = NULL;
278 switch(cc) {
279 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
280 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
281 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
282 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
283 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
284 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
285 default: LOG(FATAL) << "Unexpected cc value " << cc;
286 }
287 return res;
288}
289
290void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
291 ConditionCode cc, RegLocation rlSrc1,
292 RegLocation rlSrc2)
293{
294 if (bb->taken->startOffset <= mir->offset) {
295 emitSuspendCheck(cUnit);
296 }
297 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
298 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
299 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
300 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
301 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
302 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700303 // Don't redo the fallthrough branch in the BB driver
304 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700305}
306
307void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
308 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
309{
310 if (bb->taken->startOffset <= mir->offset) {
311 emitSuspendCheck(cUnit);
312 }
313 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
314 llvm::Value* src2;
315 if (rlSrc1.ref) {
316 src2 = cUnit->irb->GetJNull();
317 } else {
318 src2 = cUnit->irb->getInt32(0);
319 }
320 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
321 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
322 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
323 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700324 // Don't redo the fallthrough branch in the BB driver
325 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700326}
327
328llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
329 llvm::Value* src1, llvm::Value* src2)
330{
331 greenland::IntrinsicHelper::IntrinsicId id;
332 if (isLong) {
333 if (isDiv) {
334 id = greenland::IntrinsicHelper::DivLong;
335 } else {
336 id = greenland::IntrinsicHelper::RemLong;
337 }
338 } else if (isDiv) {
339 id = greenland::IntrinsicHelper::DivInt;
340 } else {
341 id = greenland::IntrinsicHelper::RemInt;
342 }
343 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
344 llvm::SmallVector<llvm::Value*, 2>args;
345 args.push_back(src1);
346 args.push_back(src2);
347 return cUnit->irb->CreateCall(intr, args);
348}
349
350llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
351 llvm::Value* src1, llvm::Value* src2)
352{
353 llvm::Value* res = NULL;
354 switch(op) {
355 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
356 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700357 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700358 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
359 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
360 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
361 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
362 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
363 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700364 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
365 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
366 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700367 default:
368 LOG(FATAL) << "Invalid op " << op;
369 }
370 return res;
371}
372
373void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
374 RegLocation rlSrc1, RegLocation rlSrc2)
375{
376 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
377 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
378 llvm::Value* res = NULL;
buzbee4f1181f2012-06-22 13:52:12 -0700379LOG(INFO) << "in convertFPArithOp";
buzbee2cfc6392012-05-07 14:51:40 -0700380 switch(op) {
381 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
382 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
383 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
384 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
385 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
386 default:
387 LOG(FATAL) << "Invalid op " << op;
388 }
389 defineValue(cUnit, res, rlDest.origSReg);
390}
391
buzbee4f1181f2012-06-22 13:52:12 -0700392void convertShift(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
393 RegLocation rlSrc1, RegLocation rlSrc2)
394{
395 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
396 llvm::Value* src2a = getLLVMValue(cUnit, rlSrc2.origSReg);
397 llvm::Value* src2b;
398 // Limit shift counnt to 63 for long and 31 for int
399 if (rlDest.wide) {
400 // Note: creates 2 unnamed temps
401 llvm::Value* t1 = cUnit->irb->CreateAnd(src2a, 0x3f);
402 src2b = cUnit->irb->CreateZExt(t1, cUnit->irb->getInt64Ty());
403 } else {
404 // Note: creates 1 unnamed temp
405 src2b = cUnit->irb->CreateAnd(src2a, 0x1f);
406 }
407 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2b);
408 defineValue(cUnit, res, rlDest.origSReg);
409}
410
buzbee2cfc6392012-05-07 14:51:40 -0700411void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
412 RegLocation rlSrc1, RegLocation rlSrc2)
413{
414 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
415 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
416 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
417 defineValue(cUnit, res, rlDest.origSReg);
418}
419
buzbeeb03f4872012-06-11 15:22:11 -0700420void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
421{
422 int index = -1;
423 DCHECK(newVal != NULL);
424 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
425 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
426 if (cUnit->shadowMap[i] == vReg) {
427 index = i;
428 break;
429 }
430 }
Elliott Hughes74847412012-06-20 18:10:21 -0700431 DCHECK_NE(index, -1) << "Corrupt shadowMap";
buzbeeb03f4872012-06-11 15:22:11 -0700432 greenland::IntrinsicHelper::IntrinsicId id =
433 greenland::IntrinsicHelper::SetShadowFrameEntry;
434 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
435 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
436 llvm::Value* args[] = { newVal, tableSlot };
437 cUnit->irb->CreateCall(func, args);
438}
439
buzbee2cfc6392012-05-07 14:51:40 -0700440void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
441 RegLocation rlSrc1, int32_t imm)
442{
443 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
444 llvm::Value* src2 = cUnit->irb->getInt32(imm);
445 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
446 defineValue(cUnit, res, rlDest.origSReg);
447}
448
buzbee6969d502012-06-15 16:40:31 -0700449void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
450 InvokeType invokeType, bool isRange)
451{
452 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
453 llvm::SmallVector<llvm::Value*, 10> args;
454 // Insert the invokeType
455 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
456 // Insert the method_idx
457 args.push_back(cUnit->irb->getInt32(info->index));
458 // Insert the optimization flags
459 args.push_back(cUnit->irb->getInt32(info->optFlags));
460 // Now, insert the actual arguments
461 if (cUnit->printMe) {
462 LOG(INFO) << "Building Invoke info";
463 }
464 for (int i = 0; i < info->numArgWords;) {
465 if (cUnit->printMe) {
466 oatDumpRegLoc(info->args[i]);
467 }
468 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
469 args.push_back(val);
470 i += info->args[i].wide ? 2 : 1;
471 }
472 /*
473 * Choose the invoke return type based on actual usage. Note: may
474 * be different than shorty. For example, if a function return value
475 * is not used, we'll treat this as a void invoke.
476 */
477 greenland::IntrinsicHelper::IntrinsicId id;
478 if (info->result.location == kLocInvalid) {
479 id = greenland::IntrinsicHelper::HLInvokeVoid;
480 } else {
481 if (info->result.wide) {
482 if (info->result.fp) {
483 id = greenland::IntrinsicHelper::HLInvokeDouble;
484 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700485 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700486 }
487 } else if (info->result.ref) {
488 id = greenland::IntrinsicHelper::HLInvokeObj;
489 } else if (info->result.fp) {
490 id = greenland::IntrinsicHelper::HLInvokeFloat;
491 } else {
492 id = greenland::IntrinsicHelper::HLInvokeInt;
493 }
494 }
495 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
496 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
497 if (info->result.location != kLocInvalid) {
498 defineValue(cUnit, res, info->result.origSReg);
499 }
500}
501
502void convertConstString(CompilationUnit* cUnit, BasicBlock* bb,
503 uint32_t string_idx, RegLocation rlDest)
504{
505 greenland::IntrinsicHelper::IntrinsicId id;
506 id = greenland::IntrinsicHelper::ConstString;
507 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
508 llvm::Value* index = cUnit->irb->getInt32(string_idx);
509 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
510 defineValue(cUnit, res, rlDest.origSReg);
511}
512
buzbee8fa0fda2012-06-27 15:44:52 -0700513void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
514 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700515{
516 greenland::IntrinsicHelper::IntrinsicId id;
517 id = greenland::IntrinsicHelper::NewInstance;
518 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
519 llvm::Value* index = cUnit->irb->getInt32(type_idx);
520 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
521 defineValue(cUnit, res, rlDest.origSReg);
522}
523
buzbee8fa0fda2012-06-27 15:44:52 -0700524void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
525 RegLocation rlDest, RegLocation rlSrc)
526{
527 greenland::IntrinsicHelper::IntrinsicId id;
528 id = greenland::IntrinsicHelper::NewArray;
529 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
530 llvm::SmallVector<llvm::Value*, 2> args;
531 args.push_back(cUnit->irb->getInt32(type_idx));
532 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
533 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
534 defineValue(cUnit, res, rlDest.origSReg);
535}
536
537void convertAget(CompilationUnit* cUnit, int optFlags,
538 greenland::IntrinsicHelper::IntrinsicId id,
539 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
540{
541 llvm::SmallVector<llvm::Value*, 3> args;
542 args.push_back(cUnit->irb->getInt32(optFlags));
543 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
544 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
545 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
546 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
547 defineValue(cUnit, res, rlDest.origSReg);
548}
549
550void convertAput(CompilationUnit* cUnit, int optFlags,
551 greenland::IntrinsicHelper::IntrinsicId id,
552 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
553{
554 llvm::SmallVector<llvm::Value*, 4> args;
555 args.push_back(cUnit->irb->getInt32(optFlags));
556 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
557 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
558 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
559 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
560 cUnit->irb->CreateCall(intr, args);
561}
562
563void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
564 RegLocation rlDest, RegLocation rlSrc)
565{
566 greenland::IntrinsicHelper::IntrinsicId id;
567 id = greenland::IntrinsicHelper::InstanceOf;
568 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
569 llvm::SmallVector<llvm::Value*, 2> args;
570 args.push_back(cUnit->irb->getInt32(type_idx));
571 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
572 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
573 defineValue(cUnit, res, rlDest.origSReg);
574}
575
buzbee2cfc6392012-05-07 14:51:40 -0700576/*
577 * Target-independent code generation. Use only high-level
578 * load/store utilities here, or target-dependent genXX() handlers
579 * when necessary.
580 */
581bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
582 llvm::BasicBlock* llvmBB, LIR* labelList)
583{
584 bool res = false; // Assume success
585 RegLocation rlSrc[3];
586 RegLocation rlDest = badLoc;
587 RegLocation rlResult = badLoc;
588 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee32412962012-06-26 16:27:56 -0700589 uint32_t vA = mir->dalvikInsn.vA;
buzbee6969d502012-06-15 16:40:31 -0700590 uint32_t vB = mir->dalvikInsn.vB;
591 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700592 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700593
buzbeeb03f4872012-06-11 15:22:11 -0700594 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700595
596 /* Prep Src and Dest locations */
597 int nextSreg = 0;
598 int nextLoc = 0;
599 int attrs = oatDataFlowAttributes[opcode];
600 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
601 if (attrs & DF_UA) {
602 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700603 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700604 nextSreg+= 2;
605 } else {
606 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
607 nextSreg++;
608 }
609 }
610 if (attrs & DF_UB) {
611 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700612 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700613 nextSreg+= 2;
614 } else {
615 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
616 nextSreg++;
617 }
618 }
619 if (attrs & DF_UC) {
620 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700621 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700622 } else {
623 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
624 }
625 }
626 if (attrs & DF_DA) {
627 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700628 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700629 } else {
buzbee15bf9802012-06-12 17:49:27 -0700630 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700631 if (rlDest.ref) {
632 objectDefinition = true;
633 }
buzbee2cfc6392012-05-07 14:51:40 -0700634 }
635 }
636
637 switch (opcode) {
638 case Instruction::NOP:
639 break;
640
641 case Instruction::MOVE:
642 case Instruction::MOVE_OBJECT:
643 case Instruction::MOVE_16:
644 case Instruction::MOVE_OBJECT_16:
645 case Instruction::MOVE_FROM16:
646 case Instruction::MOVE_WIDE:
647 case Instruction::MOVE_WIDE_16:
648 case Instruction::MOVE_WIDE_FROM16: {
649 /*
650 * Moves/copies are meaningless in pure SSA register form,
651 * but we need to preserve them for the conversion back into
652 * MIR (at least until we stop using the Dalvik register maps).
653 * Insert a dummy intrinsic copy call, which will be recognized
654 * by the quick path and removed by the portable path.
655 */
656 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
657 llvm::Value* res = emitCopy(cUnit, src, rlDest);
658 defineValue(cUnit, res, rlDest.origSReg);
659 }
660 break;
661
662 case Instruction::CONST:
663 case Instruction::CONST_4:
664 case Instruction::CONST_16: {
buzbee6969d502012-06-15 16:40:31 -0700665 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700666 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
667 defineValue(cUnit, res, rlDest.origSReg);
668 }
669 break;
670
671 case Instruction::CONST_WIDE_16:
672 case Instruction::CONST_WIDE_32: {
buzbee6969d502012-06-15 16:40:31 -0700673 llvm::Constant* immValue = cUnit->irb->GetJLong(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700674 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
675 defineValue(cUnit, res, rlDest.origSReg);
676 }
677 break;
678
679 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700680 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700681 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
682 defineValue(cUnit, res, rlDest.origSReg);
683 }
684 break;
685
686 case Instruction::CONST_WIDE: {
687 llvm::Constant* immValue =
688 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
689 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
690 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700691 }
692 break;
buzbee2cfc6392012-05-07 14:51:40 -0700693 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700694 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700695 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
696 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
697 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700698 }
699 break;
700
buzbee8fa0fda2012-06-27 15:44:52 -0700701 case Instruction::SPUT_OBJECT:
702 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
703 rlSrc[0]);
704 break;
705 case Instruction::SPUT:
706 if (rlSrc[0].fp) {
707 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
708 rlSrc[0]);
709 } else {
710 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
711 }
712 break;
713 case Instruction::SPUT_BOOLEAN:
714 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
715 rlSrc[0]);
716 break;
717 case Instruction::SPUT_BYTE:
718 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
719 break;
720 case Instruction::SPUT_CHAR:
721 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
722 break;
723 case Instruction::SPUT_SHORT:
724 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
725 break;
726 case Instruction::SPUT_WIDE:
727 if (rlSrc[0].fp) {
728 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
729 rlSrc[0]);
730 } else {
731 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
732 rlSrc[0]);
733 }
734 break;
735
736 case Instruction::SGET_OBJECT:
737 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
738 break;
739 case Instruction::SGET:
740 if (rlDest.fp) {
741 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
742 } else {
743 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
744 }
745 break;
746 case Instruction::SGET_BOOLEAN:
747 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
748 break;
749 case Instruction::SGET_BYTE:
750 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
751 break;
752 case Instruction::SGET_CHAR:
753 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
754 break;
755 case Instruction::SGET_SHORT:
756 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
757 break;
758 case Instruction::SGET_WIDE:
759 if (rlDest.fp) {
760 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
761 rlDest);
762 } else {
763 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -0700764 }
765 break;
buzbee2cfc6392012-05-07 14:51:40 -0700766
767 case Instruction::RETURN_WIDE:
768 case Instruction::RETURN:
769 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -0700770 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700771 emitSuspendCheck(cUnit);
772 }
buzbeeb03f4872012-06-11 15:22:11 -0700773 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700774 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
775 bb->hasReturn = true;
776 }
777 break;
778
779 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -0700780 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700781 emitSuspendCheck(cUnit);
782 }
buzbeeb03f4872012-06-11 15:22:11 -0700783 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700784 cUnit->irb->CreateRetVoid();
785 bb->hasReturn = true;
786 }
787 break;
788
789 case Instruction::IF_EQ:
790 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
791 break;
792 case Instruction::IF_NE:
793 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
794 break;
795 case Instruction::IF_LT:
796 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
797 break;
798 case Instruction::IF_GE:
799 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
800 break;
801 case Instruction::IF_GT:
802 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
803 break;
804 case Instruction::IF_LE:
805 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
806 break;
807 case Instruction::IF_EQZ:
808 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
809 break;
810 case Instruction::IF_NEZ:
811 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
812 break;
813 case Instruction::IF_LTZ:
814 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
815 break;
816 case Instruction::IF_GEZ:
817 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
818 break;
819 case Instruction::IF_GTZ:
820 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
821 break;
822 case Instruction::IF_LEZ:
823 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
824 break;
825
826 case Instruction::GOTO:
827 case Instruction::GOTO_16:
828 case Instruction::GOTO_32: {
829 if (bb->taken->startOffset <= bb->startOffset) {
830 emitSuspendCheck(cUnit);
831 }
832 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
833 }
834 break;
835
836 case Instruction::ADD_LONG:
837 case Instruction::ADD_LONG_2ADDR:
838 case Instruction::ADD_INT:
839 case Instruction::ADD_INT_2ADDR:
840 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
841 break;
842 case Instruction::SUB_LONG:
843 case Instruction::SUB_LONG_2ADDR:
844 case Instruction::SUB_INT:
845 case Instruction::SUB_INT_2ADDR:
846 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
847 break;
848 case Instruction::MUL_LONG:
849 case Instruction::MUL_LONG_2ADDR:
850 case Instruction::MUL_INT:
851 case Instruction::MUL_INT_2ADDR:
852 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
853 break;
854 case Instruction::DIV_LONG:
855 case Instruction::DIV_LONG_2ADDR:
856 case Instruction::DIV_INT:
857 case Instruction::DIV_INT_2ADDR:
858 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
859 break;
860 case Instruction::REM_LONG:
861 case Instruction::REM_LONG_2ADDR:
862 case Instruction::REM_INT:
863 case Instruction::REM_INT_2ADDR:
864 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
865 break;
866 case Instruction::AND_LONG:
867 case Instruction::AND_LONG_2ADDR:
868 case Instruction::AND_INT:
869 case Instruction::AND_INT_2ADDR:
870 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
871 break;
872 case Instruction::OR_LONG:
873 case Instruction::OR_LONG_2ADDR:
874 case Instruction::OR_INT:
875 case Instruction::OR_INT_2ADDR:
876 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
877 break;
878 case Instruction::XOR_LONG:
879 case Instruction::XOR_LONG_2ADDR:
880 case Instruction::XOR_INT:
881 case Instruction::XOR_INT_2ADDR:
882 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
883 break;
884 case Instruction::SHL_LONG:
885 case Instruction::SHL_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700886 convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
887 break;
buzbee2cfc6392012-05-07 14:51:40 -0700888 case Instruction::SHL_INT:
889 case Instruction::SHL_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700890 convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -0700891 break;
892 case Instruction::SHR_LONG:
893 case Instruction::SHR_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700894 convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
895 break;
buzbee2cfc6392012-05-07 14:51:40 -0700896 case Instruction::SHR_INT:
897 case Instruction::SHR_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700898 convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -0700899 break;
900 case Instruction::USHR_LONG:
901 case Instruction::USHR_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700902 convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
903 break;
buzbee2cfc6392012-05-07 14:51:40 -0700904 case Instruction::USHR_INT:
905 case Instruction::USHR_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -0700906 convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -0700907 break;
908
909 case Instruction::ADD_INT_LIT16:
910 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700911 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700912 break;
913 case Instruction::RSUB_INT:
914 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700915 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700916 break;
917 case Instruction::MUL_INT_LIT16:
918 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700919 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700920 break;
921 case Instruction::DIV_INT_LIT16:
922 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700923 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700924 break;
925 case Instruction::REM_INT_LIT16:
926 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700927 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700928 break;
929 case Instruction::AND_INT_LIT16:
930 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700931 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700932 break;
933 case Instruction::OR_INT_LIT16:
934 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700935 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700936 break;
937 case Instruction::XOR_INT_LIT16:
938 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700939 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700940 break;
941 case Instruction::SHL_INT_LIT8:
buzbee4f1181f2012-06-22 13:52:12 -0700942 convertArithOpLit(cUnit, kOpLsl, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -0700943 break;
944 case Instruction::SHR_INT_LIT8:
buzbee4f1181f2012-06-22 13:52:12 -0700945 convertArithOpLit(cUnit, kOpLsr, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -0700946 break;
947 case Instruction::USHR_INT_LIT8:
buzbee4f1181f2012-06-22 13:52:12 -0700948 convertArithOpLit(cUnit, kOpAsr, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -0700949 break;
950
951 case Instruction::ADD_FLOAT:
952 case Instruction::ADD_FLOAT_2ADDR:
953 case Instruction::ADD_DOUBLE:
954 case Instruction::ADD_DOUBLE_2ADDR:
955 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
956 break;
957
958 case Instruction::SUB_FLOAT:
959 case Instruction::SUB_FLOAT_2ADDR:
960 case Instruction::SUB_DOUBLE:
961 case Instruction::SUB_DOUBLE_2ADDR:
962 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
963 break;
964
965 case Instruction::MUL_FLOAT:
966 case Instruction::MUL_FLOAT_2ADDR:
967 case Instruction::MUL_DOUBLE:
968 case Instruction::MUL_DOUBLE_2ADDR:
969 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
970 break;
971
972 case Instruction::DIV_FLOAT:
973 case Instruction::DIV_FLOAT_2ADDR:
974 case Instruction::DIV_DOUBLE:
975 case Instruction::DIV_DOUBLE_2ADDR:
976 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
977 break;
978
979 case Instruction::REM_FLOAT:
980 case Instruction::REM_FLOAT_2ADDR:
981 case Instruction::REM_DOUBLE:
982 case Instruction::REM_DOUBLE_2ADDR:
983 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
984 break;
985
buzbee6969d502012-06-15 16:40:31 -0700986 case Instruction::INVOKE_STATIC:
987 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/);
988 break;
989 case Instruction::INVOKE_STATIC_RANGE:
990 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/);
991 break;
992
993 case Instruction::INVOKE_DIRECT:
994 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/);
995 break;
996 case Instruction::INVOKE_DIRECT_RANGE:
997 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/);
998 break;
999
1000 case Instruction::INVOKE_VIRTUAL:
1001 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/);
1002 break;
1003 case Instruction::INVOKE_VIRTUAL_RANGE:
1004 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/);
1005 break;
1006
1007 case Instruction::INVOKE_SUPER:
1008 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/);
1009 break;
1010 case Instruction::INVOKE_SUPER_RANGE:
1011 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/);
1012 break;
1013
1014 case Instruction::INVOKE_INTERFACE:
1015 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/);
1016 break;
1017 case Instruction::INVOKE_INTERFACE_RANGE:
1018 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/);
1019 break;
1020
1021 case Instruction::CONST_STRING:
1022 case Instruction::CONST_STRING_JUMBO:
1023 convertConstString(cUnit, bb, vB, rlDest);
1024 break;
1025
buzbee4f1181f2012-06-22 13:52:12 -07001026 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001027 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001028 break;
1029
buzbee32412962012-06-26 16:27:56 -07001030 case Instruction::MOVE_EXCEPTION:
1031 convertMoveException(cUnit, rlDest);
1032 break;
1033
1034 case Instruction::THROW:
1035 convertThrow(cUnit, rlSrc[0]);
1036 break;
1037
1038 case Instruction::THROW_VERIFICATION_ERROR:
1039 convertThrowVerificationError(cUnit, vA, vB);
1040 break;
buzbee6969d502012-06-15 16:40:31 -07001041
buzbee2cfc6392012-05-07 14:51:40 -07001042 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001043 case Instruction::MOVE_RESULT:
1044 case Instruction::MOVE_RESULT_OBJECT:
buzbee8fa0fda2012-06-27 15:44:52 -07001045 CHECK(false) << "Unexpected MOVE_RESULT";
buzbee2cfc6392012-05-07 14:51:40 -07001046 break;
1047
1048 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001049 convertMonitorEnterExit(cUnit, optFlags,
1050 greenland::IntrinsicHelper::MonitorEnter,
1051 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001052 break;
1053
1054 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001055 convertMonitorEnterExit(cUnit, optFlags,
1056 greenland::IntrinsicHelper::MonitorExit,
1057 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001058 break;
1059
1060 case Instruction::ARRAY_LENGTH:
buzbee8fa0fda2012-06-27 15:44:52 -07001061 convertArrayLength(cUnit, optFlags, rlSrc[0]);
1062 break;
1063
1064 case Instruction::NEW_ARRAY:
1065 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1066 break;
1067
1068 case Instruction::INSTANCE_OF:
1069 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1070 break;
1071
1072 case Instruction::AGET:
1073 if (rlDest.fp) {
1074 convertAget(cUnit, optFlags,
1075 greenland::IntrinsicHelper::HLArrayGetFloat,
1076 rlDest, rlSrc[0], rlSrc[1]);
1077 } else {
1078 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1079 rlDest, rlSrc[0], rlSrc[1]);
1080 }
1081 break;
1082 case Instruction::AGET_OBJECT:
1083 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1084 rlDest, rlSrc[0], rlSrc[1]);
1085 break;
1086 case Instruction::AGET_BOOLEAN:
1087 convertAget(cUnit, optFlags,
1088 greenland::IntrinsicHelper::HLArrayGetBoolean,
1089 rlDest, rlSrc[0], rlSrc[1]);
1090 break;
1091 case Instruction::AGET_BYTE:
1092 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1093 rlDest, rlSrc[0], rlSrc[1]);
1094 break;
1095 case Instruction::AGET_CHAR:
1096 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1097 rlDest, rlSrc[0], rlSrc[1]);
1098 break;
1099 case Instruction::AGET_SHORT:
1100 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1101 rlDest, rlSrc[0], rlSrc[1]);
1102 break;
1103 case Instruction::AGET_WIDE:
1104 if (rlDest.fp) {
1105 convertAget(cUnit, optFlags,
1106 greenland::IntrinsicHelper::HLArrayGetDouble,
1107 rlDest, rlSrc[0], rlSrc[1]);
1108 } else {
1109 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1110 rlDest, rlSrc[0], rlSrc[1]);
1111 }
1112 break;
1113
1114 case Instruction::APUT:
1115 if (rlSrc[0].fp) {
1116 convertAput(cUnit, optFlags,
1117 greenland::IntrinsicHelper::HLArrayPutFloat,
1118 rlSrc[0], rlSrc[1], rlSrc[2]);
1119 } else {
1120 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1121 rlSrc[0], rlSrc[1], rlSrc[2]);
1122 }
1123 break;
1124 case Instruction::APUT_OBJECT:
1125 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1126 rlSrc[0], rlSrc[1], rlSrc[2]);
1127 break;
1128 case Instruction::APUT_BOOLEAN:
1129 convertAput(cUnit, optFlags,
1130 greenland::IntrinsicHelper::HLArrayPutBoolean,
1131 rlSrc[0], rlSrc[1], rlSrc[2]);
1132 break;
1133 case Instruction::APUT_BYTE:
1134 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1135 rlSrc[0], rlSrc[1], rlSrc[2]);
1136 break;
1137 case Instruction::APUT_CHAR:
1138 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1139 rlSrc[0], rlSrc[1], rlSrc[2]);
1140 break;
1141 case Instruction::APUT_SHORT:
1142 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1143 rlSrc[0], rlSrc[1], rlSrc[2]);
1144 break;
1145 case Instruction::APUT_WIDE:
1146 if (rlSrc[0].fp) {
1147 convertAput(cUnit, optFlags,
1148 greenland::IntrinsicHelper::HLArrayPutDouble,
1149 rlSrc[0], rlSrc[1], rlSrc[2]);
1150 } else {
1151 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1152 rlSrc[0], rlSrc[1], rlSrc[2]);
1153 }
1154 break;
1155
1156#if 0
1157
1158 case Instruction::CHECK_CAST:
1159 genCheckCast(cUnit, mir, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001160 break;
1161
buzbee2cfc6392012-05-07 14:51:40 -07001162 case Instruction::CONST_CLASS:
1163 genConstClass(cUnit, mir, rlDest, rlSrc[0]);
1164 break;
1165
1166 case Instruction::FILL_ARRAY_DATA:
1167 genFillArrayData(cUnit, mir, rlSrc[0]);
1168 break;
1169
buzbee2cfc6392012-05-07 14:51:40 -07001170 case Instruction::FILLED_NEW_ARRAY_RANGE:
1171 genFilledNewArray(cUnit, mir, true /* range */);
1172 break;
1173
buzbee2cfc6392012-05-07 14:51:40 -07001174 case Instruction::PACKED_SWITCH:
1175 genPackedSwitch(cUnit, mir, rlSrc[0]);
1176 break;
1177
1178 case Instruction::SPARSE_SWITCH:
1179 genSparseSwitch(cUnit, mir, rlSrc[0], labelList);
1180 break;
1181
1182 case Instruction::CMPL_FLOAT:
1183 case Instruction::CMPG_FLOAT:
1184 case Instruction::CMPL_DOUBLE:
1185 case Instruction::CMPG_DOUBLE:
1186 res = genCmpFP(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
1187 break;
1188
1189 case Instruction::CMP_LONG:
1190 genCmpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
1191 break;
1192
buzbee2cfc6392012-05-07 14:51:40 -07001193 case Instruction::IGET_OBJECT:
1194 //case Instruction::IGET_OBJECT_VOLATILE:
1195 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, true);
1196 break;
1197
1198 case Instruction::IGET_WIDE:
1199 //case Instruction::IGET_WIDE_VOLATILE:
1200 genIGet(cUnit, mir, kLong, rlDest, rlSrc[0], true, false);
1201 break;
1202
1203 case Instruction::IGET:
1204 //case Instruction::IGET_VOLATILE:
1205 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, false);
1206 break;
1207
1208 case Instruction::IGET_CHAR:
1209 genIGet(cUnit, mir, kUnsignedHalf, rlDest, rlSrc[0], false, false);
1210 break;
1211
1212 case Instruction::IGET_SHORT:
1213 genIGet(cUnit, mir, kSignedHalf, rlDest, rlSrc[0], false, false);
1214 break;
1215
1216 case Instruction::IGET_BOOLEAN:
1217 case Instruction::IGET_BYTE:
1218 genIGet(cUnit, mir, kUnsignedByte, rlDest, rlSrc[0], false, false);
1219 break;
1220
1221 case Instruction::IPUT_WIDE:
1222 //case Instruction::IPUT_WIDE_VOLATILE:
1223 genIPut(cUnit, mir, kLong, rlSrc[0], rlSrc[1], true, false);
1224 break;
1225
1226 case Instruction::IPUT_OBJECT:
1227 //case Instruction::IPUT_OBJECT_VOLATILE:
1228 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, true);
1229 break;
1230
1231 case Instruction::IPUT:
1232 //case Instruction::IPUT_VOLATILE:
1233 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, false);
1234 break;
1235
1236 case Instruction::IPUT_BOOLEAN:
1237 case Instruction::IPUT_BYTE:
1238 genIPut(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], false, false);
1239 break;
1240
1241 case Instruction::IPUT_CHAR:
1242 genIPut(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], false, false);
1243 break;
1244
1245 case Instruction::IPUT_SHORT:
1246 genIPut(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
1247 break;
1248
buzbee2cfc6392012-05-07 14:51:40 -07001249 case Instruction::NEG_INT:
1250 case Instruction::NOT_INT:
1251 res = genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1252 break;
1253
1254 case Instruction::NEG_LONG:
1255 case Instruction::NOT_LONG:
1256 res = genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1257 break;
1258
1259 case Instruction::NEG_FLOAT:
1260 res = genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1261 break;
1262
1263 case Instruction::NEG_DOUBLE:
1264 res = genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1265 break;
1266
1267 case Instruction::INT_TO_LONG:
1268 genIntToLong(cUnit, mir, rlDest, rlSrc[0]);
1269 break;
1270
1271 case Instruction::LONG_TO_INT:
1272 rlSrc[0] = oatUpdateLocWide(cUnit, rlSrc[0]);
1273 rlSrc[0] = oatWideToNarrow(cUnit, rlSrc[0]);
1274 storeValue(cUnit, rlDest, rlSrc[0]);
1275 break;
1276
1277 case Instruction::INT_TO_BYTE:
1278 case Instruction::INT_TO_SHORT:
1279 case Instruction::INT_TO_CHAR:
1280 genIntNarrowing(cUnit, mir, rlDest, rlSrc[0]);
1281 break;
1282
1283 case Instruction::INT_TO_FLOAT:
1284 case Instruction::INT_TO_DOUBLE:
1285 case Instruction::LONG_TO_FLOAT:
1286 case Instruction::LONG_TO_DOUBLE:
1287 case Instruction::FLOAT_TO_INT:
1288 case Instruction::FLOAT_TO_LONG:
1289 case Instruction::FLOAT_TO_DOUBLE:
1290 case Instruction::DOUBLE_TO_INT:
1291 case Instruction::DOUBLE_TO_LONG:
1292 case Instruction::DOUBLE_TO_FLOAT:
1293 genConversion(cUnit, mir);
1294 break;
1295
1296#endif
1297
1298 default:
buzbee32412962012-06-26 16:27:56 -07001299 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001300 res = true;
1301 }
buzbeeb03f4872012-06-11 15:22:11 -07001302 if (objectDefinition) {
1303 setShadowFrameEntry(cUnit, (llvm::Value*)
1304 cUnit->llvmValues.elemList[rlDest.origSReg]);
1305 }
buzbee2cfc6392012-05-07 14:51:40 -07001306 return res;
1307}
1308
1309/* Extended MIR instructions like PHI */
1310void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1311 llvm::BasicBlock* llvmBB)
1312{
1313
1314 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1315 case kMirOpPhi: {
1316 int* incoming = (int*)mir->dalvikInsn.vB;
1317 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
1318 llvm::Type* phiType =
1319 llvmTypeFromLocRec(cUnit, rlDest);
1320 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1321 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1322 RegLocation loc;
1323 if (rlDest.wide) {
buzbee15bf9802012-06-12 17:49:27 -07001324 loc = oatGetSrcWide(cUnit, mir, i);
buzbee2cfc6392012-05-07 14:51:40 -07001325 i++;
1326 } else {
1327 loc = oatGetSrc(cUnit, mir, i);
1328 }
1329 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
1330 getLLVMBlock(cUnit, incoming[i]));
1331 }
1332 defineValue(cUnit, phi, rlDest.origSReg);
1333 break;
1334 }
1335 case kMirOpCopy: {
1336 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1337 break;
1338 }
1339#if defined(TARGET_ARM)
1340 case kMirOpFusedCmplFloat:
1341 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1342 break;
1343 case kMirOpFusedCmpgFloat:
1344 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1345 break;
1346 case kMirOpFusedCmplDouble:
1347 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1348 break;
1349 case kMirOpFusedCmpgDouble:
1350 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1351 break;
1352 case kMirOpFusedCmpLong:
1353 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1354 break;
1355#endif
1356 default:
1357 break;
1358 }
1359}
1360
1361void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1362{
1363 cUnit->currentDalvikOffset = offset;
1364 llvm::SmallVector<llvm::Value*, 1>arrayRef;
1365 arrayRef.push_back(cUnit->irb->getInt32(offset));
1366 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1367 cUnit->irb->SetDexOffset(node);
1368}
1369
1370// Attach method info as metadata to special intrinsic
1371void setMethodInfo(CompilationUnit* cUnit)
1372{
1373 // We don't want dex offset on this
1374 cUnit->irb->SetDexOffset(NULL);
1375 greenland::IntrinsicHelper::IntrinsicId id;
1376 id = greenland::IntrinsicHelper::MethodInfo;
1377 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1378 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1379 llvm::SmallVector<llvm::Value*, 2> regInfo;
1380 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1381 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1382 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1383 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1384 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1385 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1386 inst->setMetadata("RegInfo", regInfoNode);
1387 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1388 llvm::SmallVector<llvm::Value*, 50> pmap;
1389 for (int i = 0; i < promoSize; i++) {
1390 PromotionMap* p = &cUnit->promotionMap[i];
1391 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1392 ((p->fpReg & 0xff) << 16) |
1393 ((p->coreReg & 0xff) << 8) |
1394 ((p->fpLocation & 0xf) << 4) |
1395 (p->coreLocation & 0xf);
1396 pmap.push_back(cUnit->irb->getInt32(mapData));
1397 }
1398 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1399 inst->setMetadata("PromotionMap", mapNode);
1400 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1401}
1402
1403/* Handle the content in each basic block */
1404bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1405{
1406 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
1407 cUnit->irb->SetInsertPoint(llvmBB);
1408 setDexOffset(cUnit, bb->startOffset);
1409
1410 if (bb->blockType == kEntryBlock) {
1411 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001412 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1413 cUnit->numDalvikRegisters, true,
1414 kAllocMisc);
1415 for (int i = 0; i < cUnit->numSSARegs; i++) {
1416 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1417 }
1418 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1419 if (canBeRef[i]) {
1420 cUnit->numShadowFrameEntries++;
1421 }
1422 }
1423 if (cUnit->numShadowFrameEntries > 0) {
1424 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1425 cUnit->numShadowFrameEntries, true,
1426 kAllocMisc);
1427 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1428 if (canBeRef[i]) {
1429 cUnit->shadowMap[j++] = i;
1430 }
1431 }
1432 greenland::IntrinsicHelper::IntrinsicId id =
1433 greenland::IntrinsicHelper::AllocaShadowFrame;
1434 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1435 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1436 cUnit->irb->CreateCall(func, entries);
1437 }
buzbee2cfc6392012-05-07 14:51:40 -07001438 } else if (bb->blockType == kExitBlock) {
1439 /*
1440 * Because of the differences between how MIR/LIR and llvm handle exit
1441 * blocks, we won't explicitly covert them. On the llvm-to-lir
1442 * path, it will need to be regenereated.
1443 */
1444 return false;
buzbee6969d502012-06-15 16:40:31 -07001445 } else if (bb->blockType == kExceptionHandling) {
1446 /*
1447 * Because we're deferring null checking, delete the associated empty
1448 * exception block.
1449 * TODO: add new block type for exception blocks that we generate
1450 * greenland code for.
1451 */
1452 llvmBB->eraseFromParent();
1453 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001454 }
1455
1456 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1457
1458 setDexOffset(cUnit, mir->offset);
1459
1460 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
1461 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
1462
1463 /* If we're compiling for the debugger, generate an update callout */
1464 if (cUnit->genDebugger) {
1465 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1466 //genDebuggerUpdate(cUnit, mir->offset);
1467 }
1468
1469 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
1470 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1471 continue;
1472 }
1473
1474 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1475 NULL /* labelList */);
1476 if (notHandled) {
1477 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
1478 mir->offset, dalvikOpcode,
1479 Instruction::Name(dalvikOpcode),
1480 dalvikFormat);
1481 }
1482 }
1483
buzbee6969d502012-06-15 16:40:31 -07001484 if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001485 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1486 }
1487
1488 return false;
1489}
1490
1491llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1492
1493 // Get return type
1494 llvm::Type* ret_type = cUnit->irb->GetJType(cUnit->shorty[0],
1495 greenland::kAccurate);
1496
1497 // Get argument type
1498 std::vector<llvm::Type*> args_type;
1499
1500 // method object
1501 args_type.push_back(cUnit->irb->GetJMethodTy());
1502
1503 // Do we have a "this"?
1504 if ((cUnit->access_flags & kAccStatic) == 0) {
1505 args_type.push_back(cUnit->irb->GetJObjectTy());
1506 }
1507
1508 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
1509 args_type.push_back(cUnit->irb->GetJType(cUnit->shorty[i],
1510 greenland::kAccurate));
1511 }
1512
1513 return llvm::FunctionType::get(ret_type, args_type, false);
1514}
1515
1516bool createFunction(CompilationUnit* cUnit) {
1517 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1518 /* with_signature */ false));
1519 llvm::FunctionType* func_type = getFunctionType(cUnit);
1520
1521 if (func_type == NULL) {
1522 return false;
1523 }
1524
1525 cUnit->func = llvm::Function::Create(func_type,
1526 llvm::Function::ExternalLinkage,
1527 func_name, cUnit->module);
1528
1529 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1530 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1531
1532 arg_iter->setName("method");
1533 ++arg_iter;
1534
1535 int startSReg = cUnit->numRegs;
1536
1537 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1538 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1539 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1540 }
1541
1542 return true;
1543}
1544
1545bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1546{
1547 // Skip the exit block
1548 if (bb->blockType == kExitBlock) {
1549 cUnit->idToBlockMap.Put(bb->id, NULL);
1550 } else {
1551 int offset = bb->startOffset;
1552 bool entryBlock = (bb->blockType == kEntryBlock);
1553 llvm::BasicBlock* llvmBB =
1554 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
Elliott Hughes74847412012-06-20 18:10:21 -07001555 StringPrintf(kLabelFormat, offset, bb->id),
buzbee2cfc6392012-05-07 14:51:40 -07001556 cUnit->func);
1557 if (entryBlock) {
1558 cUnit->entryBB = llvmBB;
1559 cUnit->placeholderBB =
1560 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
1561 cUnit->func);
1562 }
1563 cUnit->idToBlockMap.Put(bb->id, llvmBB);
1564 }
1565 return false;
1566}
1567
1568
1569/*
1570 * Convert MIR to LLVM_IR
1571 * o For each ssa name, create LLVM named value. Type these
1572 * appropriately, and ignore high half of wide and double operands.
1573 * o For each MIR basic block, create an LLVM basic block.
1574 * o Iterate through the MIR a basic block at a time, setting arguments
1575 * to recovered ssa name.
1576 */
1577void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
1578{
1579 initIR(cUnit);
1580 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
1581
1582 // Create the function
1583 createFunction(cUnit);
1584
1585 // Create an LLVM basic block for each MIR block in dfs preorder
1586 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
1587 kPreOrderDFSTraversal, false /* isIterative */);
1588 /*
1589 * Create an llvm named value for each MIR SSA name. Note: we'll use
1590 * placeholders for all non-argument values (because we haven't seen
1591 * the definition yet).
1592 */
1593 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
1594 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1595 arg_iter++; /* Skip path method */
1596 for (int i = 0; i < cUnit->numSSARegs; i++) {
1597 llvm::Value* val;
1598 llvm::Type* ty = llvmTypeFromLocRec(cUnit, cUnit->regLocation[i]);
1599 if (i < cUnit->numRegs) {
1600 // Skip non-argument _0 names - should never be a use
1601 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)0);
1602 } else if (i >= (cUnit->numRegs + cUnit->numIns)) {
1603 // Handle SSA defs, skipping Method* and compiler temps
1604 if (SRegToVReg(cUnit, i) < 0) {
1605 val = NULL;
1606 } else {
1607 val = cUnit->irb->CreateLoad(cUnit->irb->CreateAlloca(ty, 0));
1608 val->setName(llvmSSAName(cUnit, i));
1609 }
1610 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
1611 if (cUnit->regLocation[i].wide) {
1612 // Skip high half of wide values
1613 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
1614 i++;
1615 }
1616 } else {
1617 // Recover previously-created argument values
1618 llvm::Value* argVal = arg_iter++;
1619 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
1620 }
1621 }
1622 cUnit->irb->CreateBr(cUnit->placeholderBB);
1623
1624 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
1625 kPreOrderDFSTraversal, false /* Iterative */);
1626
1627 cUnit->placeholderBB->eraseFromParent();
1628
1629 llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction);
1630
buzbeead8f15e2012-06-18 14:49:45 -07001631 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
1632 // Write bitcode to file
1633 std::string errmsg;
1634 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
1635 oatReplaceSpecialChars(fname);
1636 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07001637 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07001638
buzbeead8f15e2012-06-18 14:49:45 -07001639 llvm::OwningPtr<llvm::tool_output_file> out_file(
1640 new llvm::tool_output_file(fname.c_str(), errmsg,
1641 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07001642
buzbeead8f15e2012-06-18 14:49:45 -07001643 if (!errmsg.empty()) {
1644 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
1645 }
1646
1647 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
1648 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07001649 }
buzbee2cfc6392012-05-07 14:51:40 -07001650}
1651
1652RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
1653 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07001654 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001655 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
1656 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07001657 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07001658 if (valName.empty()) {
buzbee4f1181f2012-06-22 13:52:12 -07001659 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
1660 memset(&res, 0, sizeof(res));
1661 res.location = kLocPhysReg;
1662 res.lowReg = oatAllocTemp(cUnit);
1663 res.home = true;
1664 res.sRegLow = INVALID_SREG;
1665 res.origSReg = INVALID_SREG;
1666 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07001667 } else {
1668 DCHECK_EQ(valName[0], 'v');
1669 int baseSReg = INVALID_SREG;
1670 sscanf(valName.c_str(), "v%d_", &baseSReg);
1671 res = cUnit->regLocation[baseSReg];
1672 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07001673 }
1674 } else {
1675 res = it->second;
1676 }
1677 return res;
1678}
1679
1680Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
1681{
1682 Instruction::Code res = Instruction::NOP;
1683 if (isWide) {
1684 switch(op) {
1685 case kOpAdd: res = Instruction::ADD_LONG; break;
1686 case kOpSub: res = Instruction::SUB_LONG; break;
1687 case kOpMul: res = Instruction::MUL_LONG; break;
1688 case kOpDiv: res = Instruction::DIV_LONG; break;
1689 case kOpRem: res = Instruction::REM_LONG; break;
1690 case kOpAnd: res = Instruction::AND_LONG; break;
1691 case kOpOr: res = Instruction::OR_LONG; break;
1692 case kOpXor: res = Instruction::XOR_LONG; break;
1693 case kOpLsl: res = Instruction::SHL_LONG; break;
1694 case kOpLsr: res = Instruction::USHR_LONG; break;
1695 case kOpAsr: res = Instruction::SHR_LONG; break;
1696 default: LOG(FATAL) << "Unexpected OpKind " << op;
1697 }
1698 } else if (isConst){
1699 switch(op) {
1700 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
1701 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
1702 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
1703 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
1704 case kOpRem: res = Instruction::REM_INT_LIT16; break;
1705 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
1706 case kOpOr: res = Instruction::OR_INT_LIT16; break;
1707 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
1708 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
1709 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
1710 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
1711 default: LOG(FATAL) << "Unexpected OpKind " << op;
1712 }
1713 } else {
1714 switch(op) {
1715 case kOpAdd: res = Instruction::ADD_INT; break;
1716 case kOpSub: res = Instruction::SUB_INT; break;
1717 case kOpMul: res = Instruction::MUL_INT; break;
1718 case kOpDiv: res = Instruction::DIV_INT; break;
1719 case kOpRem: res = Instruction::REM_INT; break;
1720 case kOpAnd: res = Instruction::AND_INT; break;
1721 case kOpOr: res = Instruction::OR_INT; break;
1722 case kOpXor: res = Instruction::XOR_INT; break;
1723 case kOpLsl: res = Instruction::SHL_INT; break;
1724 case kOpLsr: res = Instruction::USHR_INT; break;
1725 case kOpAsr: res = Instruction::SHR_INT; break;
1726 default: LOG(FATAL) << "Unexpected OpKind " << op;
1727 }
1728 }
1729 return res;
1730}
1731
buzbee4f1181f2012-06-22 13:52:12 -07001732Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
1733{
1734 Instruction::Code res = Instruction::NOP;
1735 if (isWide) {
1736 switch(op) {
1737 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
1738 case kOpSub: res = Instruction::SUB_DOUBLE; break;
1739 case kOpMul: res = Instruction::MUL_DOUBLE; break;
1740 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
1741 case kOpRem: res = Instruction::REM_DOUBLE; break;
1742 default: LOG(FATAL) << "Unexpected OpKind " << op;
1743 }
1744 } else {
1745 switch(op) {
1746 case kOpAdd: res = Instruction::ADD_FLOAT; break;
1747 case kOpSub: res = Instruction::SUB_FLOAT; break;
1748 case kOpMul: res = Instruction::MUL_FLOAT; break;
1749 case kOpDiv: res = Instruction::DIV_FLOAT; break;
1750 case kOpRem: res = Instruction::REM_FLOAT; break;
1751 default: LOG(FATAL) << "Unexpected OpKind " << op;
1752 }
1753 }
1754 return res;
1755}
1756
1757void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
1758{
1759 RegLocation rlDest = getLoc(cUnit, inst);
1760 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
1761 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
1762 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
1763 if (rlDest.wide) {
1764 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1765 } else {
1766 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1767 }
1768}
1769
buzbee2cfc6392012-05-07 14:51:40 -07001770void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
1771{
1772 RegLocation rlDest = getLoc(cUnit, inst);
1773 llvm::Value* lhs = inst->getOperand(0);
buzbee4f1181f2012-06-22 13:52:12 -07001774 // Special-case RSUB
1775 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
1776 if ((op == kOpSub) && (lhsImm != NULL)) {
1777 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
1778 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
1779 lhsImm->getSExtValue());
1780 return;
1781 }
1782 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001783 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
1784 llvm::Value* rhs = inst->getOperand(1);
1785 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
1786 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
1787 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, src2->getSExtValue());
1788 } else {
1789 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
1790 RegLocation rlSrc2 = getLoc(cUnit, rhs);
1791 if (rlDest.wide) {
1792 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1793 } else {
1794 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1795 }
1796 }
1797}
1798
1799void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
1800{
1801 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
1802 DCHECK(brInst != NULL);
1803 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
1804 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
1805 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
1806}
1807
1808void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
1809{
1810 // Nop - these have already been processed
1811}
1812
1813void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
1814{
1815 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
1816 llvm::Value* retVal = retInst->getReturnValue();
1817 if (retVal != NULL) {
1818 RegLocation rlSrc = getLoc(cUnit, retVal);
1819 if (rlSrc.wide) {
1820 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
1821 } else {
1822 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
1823 }
1824 }
1825 genExitSequence(cUnit);
1826}
1827
1828ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
1829{
1830 ConditionCode res = kCondAl;
1831 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07001832 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07001833 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
1834 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
1835 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07001836 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07001837 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07001838 default: LOG(FATAL) << "Unexpected llvm condition";
1839 }
1840 return res;
1841}
1842
1843void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
1844{
1845 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
1846 UNIMPLEMENTED(FATAL);
1847}
1848
1849void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
1850 llvm::BranchInst* brInst)
1851{
1852 // Get targets
1853 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
1854 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
1855 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
1856 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
1857 // Get comparison operands
1858 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
1859 ConditionCode cond = getCond(iCmpInst->getPredicate());
1860 llvm::Value* lhs = iCmpInst->getOperand(0);
1861 // Not expecting a constant as 1st operand
1862 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
1863 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
1864 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
1865 llvm::Value* rhs = inst->getOperand(1);
1866#if defined(TARGET_MIPS)
1867 // Compare and branch in one shot
1868 (void)taken;
1869 (void)cond;
1870 (void)rhs;
1871 UNIMPLEMENTED(FATAL);
1872#else
1873 //Compare, then branch
1874 // TODO: handle fused CMP_LONG/IF_xxZ case
1875 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
1876 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
1877 } else {
1878 RegLocation rlSrc2 = getLoc(cUnit, rhs);
1879 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
1880 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
1881 }
1882 opCondBranch(cUnit, cond, taken);
1883#endif
1884 // Fallthrough
1885 opUnconditionalBranch(cUnit, fallThrough);
1886}
1887
1888void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
1889 llvm::Function* callee)
1890{
1891 UNIMPLEMENTED(FATAL);
1892}
1893
buzbee2cfc6392012-05-07 14:51:40 -07001894void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
1895{
buzbee4f1181f2012-06-22 13:52:12 -07001896 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07001897 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
1898 RegLocation rlDest = getLoc(cUnit, callInst);
1899 if (rlSrc.wide) {
1900 storeValueWide(cUnit, rlDest, rlSrc);
1901 } else {
1902 storeValue(cUnit, rlDest, rlSrc);
1903 }
1904}
1905
1906// Note: Immediate arg is a ConstantInt regardless of result type
1907void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
1908{
buzbee4f1181f2012-06-22 13:52:12 -07001909 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07001910 llvm::ConstantInt* src =
1911 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1912 uint64_t immval = src->getZExtValue();
1913 RegLocation rlDest = getLoc(cUnit, callInst);
1914 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
1915 if (rlDest.wide) {
1916 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
1917 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
1918 storeValueWide(cUnit, rlDest, rlResult);
1919 } else {
1920 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
1921 storeValue(cUnit, rlDest, rlResult);
1922 }
1923}
1924
buzbee6969d502012-06-15 16:40:31 -07001925void cvtConstString(CompilationUnit* cUnit, llvm::CallInst* callInst)
1926{
buzbee4f1181f2012-06-22 13:52:12 -07001927 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee6969d502012-06-15 16:40:31 -07001928 llvm::ConstantInt* stringIdxVal =
1929 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1930 uint32_t stringIdx = stringIdxVal->getZExtValue();
1931 RegLocation rlDest = getLoc(cUnit, callInst);
1932 genConstString(cUnit, stringIdx, rlDest);
1933}
1934
buzbee4f1181f2012-06-22 13:52:12 -07001935void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
1936{
buzbee32412962012-06-26 16:27:56 -07001937 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07001938 llvm::ConstantInt* typeIdxVal =
1939 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1940 uint32_t typeIdx = typeIdxVal->getZExtValue();
1941 RegLocation rlDest = getLoc(cUnit, callInst);
1942 genNewInstance(cUnit, typeIdx, rlDest);
1943}
1944
buzbee8fa0fda2012-06-27 15:44:52 -07001945void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
1946{
1947 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
1948 llvm::ConstantInt* typeIdxVal =
1949 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1950 uint32_t typeIdx = typeIdxVal->getZExtValue();
1951 llvm::Value* len = callInst->getArgOperand(1);
1952 RegLocation rlLen = getLoc(cUnit, len);
1953 RegLocation rlDest = getLoc(cUnit, callInst);
1954 genNewArray(cUnit, typeIdx, rlDest, rlLen);
1955}
1956
1957void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
1958{
1959 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
1960 llvm::ConstantInt* typeIdxVal =
1961 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1962 uint32_t typeIdx = typeIdxVal->getZExtValue();
1963 llvm::Value* src = callInst->getArgOperand(1);
1964 RegLocation rlSrc = getLoc(cUnit, src);
1965 RegLocation rlDest = getLoc(cUnit, callInst);
1966 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
1967}
1968
buzbee32412962012-06-26 16:27:56 -07001969void cvtThrowVerificationError(CompilationUnit* cUnit, llvm::CallInst* callInst)
1970{
1971 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
1972 llvm::ConstantInt* info1 =
1973 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1974 llvm::ConstantInt* info2 =
1975 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
1976 genThrowVerificationError(cUnit, info1->getZExtValue(), info2->getZExtValue());
1977}
1978
1979void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
1980{
1981 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
1982 llvm::Value* src = callInst->getArgOperand(0);
1983 RegLocation rlSrc = getLoc(cUnit, src);
1984 genThrow(cUnit, rlSrc);
1985}
1986
buzbee8fa0fda2012-06-27 15:44:52 -07001987void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
1988 llvm::CallInst* callInst)
1989{
1990 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
1991 llvm::ConstantInt* optFlags =
1992 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1993 llvm::Value* src = callInst->getArgOperand(1);
1994 RegLocation rlSrc = getLoc(cUnit, src);
1995 if (isEnter) {
1996 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
1997 } else {
1998 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
1999 }
2000}
2001
2002void cvtMonitorArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
2003{
2004 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2005 llvm::ConstantInt* optFlags =
2006 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2007 llvm::Value* src = callInst->getArgOperand(1);
2008 RegLocation rlSrc = getLoc(cUnit, src);
2009 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2010 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2011 RegLocation rlDest = getLoc(cUnit, callInst);
2012 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2013 int lenOffset = Array::LengthOffset().Int32Value();
2014 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2015 storeValue(cUnit, rlDest, rlResult);
2016}
2017
buzbee32412962012-06-26 16:27:56 -07002018void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2019{
2020 DCHECK_EQ(callInst->getNumArgOperands(), 0U);
2021 int exOffset = Thread::ExceptionOffset().Int32Value();
2022 RegLocation rlDest = getLoc(cUnit, callInst);
2023 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2024#if defined(TARGET_X86)
2025 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
2026 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
2027#else
2028 int resetReg = oatAllocTemp(cUnit);
2029 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
2030 loadConstant(cUnit, resetReg, 0);
2031 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
2032 oatFreeTemp(cUnit, resetReg);
2033#endif
2034 storeValue(cUnit, rlDest, rlResult);
2035}
2036
buzbee4f1181f2012-06-22 13:52:12 -07002037void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2038 bool isObject)
2039{
buzbee32412962012-06-26 16:27:56 -07002040 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002041 llvm::ConstantInt* typeIdxVal =
2042 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2043 uint32_t typeIdx = typeIdxVal->getZExtValue();
2044 RegLocation rlDest = getLoc(cUnit, callInst);
2045 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2046}
2047
buzbee8fa0fda2012-06-27 15:44:52 -07002048void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2049 bool isObject)
2050{
2051 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2052 llvm::ConstantInt* typeIdxVal =
2053 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2054 uint32_t typeIdx = typeIdxVal->getZExtValue();
2055 llvm::Value* src = callInst->getArgOperand(1);
2056 RegLocation rlSrc = getLoc(cUnit, src);
2057 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2058}
2059
2060void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2061 int scale)
2062{
2063 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2064 llvm::ConstantInt* optFlags =
2065 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2066 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2067 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2068 RegLocation rlDest = getLoc(cUnit, callInst);
2069 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2070 rlDest, scale);
2071}
2072
2073void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2074 int scale)
2075{
2076 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2077 llvm::ConstantInt* optFlags =
2078 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2079 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2080 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2081 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
2082 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2083 rlSrc, scale);
2084}
2085
buzbee6969d502012-06-15 16:40:31 -07002086void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee8fa0fda2012-06-27 15:44:52 -07002087 bool isVoid)
buzbee6969d502012-06-15 16:40:31 -07002088{
2089 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2090 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002091 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002092 info->result.location = kLocInvalid;
2093 } else {
2094 info->result = getLoc(cUnit, callInst);
2095 }
2096 llvm::ConstantInt* invokeTypeVal =
2097 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2098 llvm::ConstantInt* methodIndexVal =
2099 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2100 llvm::ConstantInt* optFlagsVal =
2101 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2102 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2103 info->index = methodIndexVal->getZExtValue();
2104 info->optFlags = optFlagsVal->getZExtValue();
2105 info->offset = cUnit->currentDalvikOffset;
2106
2107 // FIXME - rework such that we no longer need isRange
2108 info->isRange = false;
2109
2110 // Count the argument words, and then build argument array.
2111 info->numArgWords = 0;
2112 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2113 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2114 info->numArgWords += tLoc.wide ? 2 : 1;
2115 }
2116 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2117 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2118 // Now, fill in the location records, synthesizing high loc of wide vals
2119 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002120 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002121 if (cUnit->printMe) {
2122 oatDumpRegLoc(info->args[next]);
2123 }
2124 if (info->args[next].wide) {
2125 next++;
2126 // TODO: Might make sense to mark this as an invalid loc
2127 info->args[next].origSReg = info->args[next-1].origSReg+1;
2128 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2129 }
2130 next++;
2131 }
2132 genInvoke(cUnit, info);
2133}
2134
buzbeead8f15e2012-06-18 14:49:45 -07002135/* Look up the RegLocation associated with a Value. Must already be defined */
2136RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2137{
2138 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2139 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2140 return it->second;
2141}
2142
buzbee2cfc6392012-05-07 14:51:40 -07002143bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2144{
2145 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2146 // Define the starting label
2147 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2148 // Extract the starting offset from the block's name
2149 if (!isEntry) {
2150 const char* blockName = bb->getName().str().c_str();
2151 int dummy;
Elliott Hughes74847412012-06-20 18:10:21 -07002152 sscanf(blockName, kLabelFormat, &blockLabel->operands[0], &dummy);
buzbee2cfc6392012-05-07 14:51:40 -07002153 }
2154 // Set the label kind
2155 blockLabel->opcode = kPseudoNormalBlockLabel;
2156 // Insert the label
2157 oatAppendLIR(cUnit, blockLabel);
2158
2159 // Free temp registers and reset redundant store tracking */
2160 oatResetRegPool(cUnit);
2161 oatResetDefTracking(cUnit);
2162
2163 //TODO: restore oat incoming liveness optimization
2164 oatClobberAllRegs(cUnit);
2165
buzbee6969d502012-06-15 16:40:31 -07002166 LIR* headLIR = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07002167
2168 if (isEntry) {
2169 cUnit->currentDalvikOffset = 0;
buzbeead8f15e2012-06-18 14:49:45 -07002170 RegLocation* argLocs = (RegLocation*)
2171 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2172 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2173 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2174 for (unsigned i = 0; it != it_end; ++it) {
2175 llvm::Value* val = it;
2176 argLocs[i++] = valToLoc(cUnit, val);
2177 llvm::Type* ty = val->getType();
2178 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2179 argLocs[i++].sRegLow = INVALID_SREG;
2180 }
2181 }
2182 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
buzbee2cfc6392012-05-07 14:51:40 -07002183 }
2184
2185 // Visit all of the instructions in the block
2186 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2187 llvm::Instruction* inst = it;
2188 llvm::BasicBlock::iterator nextIt = ++it;
2189 // Extract the Dalvik offset from the instruction
2190 uint32_t opcode = inst->getOpcode();
2191 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2192 if (dexOffsetNode != NULL) {
2193 llvm::ConstantInt* dexOffsetValue =
2194 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2195 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2196 }
2197
buzbee6969d502012-06-15 16:40:31 -07002198 oatResetRegPool(cUnit);
2199 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2200 oatClobberAllRegs(cUnit);
2201 }
2202
2203 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2204 oatResetDefTracking(cUnit);
2205 }
2206
2207#ifndef NDEBUG
2208 /* Reset temp tracking sanity check */
2209 cUnit->liveSReg = INVALID_SREG;
2210#endif
2211
2212 LIR* boundaryLIR;
2213 const char* instStr = "boundary";
2214 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
2215 (intptr_t) instStr);
2216 cUnit->boundaryMap.Overwrite(cUnit->currentDalvikOffset, boundaryLIR);
2217
2218 /* Remember the first LIR for thisl block*/
2219 if (headLIR == NULL) {
2220 headLIR = boundaryLIR;
2221 headLIR->defMask = ENCODE_ALL;
2222 }
2223
buzbee2cfc6392012-05-07 14:51:40 -07002224 switch(opcode) {
2225
2226 case llvm::Instruction::ICmp: {
2227 llvm::Instruction* nextInst = nextIt;
2228 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2229 if (brInst != NULL /* and... */) {
2230 cvtICmpBr(cUnit, inst, brInst);
2231 ++it;
2232 } else {
2233 cvtICmp(cUnit, inst);
2234 }
2235 }
2236 break;
2237
2238 case llvm::Instruction::Call: {
2239 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2240 llvm::Function* callee = callInst->getCalledFunction();
2241 greenland::IntrinsicHelper::IntrinsicId id =
2242 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2243 switch (id) {
buzbeeb03f4872012-06-11 15:22:11 -07002244 case greenland::IntrinsicHelper::AllocaShadowFrame:
2245 case greenland::IntrinsicHelper::SetShadowFrameEntry:
buzbee6969d502012-06-15 16:40:31 -07002246 case greenland::IntrinsicHelper::PopShadowFrame:
buzbeeb03f4872012-06-11 15:22:11 -07002247 // Ignore shadow frame stuff for quick compiler
2248 break;
buzbee2cfc6392012-05-07 14:51:40 -07002249 case greenland::IntrinsicHelper::CopyInt:
2250 case greenland::IntrinsicHelper::CopyObj:
2251 case greenland::IntrinsicHelper::CopyFloat:
2252 case greenland::IntrinsicHelper::CopyLong:
2253 case greenland::IntrinsicHelper::CopyDouble:
2254 cvtCopy(cUnit, callInst);
2255 break;
2256 case greenland::IntrinsicHelper::ConstInt:
2257 case greenland::IntrinsicHelper::ConstObj:
2258 case greenland::IntrinsicHelper::ConstLong:
2259 case greenland::IntrinsicHelper::ConstFloat:
2260 case greenland::IntrinsicHelper::ConstDouble:
2261 cvtConst(cUnit, callInst);
2262 break;
buzbee4f1181f2012-06-22 13:52:12 -07002263 case greenland::IntrinsicHelper::DivInt:
2264 case greenland::IntrinsicHelper::DivLong:
2265 cvtBinOp(cUnit, kOpDiv, inst);
2266 break;
2267 case greenland::IntrinsicHelper::RemInt:
2268 case greenland::IntrinsicHelper::RemLong:
2269 cvtBinOp(cUnit, kOpRem, inst);
2270 break;
buzbee2cfc6392012-05-07 14:51:40 -07002271 case greenland::IntrinsicHelper::MethodInfo:
buzbeead8f15e2012-06-18 14:49:45 -07002272 // Already dealt with - just ignore it here.
buzbee2cfc6392012-05-07 14:51:40 -07002273 break;
2274 case greenland::IntrinsicHelper::CheckSuspend:
2275 genSuspendTest(cUnit, 0 /* optFlags already applied */);
2276 break;
buzbee4f1181f2012-06-22 13:52:12 -07002277 case greenland::IntrinsicHelper::HLInvokeObj:
buzbee8fa0fda2012-06-27 15:44:52 -07002278 case greenland::IntrinsicHelper::HLInvokeFloat:
2279 case greenland::IntrinsicHelper::HLInvokeDouble:
2280 case greenland::IntrinsicHelper::HLInvokeLong:
2281 case greenland::IntrinsicHelper::HLInvokeInt:
2282 cvtInvoke(cUnit, callInst, false /* isVoid */);
buzbee4f1181f2012-06-22 13:52:12 -07002283 break;
buzbee6969d502012-06-15 16:40:31 -07002284 case greenland::IntrinsicHelper::HLInvokeVoid:
buzbee8fa0fda2012-06-27 15:44:52 -07002285 cvtInvoke(cUnit, callInst, true /* isVoid */);
buzbee6969d502012-06-15 16:40:31 -07002286 break;
2287 case greenland::IntrinsicHelper::ConstString:
2288 cvtConstString(cUnit, callInst);
2289 break;
buzbee4f1181f2012-06-22 13:52:12 -07002290 case greenland::IntrinsicHelper::NewInstance:
2291 cvtNewInstance(cUnit, callInst);
2292 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002293 case greenland::IntrinsicHelper::HLSgetObject:
buzbee4f1181f2012-06-22 13:52:12 -07002294 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
2295 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002296 case greenland::IntrinsicHelper::HLSget:
2297 case greenland::IntrinsicHelper::HLSgetFloat:
2298 case greenland::IntrinsicHelper::HLSgetBoolean:
2299 case greenland::IntrinsicHelper::HLSgetByte:
2300 case greenland::IntrinsicHelper::HLSgetChar:
2301 case greenland::IntrinsicHelper::HLSgetShort:
2302 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
2303 break;
2304 case greenland::IntrinsicHelper::HLSgetWide:
2305 case greenland::IntrinsicHelper::HLSgetDouble:
2306 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
2307 break;
buzbee32412962012-06-26 16:27:56 -07002308 case greenland::IntrinsicHelper::GetException:
2309 cvtMoveException(cUnit, callInst);
2310 break;
2311 case greenland::IntrinsicHelper::Throw:
2312 cvtThrow(cUnit, callInst);
2313 break;
2314 case greenland::IntrinsicHelper::ThrowVerificationError:
buzbee8fa0fda2012-06-27 15:44:52 -07002315 cvtThrowVerificationError(cUnit, callInst);
buzbee32412962012-06-26 16:27:56 -07002316 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002317 case greenland::IntrinsicHelper::MonitorEnter:
2318 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
2319 break;
2320 case greenland::IntrinsicHelper::MonitorExit:
2321 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
2322 break;
2323 case greenland::IntrinsicHelper::ArrayLength:
2324 cvtMonitorArrayLength(cUnit, callInst);
2325 break;
2326 case greenland::IntrinsicHelper::NewArray:
2327 cvtNewArray(cUnit, callInst);
2328 break;
2329 case greenland::IntrinsicHelper::InstanceOf:
2330 cvtInstanceOf(cUnit, callInst);
2331 break;
2332
2333 case greenland::IntrinsicHelper::HLArrayGet:
2334 case greenland::IntrinsicHelper::HLArrayGetObject:
2335 case greenland::IntrinsicHelper::HLArrayGetFloat:
2336 cvtAget(cUnit, callInst, kWord, 2);
2337 break;
2338 case greenland::IntrinsicHelper::HLArrayGetWide:
2339 case greenland::IntrinsicHelper::HLArrayGetDouble:
2340 cvtAget(cUnit, callInst, kLong, 3);
2341 break;
2342 case greenland::IntrinsicHelper::HLArrayGetBoolean:
2343 cvtAget(cUnit, callInst, kUnsignedByte, 0);
2344 break;
2345 case greenland::IntrinsicHelper::HLArrayGetByte:
2346 cvtAget(cUnit, callInst, kSignedByte, 0);
2347 break;
2348 case greenland::IntrinsicHelper::HLArrayGetChar:
2349 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
2350 break;
2351 case greenland::IntrinsicHelper::HLArrayGetShort:
2352 cvtAget(cUnit, callInst, kSignedHalf, 1);
2353 break;
2354
2355 case greenland::IntrinsicHelper::HLArrayPut:
2356 case greenland::IntrinsicHelper::HLArrayPutObject:
2357 case greenland::IntrinsicHelper::HLArrayPutFloat:
2358 cvtAput(cUnit, callInst, kWord, 2);
2359 break;
2360 case greenland::IntrinsicHelper::HLArrayPutWide:
2361 case greenland::IntrinsicHelper::HLArrayPutDouble:
2362 cvtAput(cUnit, callInst, kLong, 3);
2363 break;
2364 case greenland::IntrinsicHelper::HLArrayPutBoolean:
2365 cvtAput(cUnit, callInst, kUnsignedByte, 0);
2366 break;
2367 case greenland::IntrinsicHelper::HLArrayPutByte:
2368 cvtAput(cUnit, callInst, kSignedByte, 0);
2369 break;
2370 case greenland::IntrinsicHelper::HLArrayPutChar:
2371 cvtAput(cUnit, callInst, kUnsignedHalf, 1);
2372 break;
2373 case greenland::IntrinsicHelper::HLArrayPutShort:
2374 cvtAput(cUnit, callInst, kSignedHalf, 1);
2375 break;
2376
buzbee2cfc6392012-05-07 14:51:40 -07002377 case greenland::IntrinsicHelper::UnknownId:
2378 cvtCall(cUnit, callInst, callee);
2379 break;
2380 default:
2381 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
2382 << cUnit->intrinsic_helper->GetName(id);
2383 }
2384 }
2385 break;
2386
2387 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
2388 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
2389 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
2390 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
2391 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
2392 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
2393 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
2394 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
2395 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
2396 case llvm::Instruction::Shl: cvtBinOp(cUnit, kOpLsl, inst); break;
2397 case llvm::Instruction::LShr: cvtBinOp(cUnit, kOpLsr, inst); break;
2398 case llvm::Instruction::AShr: cvtBinOp(cUnit, kOpAsr, inst); break;
2399 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
2400 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
buzbee4f1181f2012-06-22 13:52:12 -07002401 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
2402 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
2403 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
2404 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
2405 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07002406
buzbee32412962012-06-26 16:27:56 -07002407 case llvm::Instruction::Unreachable:
2408 break; // FIXME: can we really ignore these?
2409
buzbee2cfc6392012-05-07 14:51:40 -07002410 case llvm::Instruction::Invoke:
buzbee2cfc6392012-05-07 14:51:40 -07002411 case llvm::Instruction::Trunc:
2412 case llvm::Instruction::ZExt:
2413 case llvm::Instruction::SExt:
2414 case llvm::Instruction::FPToUI:
2415 case llvm::Instruction::FPToSI:
2416 case llvm::Instruction::UIToFP:
2417 case llvm::Instruction::SIToFP:
2418 case llvm::Instruction::FPTrunc:
2419 case llvm::Instruction::FPExt:
2420 case llvm::Instruction::PtrToInt:
2421 case llvm::Instruction::IntToPtr:
2422 case llvm::Instruction::Switch:
2423 case llvm::Instruction::FCmp:
2424 UNIMPLEMENTED(FATAL) << "Unimplemented llvm opcode: " << opcode; break;
buzbee4f1181f2012-06-22 13:52:12 -07002425 break;
buzbee2cfc6392012-05-07 14:51:40 -07002426
2427 case llvm::Instruction::URem:
2428 case llvm::Instruction::UDiv:
2429 case llvm::Instruction::Resume:
buzbee2cfc6392012-05-07 14:51:40 -07002430 case llvm::Instruction::Alloca:
2431 case llvm::Instruction::GetElementPtr:
2432 case llvm::Instruction::Fence:
2433 case llvm::Instruction::AtomicCmpXchg:
2434 case llvm::Instruction::AtomicRMW:
2435 case llvm::Instruction::BitCast:
2436 case llvm::Instruction::VAArg:
2437 case llvm::Instruction::Select:
2438 case llvm::Instruction::UserOp1:
2439 case llvm::Instruction::UserOp2:
2440 case llvm::Instruction::ExtractElement:
2441 case llvm::Instruction::InsertElement:
2442 case llvm::Instruction::ShuffleVector:
2443 case llvm::Instruction::ExtractValue:
2444 case llvm::Instruction::InsertValue:
2445 case llvm::Instruction::LandingPad:
2446 case llvm::Instruction::IndirectBr:
2447 case llvm::Instruction::Load:
2448 case llvm::Instruction::Store:
2449 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
2450
2451 default:
2452 LOG(FATAL) << "Unknown llvm opcode: " << opcode; break;
2453 }
2454 }
buzbee6969d502012-06-15 16:40:31 -07002455
2456 if (headLIR != NULL) {
2457 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
2458 }
buzbee2cfc6392012-05-07 14:51:40 -07002459 return false;
2460}
2461
2462/*
2463 * Convert LLVM_IR to MIR:
2464 * o Iterate through the LLVM_IR and construct a graph using
2465 * standard MIR building blocks.
2466 * o Perform a basic-block optimization pass to remove unnecessary
2467 * store/load sequences.
2468 * o Convert the LLVM Value operands into RegLocations where applicable.
2469 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
2470 * o Perform register promotion
2471 * o Iterate through the graph a basic block at a time, generating
2472 * LIR.
2473 * o Assemble LIR as usual.
2474 * o Profit.
2475 */
2476void oatMethodBitcode2LIR(CompilationUnit* cUnit)
2477{
buzbeead8f15e2012-06-18 14:49:45 -07002478 llvm::Function* func = cUnit->func;
2479 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07002480 // Allocate a list for LIR basic block labels
2481 cUnit->blockLabelList =
2482 (void*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
2483 LIR* labelList = (LIR*)cUnit->blockLabelList;
2484 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07002485 for (llvm::Function::iterator i = func->begin(),
2486 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07002487 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
2488 &labelList[nextLabel++]);
2489 }
buzbeead8f15e2012-06-18 14:49:45 -07002490
2491 /*
2492 * Keep honest - clear regLocations, Value => RegLocation,
2493 * promotion map and VmapTables.
2494 */
2495 cUnit->locMap.clear(); // Start fresh
2496 cUnit->regLocation = NULL;
2497 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
2498 i++) {
2499 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
2500 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
2501 }
2502 cUnit->coreSpillMask = 0;
2503 cUnit->numCoreSpills = 0;
2504 cUnit->fpSpillMask = 0;
2505 cUnit->numFPSpills = 0;
2506 cUnit->coreVmapTable.clear();
2507 cUnit->fpVmapTable.clear();
2508 oatAdjustSpillMask(cUnit);
2509 cUnit->frameSize = oatComputeFrameSize(cUnit);
2510
2511 /*
2512 * At this point, we've lost all knowledge of register promotion.
2513 * Rebuild that info from the MethodInfo intrinsic (if it
2514 * exists - not required for correctness).
2515 */
2516 // TODO: find and recover MethodInfo.
2517
2518 // Create RegLocations for arguments
2519 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2520 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2521 for (; it != it_end; ++it) {
2522 llvm::Value* val = it;
2523 createLocFromValue(cUnit, val);
2524 }
2525 // Create RegLocations for all non-argument defintions
2526 for (llvm::inst_iterator i = llvm::inst_begin(func),
2527 e = llvm::inst_end(func); i != e; ++i) {
2528 llvm::Value* val = &*i;
2529 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
2530 createLocFromValue(cUnit, val);
2531 }
2532 }
2533
buzbee2cfc6392012-05-07 14:51:40 -07002534 // Walk the blocks, generating code.
2535 for (llvm::Function::iterator i = cUnit->func->begin(),
2536 e = cUnit->func->end(); i != e; ++i) {
2537 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
2538 }
2539
2540 handleSuspendLaunchpads(cUnit);
2541
2542 handleThrowLaunchpads(cUnit);
2543
2544 handleIntrinsicLaunchpads(cUnit);
2545
2546 freeIR(cUnit);
2547}
2548
2549
2550} // namespace art
2551
2552#endif // ART_USE_QUICK_COMPILER