blob: f13a473be5a42169c6804465e40e70eed42a047b [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>
30
buzbee6969d502012-06-15 16:40:31 -070031const char* labelFormat = "L0x%x_%d";
buzbee2cfc6392012-05-07 14:51:40 -070032
33namespace art {
34extern const RegLocation badLoc;
buzbeeb03f4872012-06-11 15:22:11 -070035RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val);
buzbee2cfc6392012-05-07 14:51:40 -070036
37llvm::BasicBlock* getLLVMBlock(CompilationUnit* cUnit, int id)
38{
39 return cUnit->idToBlockMap.Get(id);
40}
41
42llvm::Value* getLLVMValue(CompilationUnit* cUnit, int sReg)
43{
44 return (llvm::Value*)oatGrowableListGetElement(&cUnit->llvmValues, sReg);
45}
46
47// Replace the placeholder value with the real definition
48void defineValue(CompilationUnit* cUnit, llvm::Value* val, int sReg)
49{
50 llvm::Value* placeholder = getLLVMValue(cUnit, sReg);
51 CHECK(placeholder != NULL) << "Null placeholder - shouldn't happen";
52 placeholder->replaceAllUsesWith(val);
53 val->takeName(placeholder);
54 cUnit->llvmValues.elemList[sReg] = (intptr_t)val;
55}
56
57llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
58{
59 llvm::Type* res = NULL;
60 if (loc.wide) {
61 if (loc.fp)
62 res = cUnit->irb->GetJDoubleTy();
63 else
64 res = cUnit->irb->GetJLongTy();
65 } else {
66 if (loc.fp) {
67 res = cUnit->irb->GetJFloatTy();
68 } else {
69 if (loc.ref)
70 res = cUnit->irb->GetJObjectTy();
71 else
72 res = cUnit->irb->GetJIntTy();
73 }
74 }
75 return res;
76}
77
78void initIR(CompilationUnit* cUnit)
79{
80 cUnit->context = new llvm::LLVMContext();
81 cUnit->module = new llvm::Module("art", *cUnit->context);
82 llvm::StructType::create(*cUnit->context, "JavaObject");
83 llvm::StructType::create(*cUnit->context, "Method");
84 llvm::StructType::create(*cUnit->context, "Thread");
85 cUnit->intrinsic_helper =
86 new greenland::IntrinsicHelper(*cUnit->context, *cUnit->module);
87 cUnit->irb =
88 new greenland::IRBuilder(*cUnit->context, *cUnit->module,
89 *cUnit->intrinsic_helper);
90}
91
92void freeIR(CompilationUnit* cUnit)
93{
94 delete cUnit->irb;
95 delete cUnit->intrinsic_helper;
96 delete cUnit->module;
97 delete cUnit->context;
98}
99
100const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
101 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
102}
103
104llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
105 RegLocation loc)
106{
107 greenland::IntrinsicHelper::IntrinsicId id;
108 if (loc.wide) {
109 if (loc.fp) {
110 id = greenland::IntrinsicHelper::ConstDouble;
111 } else {
112 id = greenland::IntrinsicHelper::ConstLong;
113 }
114 } else {
115 if (loc.fp) {
116 id = greenland::IntrinsicHelper::ConstFloat;
117 } if (loc.ref) {
118 id = greenland::IntrinsicHelper::ConstObj;
119 } else {
120 id = greenland::IntrinsicHelper::ConstInt;
121 }
122 }
123 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
124 return cUnit->irb->CreateCall(intr, src);
125}
buzbeeb03f4872012-06-11 15:22:11 -0700126
127void emitPopShadowFrame(CompilationUnit* cUnit)
128{
129 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
130 greenland::IntrinsicHelper::PopShadowFrame);
131 cUnit->irb->CreateCall(intr);
132}
133
134
135
buzbee2cfc6392012-05-07 14:51:40 -0700136llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
137 RegLocation loc)
138{
139 greenland::IntrinsicHelper::IntrinsicId id;
140 if (loc.wide) {
141 if (loc.fp) {
142 id = greenland::IntrinsicHelper::CopyDouble;
143 } else {
144 id = greenland::IntrinsicHelper::CopyLong;
145 }
146 } else {
147 if (loc.fp) {
148 id = greenland::IntrinsicHelper::CopyFloat;
149 } if (loc.ref) {
150 id = greenland::IntrinsicHelper::CopyObj;
151 } else {
152 id = greenland::IntrinsicHelper::CopyInt;
153 }
154 }
155 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
156 return cUnit->irb->CreateCall(intr, src);
157}
158
159void emitSuspendCheck(CompilationUnit* cUnit)
160{
161 greenland::IntrinsicHelper::IntrinsicId id =
162 greenland::IntrinsicHelper::CheckSuspend;
163 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
164 cUnit->irb->CreateCall(intr);
165}
166
167llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
168 llvm::Value* src1, llvm::Value* src2)
169{
170 llvm::Value* res = NULL;
171 switch(cc) {
172 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
173 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
174 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
175 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
176 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
177 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
178 default: LOG(FATAL) << "Unexpected cc value " << cc;
179 }
180 return res;
181}
182
183void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
184 ConditionCode cc, RegLocation rlSrc1,
185 RegLocation rlSrc2)
186{
187 if (bb->taken->startOffset <= mir->offset) {
188 emitSuspendCheck(cUnit);
189 }
190 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
191 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
192 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
193 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
194 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
195 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700196 // Don't redo the fallthrough branch in the BB driver
197 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700198}
199
200void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
201 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
202{
203 if (bb->taken->startOffset <= mir->offset) {
204 emitSuspendCheck(cUnit);
205 }
206 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
207 llvm::Value* src2;
208 if (rlSrc1.ref) {
209 src2 = cUnit->irb->GetJNull();
210 } else {
211 src2 = cUnit->irb->getInt32(0);
212 }
213 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
214 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
215 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
216 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700217 // Don't redo the fallthrough branch in the BB driver
218 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700219}
220
221llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
222 llvm::Value* src1, llvm::Value* src2)
223{
224 greenland::IntrinsicHelper::IntrinsicId id;
225 if (isLong) {
226 if (isDiv) {
227 id = greenland::IntrinsicHelper::DivLong;
228 } else {
229 id = greenland::IntrinsicHelper::RemLong;
230 }
231 } else if (isDiv) {
232 id = greenland::IntrinsicHelper::DivInt;
233 } else {
234 id = greenland::IntrinsicHelper::RemInt;
235 }
236 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
237 llvm::SmallVector<llvm::Value*, 2>args;
238 args.push_back(src1);
239 args.push_back(src2);
240 return cUnit->irb->CreateCall(intr, args);
241}
242
243llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
244 llvm::Value* src1, llvm::Value* src2)
245{
246 llvm::Value* res = NULL;
247 switch(op) {
248 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
249 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
250 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
251 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
252 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
253 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
254 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
255 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
256 case kOpLsl: UNIMPLEMENTED(FATAL) << "Need Lsl"; break;
257 case kOpLsr: UNIMPLEMENTED(FATAL) << "Need Lsr"; break;
258 case kOpAsr: UNIMPLEMENTED(FATAL) << "Need Asr"; break;
259 default:
260 LOG(FATAL) << "Invalid op " << op;
261 }
262 return res;
263}
264
265void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
266 RegLocation rlSrc1, RegLocation rlSrc2)
267{
268 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
269 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
270 llvm::Value* res = NULL;
271 switch(op) {
272 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
273 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
274 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
275 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
276 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
277 default:
278 LOG(FATAL) << "Invalid op " << op;
279 }
280 defineValue(cUnit, res, rlDest.origSReg);
281}
282
283void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
284 RegLocation rlSrc1, RegLocation rlSrc2)
285{
286 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
287 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
288 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
289 defineValue(cUnit, res, rlDest.origSReg);
290}
291
buzbeeb03f4872012-06-11 15:22:11 -0700292void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
293{
294 int index = -1;
295 DCHECK(newVal != NULL);
296 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
297 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
298 if (cUnit->shadowMap[i] == vReg) {
299 index = i;
300 break;
301 }
302 }
303 DCHECK(index != -1) << "Corrupt shadowMap";
304 greenland::IntrinsicHelper::IntrinsicId id =
305 greenland::IntrinsicHelper::SetShadowFrameEntry;
306 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
307 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
308 llvm::Value* args[] = { newVal, tableSlot };
309 cUnit->irb->CreateCall(func, args);
310}
311
buzbee2cfc6392012-05-07 14:51:40 -0700312void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
313 RegLocation rlSrc1, int32_t imm)
314{
315 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
316 llvm::Value* src2 = cUnit->irb->getInt32(imm);
317 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
318 defineValue(cUnit, res, rlDest.origSReg);
319}
320
buzbee6969d502012-06-15 16:40:31 -0700321void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
322 InvokeType invokeType, bool isRange)
323{
324 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
325 llvm::SmallVector<llvm::Value*, 10> args;
326 // Insert the invokeType
327 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
328 // Insert the method_idx
329 args.push_back(cUnit->irb->getInt32(info->index));
330 // Insert the optimization flags
331 args.push_back(cUnit->irb->getInt32(info->optFlags));
332 // Now, insert the actual arguments
333 if (cUnit->printMe) {
334 LOG(INFO) << "Building Invoke info";
335 }
336 for (int i = 0; i < info->numArgWords;) {
337 if (cUnit->printMe) {
338 oatDumpRegLoc(info->args[i]);
339 }
340 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
341 args.push_back(val);
342 i += info->args[i].wide ? 2 : 1;
343 }
344 /*
345 * Choose the invoke return type based on actual usage. Note: may
346 * be different than shorty. For example, if a function return value
347 * is not used, we'll treat this as a void invoke.
348 */
349 greenland::IntrinsicHelper::IntrinsicId id;
350 if (info->result.location == kLocInvalid) {
351 id = greenland::IntrinsicHelper::HLInvokeVoid;
352 } else {
353 if (info->result.wide) {
354 if (info->result.fp) {
355 id = greenland::IntrinsicHelper::HLInvokeDouble;
356 } else {
357 id = greenland::IntrinsicHelper::HLInvokeFloat;
358 }
359 } else if (info->result.ref) {
360 id = greenland::IntrinsicHelper::HLInvokeObj;
361 } else if (info->result.fp) {
362 id = greenland::IntrinsicHelper::HLInvokeFloat;
363 } else {
364 id = greenland::IntrinsicHelper::HLInvokeInt;
365 }
366 }
367 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
368 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
369 if (info->result.location != kLocInvalid) {
370 defineValue(cUnit, res, info->result.origSReg);
371 }
372}
373
374void convertConstString(CompilationUnit* cUnit, BasicBlock* bb,
375 uint32_t string_idx, RegLocation rlDest)
376{
377 greenland::IntrinsicHelper::IntrinsicId id;
378 id = greenland::IntrinsicHelper::ConstString;
379 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
380 llvm::Value* index = cUnit->irb->getInt32(string_idx);
381 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
382 defineValue(cUnit, res, rlDest.origSReg);
383}
384
buzbee2cfc6392012-05-07 14:51:40 -0700385/*
386 * Target-independent code generation. Use only high-level
387 * load/store utilities here, or target-dependent genXX() handlers
388 * when necessary.
389 */
390bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
391 llvm::BasicBlock* llvmBB, LIR* labelList)
392{
393 bool res = false; // Assume success
394 RegLocation rlSrc[3];
395 RegLocation rlDest = badLoc;
396 RegLocation rlResult = badLoc;
397 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee6969d502012-06-15 16:40:31 -0700398 uint32_t vB = mir->dalvikInsn.vB;
399 uint32_t vC = mir->dalvikInsn.vC;
400
buzbeeb03f4872012-06-11 15:22:11 -0700401 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700402
403 /* Prep Src and Dest locations */
404 int nextSreg = 0;
405 int nextLoc = 0;
406 int attrs = oatDataFlowAttributes[opcode];
407 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
408 if (attrs & DF_UA) {
409 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700410 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700411 nextSreg+= 2;
412 } else {
413 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
414 nextSreg++;
415 }
416 }
417 if (attrs & DF_UB) {
418 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700419 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700420 nextSreg+= 2;
421 } else {
422 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
423 nextSreg++;
424 }
425 }
426 if (attrs & DF_UC) {
427 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700428 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700429 } else {
430 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
431 }
432 }
433 if (attrs & DF_DA) {
434 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700435 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700436 } else {
buzbee15bf9802012-06-12 17:49:27 -0700437 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700438 if (rlDest.ref) {
439 objectDefinition = true;
440 }
buzbee2cfc6392012-05-07 14:51:40 -0700441 }
442 }
443
444 switch (opcode) {
445 case Instruction::NOP:
446 break;
447
448 case Instruction::MOVE:
449 case Instruction::MOVE_OBJECT:
450 case Instruction::MOVE_16:
451 case Instruction::MOVE_OBJECT_16:
452 case Instruction::MOVE_FROM16:
453 case Instruction::MOVE_WIDE:
454 case Instruction::MOVE_WIDE_16:
455 case Instruction::MOVE_WIDE_FROM16: {
456 /*
457 * Moves/copies are meaningless in pure SSA register form,
458 * but we need to preserve them for the conversion back into
459 * MIR (at least until we stop using the Dalvik register maps).
460 * Insert a dummy intrinsic copy call, which will be recognized
461 * by the quick path and removed by the portable path.
462 */
463 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
464 llvm::Value* res = emitCopy(cUnit, src, rlDest);
465 defineValue(cUnit, res, rlDest.origSReg);
466 }
467 break;
468
469 case Instruction::CONST:
470 case Instruction::CONST_4:
471 case Instruction::CONST_16: {
buzbee6969d502012-06-15 16:40:31 -0700472 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700473 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
474 defineValue(cUnit, res, rlDest.origSReg);
475 }
476 break;
477
478 case Instruction::CONST_WIDE_16:
479 case Instruction::CONST_WIDE_32: {
buzbee6969d502012-06-15 16:40:31 -0700480 llvm::Constant* immValue = cUnit->irb->GetJLong(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700481 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
482 defineValue(cUnit, res, rlDest.origSReg);
483 }
484 break;
485
486 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700487 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700488 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
489 defineValue(cUnit, res, rlDest.origSReg);
490 }
491 break;
492
493 case Instruction::CONST_WIDE: {
494 llvm::Constant* immValue =
495 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
496 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
497 defineValue(cUnit, res, rlDest.origSReg);
498 }
499 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700500 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700501 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
502 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
503 defineValue(cUnit, res, rlDest.origSReg);
504 }
505
506 case Instruction::RETURN_WIDE:
507 case Instruction::RETURN:
508 case Instruction::RETURN_OBJECT: {
509 if (!cUnit->attrs & METHOD_IS_LEAF) {
510 emitSuspendCheck(cUnit);
511 }
buzbeeb03f4872012-06-11 15:22:11 -0700512 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700513 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
514 bb->hasReturn = true;
515 }
516 break;
517
518 case Instruction::RETURN_VOID: {
519 if (!cUnit->attrs & METHOD_IS_LEAF) {
520 emitSuspendCheck(cUnit);
521 }
buzbeeb03f4872012-06-11 15:22:11 -0700522 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700523 cUnit->irb->CreateRetVoid();
524 bb->hasReturn = true;
525 }
526 break;
527
528 case Instruction::IF_EQ:
529 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
530 break;
531 case Instruction::IF_NE:
532 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
533 break;
534 case Instruction::IF_LT:
535 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
536 break;
537 case Instruction::IF_GE:
538 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
539 break;
540 case Instruction::IF_GT:
541 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
542 break;
543 case Instruction::IF_LE:
544 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
545 break;
546 case Instruction::IF_EQZ:
547 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
548 break;
549 case Instruction::IF_NEZ:
550 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
551 break;
552 case Instruction::IF_LTZ:
553 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
554 break;
555 case Instruction::IF_GEZ:
556 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
557 break;
558 case Instruction::IF_GTZ:
559 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
560 break;
561 case Instruction::IF_LEZ:
562 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
563 break;
564
565 case Instruction::GOTO:
566 case Instruction::GOTO_16:
567 case Instruction::GOTO_32: {
568 if (bb->taken->startOffset <= bb->startOffset) {
569 emitSuspendCheck(cUnit);
570 }
571 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
572 }
573 break;
574
575 case Instruction::ADD_LONG:
576 case Instruction::ADD_LONG_2ADDR:
577 case Instruction::ADD_INT:
578 case Instruction::ADD_INT_2ADDR:
579 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
580 break;
581 case Instruction::SUB_LONG:
582 case Instruction::SUB_LONG_2ADDR:
583 case Instruction::SUB_INT:
584 case Instruction::SUB_INT_2ADDR:
585 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
586 break;
587 case Instruction::MUL_LONG:
588 case Instruction::MUL_LONG_2ADDR:
589 case Instruction::MUL_INT:
590 case Instruction::MUL_INT_2ADDR:
591 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
592 break;
593 case Instruction::DIV_LONG:
594 case Instruction::DIV_LONG_2ADDR:
595 case Instruction::DIV_INT:
596 case Instruction::DIV_INT_2ADDR:
597 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
598 break;
599 case Instruction::REM_LONG:
600 case Instruction::REM_LONG_2ADDR:
601 case Instruction::REM_INT:
602 case Instruction::REM_INT_2ADDR:
603 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
604 break;
605 case Instruction::AND_LONG:
606 case Instruction::AND_LONG_2ADDR:
607 case Instruction::AND_INT:
608 case Instruction::AND_INT_2ADDR:
609 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
610 break;
611 case Instruction::OR_LONG:
612 case Instruction::OR_LONG_2ADDR:
613 case Instruction::OR_INT:
614 case Instruction::OR_INT_2ADDR:
615 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
616 break;
617 case Instruction::XOR_LONG:
618 case Instruction::XOR_LONG_2ADDR:
619 case Instruction::XOR_INT:
620 case Instruction::XOR_INT_2ADDR:
621 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
622 break;
623 case Instruction::SHL_LONG:
624 case Instruction::SHL_LONG_2ADDR:
625 case Instruction::SHL_INT:
626 case Instruction::SHL_INT_2ADDR:
627 convertArithOp(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
628 break;
629 case Instruction::SHR_LONG:
630 case Instruction::SHR_LONG_2ADDR:
631 case Instruction::SHR_INT:
632 case Instruction::SHR_INT_2ADDR:
633 convertArithOp(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
634 break;
635 case Instruction::USHR_LONG:
636 case Instruction::USHR_LONG_2ADDR:
637 case Instruction::USHR_INT:
638 case Instruction::USHR_INT_2ADDR:
639 convertArithOp(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
640 break;
641
642 case Instruction::ADD_INT_LIT16:
643 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700644 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700645 break;
646 case Instruction::RSUB_INT:
647 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700648 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700649 break;
650 case Instruction::MUL_INT_LIT16:
651 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700652 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700653 break;
654 case Instruction::DIV_INT_LIT16:
655 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700656 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700657 break;
658 case Instruction::REM_INT_LIT16:
659 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700660 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700661 break;
662 case Instruction::AND_INT_LIT16:
663 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700664 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700665 break;
666 case Instruction::OR_INT_LIT16:
667 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700668 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700669 break;
670 case Instruction::XOR_INT_LIT16:
671 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700672 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700673 break;
674 case Instruction::SHL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700675 convertArithOpLit(cUnit, kOpLsl, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700676 break;
677 case Instruction::SHR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700678 convertArithOpLit(cUnit, kOpLsr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700679 break;
680 case Instruction::USHR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -0700681 convertArithOpLit(cUnit, kOpAsr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -0700682 break;
683
684 case Instruction::ADD_FLOAT:
685 case Instruction::ADD_FLOAT_2ADDR:
686 case Instruction::ADD_DOUBLE:
687 case Instruction::ADD_DOUBLE_2ADDR:
688 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
689 break;
690
691 case Instruction::SUB_FLOAT:
692 case Instruction::SUB_FLOAT_2ADDR:
693 case Instruction::SUB_DOUBLE:
694 case Instruction::SUB_DOUBLE_2ADDR:
695 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
696 break;
697
698 case Instruction::MUL_FLOAT:
699 case Instruction::MUL_FLOAT_2ADDR:
700 case Instruction::MUL_DOUBLE:
701 case Instruction::MUL_DOUBLE_2ADDR:
702 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
703 break;
704
705 case Instruction::DIV_FLOAT:
706 case Instruction::DIV_FLOAT_2ADDR:
707 case Instruction::DIV_DOUBLE:
708 case Instruction::DIV_DOUBLE_2ADDR:
709 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
710 break;
711
712 case Instruction::REM_FLOAT:
713 case Instruction::REM_FLOAT_2ADDR:
714 case Instruction::REM_DOUBLE:
715 case Instruction::REM_DOUBLE_2ADDR:
716 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
717 break;
718
buzbee6969d502012-06-15 16:40:31 -0700719 case Instruction::INVOKE_STATIC:
720 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/);
721 break;
722 case Instruction::INVOKE_STATIC_RANGE:
723 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/);
724 break;
725
726 case Instruction::INVOKE_DIRECT:
727 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/);
728 break;
729 case Instruction::INVOKE_DIRECT_RANGE:
730 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/);
731 break;
732
733 case Instruction::INVOKE_VIRTUAL:
734 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/);
735 break;
736 case Instruction::INVOKE_VIRTUAL_RANGE:
737 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/);
738 break;
739
740 case Instruction::INVOKE_SUPER:
741 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/);
742 break;
743 case Instruction::INVOKE_SUPER_RANGE:
744 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/);
745 break;
746
747 case Instruction::INVOKE_INTERFACE:
748 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/);
749 break;
750 case Instruction::INVOKE_INTERFACE_RANGE:
751 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/);
752 break;
753
754 case Instruction::CONST_STRING:
755 case Instruction::CONST_STRING_JUMBO:
756 convertConstString(cUnit, bb, vB, rlDest);
757 break;
758
759
buzbee2cfc6392012-05-07 14:51:40 -0700760#if 0
761
762 case Instruction::MOVE_EXCEPTION: {
763 int exOffset = Thread::ExceptionOffset().Int32Value();
764 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
765#if defined(TARGET_X86)
766 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
767 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
768#else
769 int resetReg = oatAllocTemp(cUnit);
770 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
771 loadConstant(cUnit, resetReg, 0);
772 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
773 storeValue(cUnit, rlDest, rlResult);
774 oatFreeTemp(cUnit, resetReg);
775#endif
776 break;
777 }
778
779 case Instruction::MOVE_RESULT_WIDE:
780 if (mir->optimizationFlags & MIR_INLINED)
781 break; // Nop - combined w/ previous invoke
782 storeValueWide(cUnit, rlDest, oatGetReturnWide(cUnit, rlDest.fp));
783 break;
784
785 case Instruction::MOVE_RESULT:
786 case Instruction::MOVE_RESULT_OBJECT:
787 if (mir->optimizationFlags & MIR_INLINED)
788 break; // Nop - combined w/ previous invoke
789 storeValue(cUnit, rlDest, oatGetReturn(cUnit, rlDest.fp));
790 break;
791
792 case Instruction::MONITOR_ENTER:
793 genMonitorEnter(cUnit, mir, rlSrc[0]);
794 break;
795
796 case Instruction::MONITOR_EXIT:
797 genMonitorExit(cUnit, mir, rlSrc[0]);
798 break;
799
800 case Instruction::CHECK_CAST:
801 genCheckCast(cUnit, mir, rlSrc[0]);
802 break;
803
804 case Instruction::INSTANCE_OF:
805 genInstanceof(cUnit, mir, rlDest, rlSrc[0]);
806 break;
807
808 case Instruction::NEW_INSTANCE:
809 genNewInstance(cUnit, mir, rlDest);
810 break;
811
812 case Instruction::THROW:
813 genThrow(cUnit, mir, rlSrc[0]);
814 break;
815
816 case Instruction::THROW_VERIFICATION_ERROR:
817 genThrowVerificationError(cUnit, mir);
818 break;
819
820 case Instruction::ARRAY_LENGTH:
821 int lenOffset;
822 lenOffset = Array::LengthOffset().Int32Value();
823 rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
824 genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, mir);
825 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
826 loadWordDisp(cUnit, rlSrc[0].lowReg, lenOffset, rlResult.lowReg);
827 storeValue(cUnit, rlDest, rlResult);
828 break;
829
buzbee2cfc6392012-05-07 14:51:40 -0700830 case Instruction::CONST_CLASS:
831 genConstClass(cUnit, mir, rlDest, rlSrc[0]);
832 break;
833
834 case Instruction::FILL_ARRAY_DATA:
835 genFillArrayData(cUnit, mir, rlSrc[0]);
836 break;
837
838 case Instruction::FILLED_NEW_ARRAY:
839 genFilledNewArray(cUnit, mir, false /* not range */);
840 break;
841
842 case Instruction::FILLED_NEW_ARRAY_RANGE:
843 genFilledNewArray(cUnit, mir, true /* range */);
844 break;
845
846 case Instruction::NEW_ARRAY:
847 genNewArray(cUnit, mir, rlDest, rlSrc[0]);
848 break;
849
850 case Instruction::PACKED_SWITCH:
851 genPackedSwitch(cUnit, mir, rlSrc[0]);
852 break;
853
854 case Instruction::SPARSE_SWITCH:
855 genSparseSwitch(cUnit, mir, rlSrc[0], labelList);
856 break;
857
858 case Instruction::CMPL_FLOAT:
859 case Instruction::CMPG_FLOAT:
860 case Instruction::CMPL_DOUBLE:
861 case Instruction::CMPG_DOUBLE:
862 res = genCmpFP(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
863 break;
864
865 case Instruction::CMP_LONG:
866 genCmpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[1]);
867 break;
868
869 case Instruction::AGET_WIDE:
870 genArrayGet(cUnit, mir, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
871 break;
872 case Instruction::AGET:
873 case Instruction::AGET_OBJECT:
874 genArrayGet(cUnit, mir, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
875 break;
876 case Instruction::AGET_BOOLEAN:
877 genArrayGet(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
878 break;
879 case Instruction::AGET_BYTE:
880 genArrayGet(cUnit, mir, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
881 break;
882 case Instruction::AGET_CHAR:
883 genArrayGet(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
884 break;
885 case Instruction::AGET_SHORT:
886 genArrayGet(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
887 break;
888 case Instruction::APUT_WIDE:
889 genArrayPut(cUnit, mir, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
890 break;
891 case Instruction::APUT:
892 genArrayPut(cUnit, mir, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
893 break;
894 case Instruction::APUT_OBJECT:
895 genArrayObjPut(cUnit, mir, rlSrc[1], rlSrc[2], rlSrc[0], 2);
896 break;
897 case Instruction::APUT_SHORT:
898 case Instruction::APUT_CHAR:
899 genArrayPut(cUnit, mir, kUnsignedHalf, rlSrc[1], rlSrc[2], rlSrc[0], 1);
900 break;
901 case Instruction::APUT_BYTE:
902 case Instruction::APUT_BOOLEAN:
903 genArrayPut(cUnit, mir, kUnsignedByte, rlSrc[1], rlSrc[2],
904 rlSrc[0], 0);
905 break;
906
907 case Instruction::IGET_OBJECT:
908 //case Instruction::IGET_OBJECT_VOLATILE:
909 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, true);
910 break;
911
912 case Instruction::IGET_WIDE:
913 //case Instruction::IGET_WIDE_VOLATILE:
914 genIGet(cUnit, mir, kLong, rlDest, rlSrc[0], true, false);
915 break;
916
917 case Instruction::IGET:
918 //case Instruction::IGET_VOLATILE:
919 genIGet(cUnit, mir, kWord, rlDest, rlSrc[0], false, false);
920 break;
921
922 case Instruction::IGET_CHAR:
923 genIGet(cUnit, mir, kUnsignedHalf, rlDest, rlSrc[0], false, false);
924 break;
925
926 case Instruction::IGET_SHORT:
927 genIGet(cUnit, mir, kSignedHalf, rlDest, rlSrc[0], false, false);
928 break;
929
930 case Instruction::IGET_BOOLEAN:
931 case Instruction::IGET_BYTE:
932 genIGet(cUnit, mir, kUnsignedByte, rlDest, rlSrc[0], false, false);
933 break;
934
935 case Instruction::IPUT_WIDE:
936 //case Instruction::IPUT_WIDE_VOLATILE:
937 genIPut(cUnit, mir, kLong, rlSrc[0], rlSrc[1], true, false);
938 break;
939
940 case Instruction::IPUT_OBJECT:
941 //case Instruction::IPUT_OBJECT_VOLATILE:
942 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, true);
943 break;
944
945 case Instruction::IPUT:
946 //case Instruction::IPUT_VOLATILE:
947 genIPut(cUnit, mir, kWord, rlSrc[0], rlSrc[1], false, false);
948 break;
949
950 case Instruction::IPUT_BOOLEAN:
951 case Instruction::IPUT_BYTE:
952 genIPut(cUnit, mir, kUnsignedByte, rlSrc[0], rlSrc[1], false, false);
953 break;
954
955 case Instruction::IPUT_CHAR:
956 genIPut(cUnit, mir, kUnsignedHalf, rlSrc[0], rlSrc[1], false, false);
957 break;
958
959 case Instruction::IPUT_SHORT:
960 genIPut(cUnit, mir, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
961 break;
962
963 case Instruction::SGET_OBJECT:
964 genSget(cUnit, mir, rlDest, false, true);
965 break;
966 case Instruction::SGET:
967 case Instruction::SGET_BOOLEAN:
968 case Instruction::SGET_BYTE:
969 case Instruction::SGET_CHAR:
970 case Instruction::SGET_SHORT:
971 genSget(cUnit, mir, rlDest, false, false);
972 break;
973
974 case Instruction::SGET_WIDE:
975 genSget(cUnit, mir, rlDest, true, false);
976 break;
977
978 case Instruction::SPUT_OBJECT:
979 genSput(cUnit, mir, rlSrc[0], false, true);
980 break;
981
982 case Instruction::SPUT:
983 case Instruction::SPUT_BOOLEAN:
984 case Instruction::SPUT_BYTE:
985 case Instruction::SPUT_CHAR:
986 case Instruction::SPUT_SHORT:
987 genSput(cUnit, mir, rlSrc[0], false, false);
988 break;
989
990 case Instruction::SPUT_WIDE:
991 genSput(cUnit, mir, rlSrc[0], true, false);
992 break;
993
buzbee2cfc6392012-05-07 14:51:40 -0700994 case Instruction::NEG_INT:
995 case Instruction::NOT_INT:
996 res = genArithOpInt(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
997 break;
998
999 case Instruction::NEG_LONG:
1000 case Instruction::NOT_LONG:
1001 res = genArithOpLong(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1002 break;
1003
1004 case Instruction::NEG_FLOAT:
1005 res = genArithOpFloat(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1006 break;
1007
1008 case Instruction::NEG_DOUBLE:
1009 res = genArithOpDouble(cUnit, mir, rlDest, rlSrc[0], rlSrc[0]);
1010 break;
1011
1012 case Instruction::INT_TO_LONG:
1013 genIntToLong(cUnit, mir, rlDest, rlSrc[0]);
1014 break;
1015
1016 case Instruction::LONG_TO_INT:
1017 rlSrc[0] = oatUpdateLocWide(cUnit, rlSrc[0]);
1018 rlSrc[0] = oatWideToNarrow(cUnit, rlSrc[0]);
1019 storeValue(cUnit, rlDest, rlSrc[0]);
1020 break;
1021
1022 case Instruction::INT_TO_BYTE:
1023 case Instruction::INT_TO_SHORT:
1024 case Instruction::INT_TO_CHAR:
1025 genIntNarrowing(cUnit, mir, rlDest, rlSrc[0]);
1026 break;
1027
1028 case Instruction::INT_TO_FLOAT:
1029 case Instruction::INT_TO_DOUBLE:
1030 case Instruction::LONG_TO_FLOAT:
1031 case Instruction::LONG_TO_DOUBLE:
1032 case Instruction::FLOAT_TO_INT:
1033 case Instruction::FLOAT_TO_LONG:
1034 case Instruction::FLOAT_TO_DOUBLE:
1035 case Instruction::DOUBLE_TO_INT:
1036 case Instruction::DOUBLE_TO_LONG:
1037 case Instruction::DOUBLE_TO_FLOAT:
1038 genConversion(cUnit, mir);
1039 break;
1040
1041#endif
1042
1043 default:
1044 res = true;
1045 }
buzbeeb03f4872012-06-11 15:22:11 -07001046 if (objectDefinition) {
1047 setShadowFrameEntry(cUnit, (llvm::Value*)
1048 cUnit->llvmValues.elemList[rlDest.origSReg]);
1049 }
buzbee2cfc6392012-05-07 14:51:40 -07001050 return res;
1051}
1052
1053/* Extended MIR instructions like PHI */
1054void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1055 llvm::BasicBlock* llvmBB)
1056{
1057
1058 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1059 case kMirOpPhi: {
1060 int* incoming = (int*)mir->dalvikInsn.vB;
1061 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
1062 llvm::Type* phiType =
1063 llvmTypeFromLocRec(cUnit, rlDest);
1064 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1065 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1066 RegLocation loc;
1067 if (rlDest.wide) {
buzbee15bf9802012-06-12 17:49:27 -07001068 loc = oatGetSrcWide(cUnit, mir, i);
buzbee2cfc6392012-05-07 14:51:40 -07001069 i++;
1070 } else {
1071 loc = oatGetSrc(cUnit, mir, i);
1072 }
1073 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
1074 getLLVMBlock(cUnit, incoming[i]));
1075 }
1076 defineValue(cUnit, phi, rlDest.origSReg);
1077 break;
1078 }
1079 case kMirOpCopy: {
1080 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1081 break;
1082 }
1083#if defined(TARGET_ARM)
1084 case kMirOpFusedCmplFloat:
1085 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1086 break;
1087 case kMirOpFusedCmpgFloat:
1088 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1089 break;
1090 case kMirOpFusedCmplDouble:
1091 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1092 break;
1093 case kMirOpFusedCmpgDouble:
1094 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1095 break;
1096 case kMirOpFusedCmpLong:
1097 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1098 break;
1099#endif
1100 default:
1101 break;
1102 }
1103}
1104
1105void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1106{
1107 cUnit->currentDalvikOffset = offset;
1108 llvm::SmallVector<llvm::Value*, 1>arrayRef;
1109 arrayRef.push_back(cUnit->irb->getInt32(offset));
1110 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1111 cUnit->irb->SetDexOffset(node);
1112}
1113
1114// Attach method info as metadata to special intrinsic
1115void setMethodInfo(CompilationUnit* cUnit)
1116{
1117 // We don't want dex offset on this
1118 cUnit->irb->SetDexOffset(NULL);
1119 greenland::IntrinsicHelper::IntrinsicId id;
1120 id = greenland::IntrinsicHelper::MethodInfo;
1121 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1122 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1123 llvm::SmallVector<llvm::Value*, 2> regInfo;
1124 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1125 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1126 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1127 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1128 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1129 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1130 inst->setMetadata("RegInfo", regInfoNode);
1131 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1132 llvm::SmallVector<llvm::Value*, 50> pmap;
1133 for (int i = 0; i < promoSize; i++) {
1134 PromotionMap* p = &cUnit->promotionMap[i];
1135 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1136 ((p->fpReg & 0xff) << 16) |
1137 ((p->coreReg & 0xff) << 8) |
1138 ((p->fpLocation & 0xf) << 4) |
1139 (p->coreLocation & 0xf);
1140 pmap.push_back(cUnit->irb->getInt32(mapData));
1141 }
1142 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1143 inst->setMetadata("PromotionMap", mapNode);
1144 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1145}
1146
1147/* Handle the content in each basic block */
1148bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1149{
1150 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
1151 cUnit->irb->SetInsertPoint(llvmBB);
1152 setDexOffset(cUnit, bb->startOffset);
1153
1154 if (bb->blockType == kEntryBlock) {
1155 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001156 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1157 cUnit->numDalvikRegisters, true,
1158 kAllocMisc);
1159 for (int i = 0; i < cUnit->numSSARegs; i++) {
1160 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1161 }
1162 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1163 if (canBeRef[i]) {
1164 cUnit->numShadowFrameEntries++;
1165 }
1166 }
1167 if (cUnit->numShadowFrameEntries > 0) {
1168 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1169 cUnit->numShadowFrameEntries, true,
1170 kAllocMisc);
1171 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1172 if (canBeRef[i]) {
1173 cUnit->shadowMap[j++] = i;
1174 }
1175 }
1176 greenland::IntrinsicHelper::IntrinsicId id =
1177 greenland::IntrinsicHelper::AllocaShadowFrame;
1178 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1179 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1180 cUnit->irb->CreateCall(func, entries);
1181 }
buzbee2cfc6392012-05-07 14:51:40 -07001182 } else if (bb->blockType == kExitBlock) {
1183 /*
1184 * Because of the differences between how MIR/LIR and llvm handle exit
1185 * blocks, we won't explicitly covert them. On the llvm-to-lir
1186 * path, it will need to be regenereated.
1187 */
1188 return false;
buzbee6969d502012-06-15 16:40:31 -07001189 } else if (bb->blockType == kExceptionHandling) {
1190 /*
1191 * Because we're deferring null checking, delete the associated empty
1192 * exception block.
1193 * TODO: add new block type for exception blocks that we generate
1194 * greenland code for.
1195 */
1196 llvmBB->eraseFromParent();
1197 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001198 }
1199
1200 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1201
1202 setDexOffset(cUnit, mir->offset);
1203
1204 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
1205 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
1206
1207 /* If we're compiling for the debugger, generate an update callout */
1208 if (cUnit->genDebugger) {
1209 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1210 //genDebuggerUpdate(cUnit, mir->offset);
1211 }
1212
1213 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
1214 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1215 continue;
1216 }
1217
1218 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1219 NULL /* labelList */);
1220 if (notHandled) {
1221 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
1222 mir->offset, dalvikOpcode,
1223 Instruction::Name(dalvikOpcode),
1224 dalvikFormat);
1225 }
1226 }
1227
buzbee6969d502012-06-15 16:40:31 -07001228 if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001229 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1230 }
1231
1232 return false;
1233}
1234
1235llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1236
1237 // Get return type
1238 llvm::Type* ret_type = cUnit->irb->GetJType(cUnit->shorty[0],
1239 greenland::kAccurate);
1240
1241 // Get argument type
1242 std::vector<llvm::Type*> args_type;
1243
1244 // method object
1245 args_type.push_back(cUnit->irb->GetJMethodTy());
1246
1247 // Do we have a "this"?
1248 if ((cUnit->access_flags & kAccStatic) == 0) {
1249 args_type.push_back(cUnit->irb->GetJObjectTy());
1250 }
1251
1252 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
1253 args_type.push_back(cUnit->irb->GetJType(cUnit->shorty[i],
1254 greenland::kAccurate));
1255 }
1256
1257 return llvm::FunctionType::get(ret_type, args_type, false);
1258}
1259
1260bool createFunction(CompilationUnit* cUnit) {
1261 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1262 /* with_signature */ false));
1263 llvm::FunctionType* func_type = getFunctionType(cUnit);
1264
1265 if (func_type == NULL) {
1266 return false;
1267 }
1268
1269 cUnit->func = llvm::Function::Create(func_type,
1270 llvm::Function::ExternalLinkage,
1271 func_name, cUnit->module);
1272
1273 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1274 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1275
1276 arg_iter->setName("method");
1277 ++arg_iter;
1278
1279 int startSReg = cUnit->numRegs;
1280
1281 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1282 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1283 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1284 }
1285
1286 return true;
1287}
1288
1289bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1290{
1291 // Skip the exit block
1292 if (bb->blockType == kExitBlock) {
1293 cUnit->idToBlockMap.Put(bb->id, NULL);
1294 } else {
1295 int offset = bb->startOffset;
1296 bool entryBlock = (bb->blockType == kEntryBlock);
1297 llvm::BasicBlock* llvmBB =
1298 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
1299 StringPrintf(labelFormat, offset, bb->id),
1300 cUnit->func);
1301 if (entryBlock) {
1302 cUnit->entryBB = llvmBB;
1303 cUnit->placeholderBB =
1304 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
1305 cUnit->func);
1306 }
1307 cUnit->idToBlockMap.Put(bb->id, llvmBB);
1308 }
1309 return false;
1310}
1311
1312
1313/*
1314 * Convert MIR to LLVM_IR
1315 * o For each ssa name, create LLVM named value. Type these
1316 * appropriately, and ignore high half of wide and double operands.
1317 * o For each MIR basic block, create an LLVM basic block.
1318 * o Iterate through the MIR a basic block at a time, setting arguments
1319 * to recovered ssa name.
1320 */
1321void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
1322{
1323 initIR(cUnit);
1324 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
1325
1326 // Create the function
1327 createFunction(cUnit);
1328
1329 // Create an LLVM basic block for each MIR block in dfs preorder
1330 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
1331 kPreOrderDFSTraversal, false /* isIterative */);
1332 /*
1333 * Create an llvm named value for each MIR SSA name. Note: we'll use
1334 * placeholders for all non-argument values (because we haven't seen
1335 * the definition yet).
1336 */
1337 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
1338 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1339 arg_iter++; /* Skip path method */
1340 for (int i = 0; i < cUnit->numSSARegs; i++) {
1341 llvm::Value* val;
1342 llvm::Type* ty = llvmTypeFromLocRec(cUnit, cUnit->regLocation[i]);
1343 if (i < cUnit->numRegs) {
1344 // Skip non-argument _0 names - should never be a use
1345 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)0);
1346 } else if (i >= (cUnit->numRegs + cUnit->numIns)) {
1347 // Handle SSA defs, skipping Method* and compiler temps
1348 if (SRegToVReg(cUnit, i) < 0) {
1349 val = NULL;
1350 } else {
1351 val = cUnit->irb->CreateLoad(cUnit->irb->CreateAlloca(ty, 0));
1352 val->setName(llvmSSAName(cUnit, i));
1353 }
1354 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
1355 if (cUnit->regLocation[i].wide) {
1356 // Skip high half of wide values
1357 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
1358 i++;
1359 }
1360 } else {
1361 // Recover previously-created argument values
1362 llvm::Value* argVal = arg_iter++;
1363 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
1364 }
1365 }
1366 cUnit->irb->CreateBr(cUnit->placeholderBB);
1367
1368 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
1369 kPreOrderDFSTraversal, false /* Iterative */);
1370
1371 cUnit->placeholderBB->eraseFromParent();
1372
1373 llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction);
1374
buzbee6969d502012-06-15 16:40:31 -07001375 // Write bitcode to file
1376 std::string errmsg;
buzbee2cfc6392012-05-07 14:51:40 -07001377
buzbee6969d502012-06-15 16:40:31 -07001378 llvm::OwningPtr<llvm::tool_output_file> out_file(
buzbee2cfc6392012-05-07 14:51:40 -07001379 new llvm::tool_output_file("/tmp/foo.bc", errmsg,
1380 llvm::raw_fd_ostream::F_Binary));
1381
buzbee6969d502012-06-15 16:40:31 -07001382 if (!errmsg.empty()) {
1383 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
1384 }
buzbee2cfc6392012-05-07 14:51:40 -07001385
buzbee6969d502012-06-15 16:40:31 -07001386 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
1387 out_file->keep();
buzbee2cfc6392012-05-07 14:51:40 -07001388}
1389
1390RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
1391 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07001392 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001393 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
1394 if (it == cUnit->locMap.end()) {
1395 const char* valName = val->getName().str().c_str();
1396 DCHECK(valName != NULL);
1397 DCHECK(strlen(valName) > 0);
1398 if (valName[0] == 'v') {
1399 int baseSReg = INVALID_SREG;
1400 sscanf(valName, "v%d_", &baseSReg);
1401 res = cUnit->regLocation[baseSReg];
1402 cUnit->locMap.Put(val, res);
1403 } else {
1404 UNIMPLEMENTED(WARNING) << "Need to handle llvm temps";
1405 DCHECK(valName[0] == 't');
1406 }
1407 } else {
1408 res = it->second;
1409 }
1410 return res;
1411}
1412
1413Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
1414{
1415 Instruction::Code res = Instruction::NOP;
1416 if (isWide) {
1417 switch(op) {
1418 case kOpAdd: res = Instruction::ADD_LONG; break;
1419 case kOpSub: res = Instruction::SUB_LONG; break;
1420 case kOpMul: res = Instruction::MUL_LONG; break;
1421 case kOpDiv: res = Instruction::DIV_LONG; break;
1422 case kOpRem: res = Instruction::REM_LONG; break;
1423 case kOpAnd: res = Instruction::AND_LONG; break;
1424 case kOpOr: res = Instruction::OR_LONG; break;
1425 case kOpXor: res = Instruction::XOR_LONG; break;
1426 case kOpLsl: res = Instruction::SHL_LONG; break;
1427 case kOpLsr: res = Instruction::USHR_LONG; break;
1428 case kOpAsr: res = Instruction::SHR_LONG; break;
1429 default: LOG(FATAL) << "Unexpected OpKind " << op;
1430 }
1431 } else if (isConst){
1432 switch(op) {
1433 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
1434 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
1435 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
1436 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
1437 case kOpRem: res = Instruction::REM_INT_LIT16; break;
1438 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
1439 case kOpOr: res = Instruction::OR_INT_LIT16; break;
1440 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
1441 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
1442 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
1443 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
1444 default: LOG(FATAL) << "Unexpected OpKind " << op;
1445 }
1446 } else {
1447 switch(op) {
1448 case kOpAdd: res = Instruction::ADD_INT; break;
1449 case kOpSub: res = Instruction::SUB_INT; break;
1450 case kOpMul: res = Instruction::MUL_INT; break;
1451 case kOpDiv: res = Instruction::DIV_INT; break;
1452 case kOpRem: res = Instruction::REM_INT; break;
1453 case kOpAnd: res = Instruction::AND_INT; break;
1454 case kOpOr: res = Instruction::OR_INT; break;
1455 case kOpXor: res = Instruction::XOR_INT; break;
1456 case kOpLsl: res = Instruction::SHL_INT; break;
1457 case kOpLsr: res = Instruction::USHR_INT; break;
1458 case kOpAsr: res = Instruction::SHR_INT; break;
1459 default: LOG(FATAL) << "Unexpected OpKind " << op;
1460 }
1461 }
1462 return res;
1463}
1464
1465void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
1466{
1467 RegLocation rlDest = getLoc(cUnit, inst);
1468 llvm::Value* lhs = inst->getOperand(0);
1469 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
1470 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
1471 llvm::Value* rhs = inst->getOperand(1);
1472 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
1473 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
1474 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, src2->getSExtValue());
1475 } else {
1476 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
1477 RegLocation rlSrc2 = getLoc(cUnit, rhs);
1478 if (rlDest.wide) {
1479 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1480 } else {
1481 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
1482 }
1483 }
1484}
1485
1486void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
1487{
1488 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
1489 DCHECK(brInst != NULL);
1490 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
1491 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
1492 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
1493}
1494
1495void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
1496{
1497 // Nop - these have already been processed
1498}
1499
1500void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
1501{
1502 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
1503 llvm::Value* retVal = retInst->getReturnValue();
1504 if (retVal != NULL) {
1505 RegLocation rlSrc = getLoc(cUnit, retVal);
1506 if (rlSrc.wide) {
1507 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
1508 } else {
1509 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
1510 }
1511 }
1512 genExitSequence(cUnit);
1513}
1514
1515ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
1516{
1517 ConditionCode res = kCondAl;
1518 switch(llvmCond) {
1519 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
buzbee6969d502012-06-15 16:40:31 -07001520 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee2cfc6392012-05-07 14:51:40 -07001521 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
1522 default: LOG(FATAL) << "Unexpected llvm condition";
1523 }
1524 return res;
1525}
1526
1527void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
1528{
1529 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
1530 UNIMPLEMENTED(FATAL);
1531}
1532
1533void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
1534 llvm::BranchInst* brInst)
1535{
1536 // Get targets
1537 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
1538 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
1539 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
1540 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
1541 // Get comparison operands
1542 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
1543 ConditionCode cond = getCond(iCmpInst->getPredicate());
1544 llvm::Value* lhs = iCmpInst->getOperand(0);
1545 // Not expecting a constant as 1st operand
1546 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
1547 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
1548 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
1549 llvm::Value* rhs = inst->getOperand(1);
1550#if defined(TARGET_MIPS)
1551 // Compare and branch in one shot
1552 (void)taken;
1553 (void)cond;
1554 (void)rhs;
1555 UNIMPLEMENTED(FATAL);
1556#else
1557 //Compare, then branch
1558 // TODO: handle fused CMP_LONG/IF_xxZ case
1559 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
1560 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
1561 } else {
1562 RegLocation rlSrc2 = getLoc(cUnit, rhs);
1563 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
1564 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
1565 }
1566 opCondBranch(cUnit, cond, taken);
1567#endif
1568 // Fallthrough
1569 opUnconditionalBranch(cUnit, fallThrough);
1570}
1571
1572void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
1573 llvm::Function* callee)
1574{
1575 UNIMPLEMENTED(FATAL);
1576}
1577
1578void setMethodInfo(CompilationUnit* cUnit, llvm::CallInst* callInst)
1579{
1580 UNIMPLEMENTED(WARNING) << "Net setMethodInfo";
1581}
1582
1583void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
1584{
1585 DCHECK(callInst->getNumArgOperands() == 1);
1586 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
1587 RegLocation rlDest = getLoc(cUnit, callInst);
1588 if (rlSrc.wide) {
1589 storeValueWide(cUnit, rlDest, rlSrc);
1590 } else {
1591 storeValue(cUnit, rlDest, rlSrc);
1592 }
1593}
1594
1595// Note: Immediate arg is a ConstantInt regardless of result type
1596void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
1597{
1598 DCHECK(callInst->getNumArgOperands() == 1);
1599 llvm::ConstantInt* src =
1600 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1601 uint64_t immval = src->getZExtValue();
1602 RegLocation rlDest = getLoc(cUnit, callInst);
1603 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
1604 if (rlDest.wide) {
1605 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
1606 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
1607 storeValueWide(cUnit, rlDest, rlResult);
1608 } else {
1609 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
1610 storeValue(cUnit, rlDest, rlResult);
1611 }
1612}
1613
buzbee6969d502012-06-15 16:40:31 -07001614void cvtConstString(CompilationUnit* cUnit, llvm::CallInst* callInst)
1615{
1616 DCHECK(callInst->getNumArgOperands() == 1);
1617 llvm::ConstantInt* stringIdxVal =
1618 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1619 uint32_t stringIdx = stringIdxVal->getZExtValue();
1620 RegLocation rlDest = getLoc(cUnit, callInst);
1621 genConstString(cUnit, stringIdx, rlDest);
1622}
1623
1624void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
1625 greenland::JType jtype)
1626{
1627 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
1628 kAllocMisc);
1629 if (jtype == greenland::kVoid) {
1630 info->result.location = kLocInvalid;
1631 } else {
1632 info->result = getLoc(cUnit, callInst);
1633 }
1634 llvm::ConstantInt* invokeTypeVal =
1635 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
1636 llvm::ConstantInt* methodIndexVal =
1637 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
1638 llvm::ConstantInt* optFlagsVal =
1639 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
1640 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
1641 info->index = methodIndexVal->getZExtValue();
1642 info->optFlags = optFlagsVal->getZExtValue();
1643 info->offset = cUnit->currentDalvikOffset;
1644
1645 // FIXME - rework such that we no longer need isRange
1646 info->isRange = false;
1647
1648 // Count the argument words, and then build argument array.
1649 info->numArgWords = 0;
1650 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
1651 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
1652 info->numArgWords += tLoc.wide ? 2 : 1;
1653 }
1654 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
1655 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
1656 // Now, fill in the location records, synthesizing high loc of wide vals
1657 for (int i = 3, next = 0; next < info->numArgWords;) {
1658 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i));
1659 if (cUnit->printMe) {
1660 oatDumpRegLoc(info->args[next]);
1661 }
1662 if (info->args[next].wide) {
1663 next++;
1664 // TODO: Might make sense to mark this as an invalid loc
1665 info->args[next].origSReg = info->args[next-1].origSReg+1;
1666 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
1667 }
1668 next++;
1669 }
1670 genInvoke(cUnit, info);
1671}
1672
buzbee2cfc6392012-05-07 14:51:40 -07001673bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
1674{
1675 bool isEntry = (bb == &cUnit->func->getEntryBlock());
1676 // Define the starting label
1677 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
1678 // Extract the starting offset from the block's name
1679 if (!isEntry) {
1680 const char* blockName = bb->getName().str().c_str();
1681 int dummy;
1682 sscanf(blockName, labelFormat, &blockLabel->operands[0], &dummy);
1683 }
1684 // Set the label kind
1685 blockLabel->opcode = kPseudoNormalBlockLabel;
1686 // Insert the label
1687 oatAppendLIR(cUnit, blockLabel);
1688
1689 // Free temp registers and reset redundant store tracking */
1690 oatResetRegPool(cUnit);
1691 oatResetDefTracking(cUnit);
1692
1693 //TODO: restore oat incoming liveness optimization
1694 oatClobberAllRegs(cUnit);
1695
buzbee6969d502012-06-15 16:40:31 -07001696 LIR* headLIR = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07001697
1698 if (isEntry) {
1699 cUnit->currentDalvikOffset = 0;
1700 genEntrySequence(cUnit);
1701 }
1702
1703 // Visit all of the instructions in the block
1704 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
1705 llvm::Instruction* inst = it;
1706 llvm::BasicBlock::iterator nextIt = ++it;
1707 // Extract the Dalvik offset from the instruction
1708 uint32_t opcode = inst->getOpcode();
1709 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
1710 if (dexOffsetNode != NULL) {
1711 llvm::ConstantInt* dexOffsetValue =
1712 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
1713 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
1714 }
1715
buzbee6969d502012-06-15 16:40:31 -07001716 oatResetRegPool(cUnit);
1717 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
1718 oatClobberAllRegs(cUnit);
1719 }
1720
1721 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
1722 oatResetDefTracking(cUnit);
1723 }
1724
1725#ifndef NDEBUG
1726 /* Reset temp tracking sanity check */
1727 cUnit->liveSReg = INVALID_SREG;
1728#endif
1729
1730 LIR* boundaryLIR;
1731 const char* instStr = "boundary";
1732 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
1733 (intptr_t) instStr);
1734 cUnit->boundaryMap.Overwrite(cUnit->currentDalvikOffset, boundaryLIR);
1735
1736 /* Remember the first LIR for thisl block*/
1737 if (headLIR == NULL) {
1738 headLIR = boundaryLIR;
1739 headLIR->defMask = ENCODE_ALL;
1740 }
1741
buzbee2cfc6392012-05-07 14:51:40 -07001742 switch(opcode) {
1743
1744 case llvm::Instruction::ICmp: {
1745 llvm::Instruction* nextInst = nextIt;
1746 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
1747 if (brInst != NULL /* and... */) {
1748 cvtICmpBr(cUnit, inst, brInst);
1749 ++it;
1750 } else {
1751 cvtICmp(cUnit, inst);
1752 }
1753 }
1754 break;
1755
1756 case llvm::Instruction::Call: {
1757 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
1758 llvm::Function* callee = callInst->getCalledFunction();
1759 greenland::IntrinsicHelper::IntrinsicId id =
1760 cUnit->intrinsic_helper->GetIntrinsicId(callee);
1761 switch (id) {
buzbeeb03f4872012-06-11 15:22:11 -07001762 case greenland::IntrinsicHelper::AllocaShadowFrame:
1763 case greenland::IntrinsicHelper::SetShadowFrameEntry:
buzbee6969d502012-06-15 16:40:31 -07001764 case greenland::IntrinsicHelper::PopShadowFrame:
buzbeeb03f4872012-06-11 15:22:11 -07001765 // Ignore shadow frame stuff for quick compiler
1766 break;
buzbee2cfc6392012-05-07 14:51:40 -07001767 case greenland::IntrinsicHelper::CopyInt:
1768 case greenland::IntrinsicHelper::CopyObj:
1769 case greenland::IntrinsicHelper::CopyFloat:
1770 case greenland::IntrinsicHelper::CopyLong:
1771 case greenland::IntrinsicHelper::CopyDouble:
1772 cvtCopy(cUnit, callInst);
1773 break;
1774 case greenland::IntrinsicHelper::ConstInt:
1775 case greenland::IntrinsicHelper::ConstObj:
1776 case greenland::IntrinsicHelper::ConstLong:
1777 case greenland::IntrinsicHelper::ConstFloat:
1778 case greenland::IntrinsicHelper::ConstDouble:
1779 cvtConst(cUnit, callInst);
1780 break;
1781 case greenland::IntrinsicHelper::MethodInfo:
1782 setMethodInfo(cUnit, callInst);
1783 break;
1784 case greenland::IntrinsicHelper::CheckSuspend:
1785 genSuspendTest(cUnit, 0 /* optFlags already applied */);
1786 break;
buzbee6969d502012-06-15 16:40:31 -07001787 case greenland::IntrinsicHelper::HLInvokeInt:
1788 cvtInvoke(cUnit, callInst, greenland::kInt);
1789 break;
1790 case greenland::IntrinsicHelper::HLInvokeVoid:
1791 cvtInvoke(cUnit, callInst, greenland::kVoid);
1792 break;
1793 case greenland::IntrinsicHelper::ConstString:
1794 cvtConstString(cUnit, callInst);
1795 break;
buzbee2cfc6392012-05-07 14:51:40 -07001796 case greenland::IntrinsicHelper::UnknownId:
1797 cvtCall(cUnit, callInst, callee);
1798 break;
1799 default:
1800 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
1801 << cUnit->intrinsic_helper->GetName(id);
1802 }
1803 }
1804 break;
1805
1806 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
1807 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
1808 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
1809 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
1810 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
1811 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
1812 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
1813 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
1814 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
1815 case llvm::Instruction::Shl: cvtBinOp(cUnit, kOpLsl, inst); break;
1816 case llvm::Instruction::LShr: cvtBinOp(cUnit, kOpLsr, inst); break;
1817 case llvm::Instruction::AShr: cvtBinOp(cUnit, kOpAsr, inst); break;
1818 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
1819 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
1820
1821 case llvm::Instruction::Invoke:
1822 case llvm::Instruction::FAdd:
1823 case llvm::Instruction::FSub:
1824 case llvm::Instruction::FMul:
1825 case llvm::Instruction::FDiv:
1826 case llvm::Instruction::FRem:
1827 case llvm::Instruction::Trunc:
1828 case llvm::Instruction::ZExt:
1829 case llvm::Instruction::SExt:
1830 case llvm::Instruction::FPToUI:
1831 case llvm::Instruction::FPToSI:
1832 case llvm::Instruction::UIToFP:
1833 case llvm::Instruction::SIToFP:
1834 case llvm::Instruction::FPTrunc:
1835 case llvm::Instruction::FPExt:
1836 case llvm::Instruction::PtrToInt:
1837 case llvm::Instruction::IntToPtr:
1838 case llvm::Instruction::Switch:
1839 case llvm::Instruction::FCmp:
1840 UNIMPLEMENTED(FATAL) << "Unimplemented llvm opcode: " << opcode; break;
1841
1842 case llvm::Instruction::URem:
1843 case llvm::Instruction::UDiv:
1844 case llvm::Instruction::Resume:
1845 case llvm::Instruction::Unreachable:
1846 case llvm::Instruction::Alloca:
1847 case llvm::Instruction::GetElementPtr:
1848 case llvm::Instruction::Fence:
1849 case llvm::Instruction::AtomicCmpXchg:
1850 case llvm::Instruction::AtomicRMW:
1851 case llvm::Instruction::BitCast:
1852 case llvm::Instruction::VAArg:
1853 case llvm::Instruction::Select:
1854 case llvm::Instruction::UserOp1:
1855 case llvm::Instruction::UserOp2:
1856 case llvm::Instruction::ExtractElement:
1857 case llvm::Instruction::InsertElement:
1858 case llvm::Instruction::ShuffleVector:
1859 case llvm::Instruction::ExtractValue:
1860 case llvm::Instruction::InsertValue:
1861 case llvm::Instruction::LandingPad:
1862 case llvm::Instruction::IndirectBr:
1863 case llvm::Instruction::Load:
1864 case llvm::Instruction::Store:
1865 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
1866
1867 default:
1868 LOG(FATAL) << "Unknown llvm opcode: " << opcode; break;
1869 }
1870 }
buzbee6969d502012-06-15 16:40:31 -07001871
1872 if (headLIR != NULL) {
1873 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
1874 }
buzbee2cfc6392012-05-07 14:51:40 -07001875 return false;
1876}
1877
1878/*
1879 * Convert LLVM_IR to MIR:
1880 * o Iterate through the LLVM_IR and construct a graph using
1881 * standard MIR building blocks.
1882 * o Perform a basic-block optimization pass to remove unnecessary
1883 * store/load sequences.
1884 * o Convert the LLVM Value operands into RegLocations where applicable.
1885 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
1886 * o Perform register promotion
1887 * o Iterate through the graph a basic block at a time, generating
1888 * LIR.
1889 * o Assemble LIR as usual.
1890 * o Profit.
1891 */
1892void oatMethodBitcode2LIR(CompilationUnit* cUnit)
1893{
1894 int numBasicBlocks = cUnit->func->getBasicBlockList().size();
1895 // Allocate a list for LIR basic block labels
1896 cUnit->blockLabelList =
1897 (void*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
1898 LIR* labelList = (LIR*)cUnit->blockLabelList;
1899 int nextLabel = 0;
1900 for (llvm::Function::iterator i = cUnit->func->begin(),
1901 e = cUnit->func->end(); i != e; ++i) {
1902 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
1903 &labelList[nextLabel++]);
1904 }
1905 // Walk the blocks, generating code.
1906 for (llvm::Function::iterator i = cUnit->func->begin(),
1907 e = cUnit->func->end(); i != e; ++i) {
1908 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
1909 }
1910
1911 handleSuspendLaunchpads(cUnit);
1912
1913 handleThrowLaunchpads(cUnit);
1914
1915 handleIntrinsicLaunchpads(cUnit);
1916
1917 freeIR(cUnit);
1918}
1919
1920
1921} // namespace art
1922
1923#endif // ART_USE_QUICK_COMPILER