blob: 71921d00a7a4be380cbdcdaf5d6ab090c315d3ba [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
buzbeef58c12c2012-07-03 15:06:29 -0700143llvm::BasicBlock* findCaseTarget(CompilationUnit* cUnit, uint32_t vaddr)
144{
145 BasicBlock* bb = oatFindBlock(cUnit, vaddr);
146 DCHECK(bb != NULL);
147 return getLLVMBlock(cUnit, bb->id);
148}
149
150void convertPackedSwitch(CompilationUnit* cUnit, BasicBlock* bb,
151 int32_t tableOffset, RegLocation rlSrc)
152{
153 const Instruction::PackedSwitchPayload* payload =
154 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
155 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
156
157 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
158
159 llvm::SwitchInst* sw =
160 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
161 payload->case_count);
162
163 for (uint16_t i = 0; i < payload->case_count; ++i) {
164 llvm::BasicBlock* llvmBB =
165 findCaseTarget(cUnit, cUnit->currentDalvikOffset + payload->targets[i]);
166 sw->addCase(cUnit->irb->getInt32(payload->first_key + i), llvmBB);
167 }
168 llvm::MDNode* switchNode =
169 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
170 sw->setMetadata("SwitchTable", switchNode);
171 bb->taken = NULL;
172 bb->fallThrough = NULL;
173}
174
buzbee8fa0fda2012-06-27 15:44:52 -0700175void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
176 greenland::IntrinsicHelper::IntrinsicId id,
177 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700178{
buzbee8fa0fda2012-06-27 15:44:52 -0700179 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700180 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700181 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
182 defineValue(cUnit, res, rlDest.origSReg);
183}
184
185void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
186 greenland::IntrinsicHelper::IntrinsicId id,
187 RegLocation rlSrc)
188{
189 llvm::SmallVector<llvm::Value*, 2> args;
190 args.push_back(cUnit->irb->getInt32(fieldIndex));
191 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
192 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
193 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700194}
195
buzbee101305f2012-06-28 18:00:56 -0700196void convertFillArrayData(CompilationUnit* cUnit, int32_t offset,
197 RegLocation rlArray)
198{
199 greenland::IntrinsicHelper::IntrinsicId id;
200 id = greenland::IntrinsicHelper::FillArrayData;
201 llvm::SmallVector<llvm::Value*, 2> args;
202 args.push_back(cUnit->irb->getInt32(offset));
203 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
204 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
205 cUnit->irb->CreateCall(intr, args);
206}
207
buzbee2cfc6392012-05-07 14:51:40 -0700208llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
209 RegLocation loc)
210{
211 greenland::IntrinsicHelper::IntrinsicId id;
212 if (loc.wide) {
213 if (loc.fp) {
214 id = greenland::IntrinsicHelper::ConstDouble;
215 } else {
216 id = greenland::IntrinsicHelper::ConstLong;
217 }
218 } else {
219 if (loc.fp) {
220 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700221 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700222 id = greenland::IntrinsicHelper::ConstObj;
223 } else {
224 id = greenland::IntrinsicHelper::ConstInt;
225 }
226 }
227 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
228 return cUnit->irb->CreateCall(intr, src);
229}
buzbeeb03f4872012-06-11 15:22:11 -0700230
231void emitPopShadowFrame(CompilationUnit* cUnit)
232{
233 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
234 greenland::IntrinsicHelper::PopShadowFrame);
235 cUnit->irb->CreateCall(intr);
236}
237
buzbee2cfc6392012-05-07 14:51:40 -0700238llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
239 RegLocation loc)
240{
241 greenland::IntrinsicHelper::IntrinsicId id;
242 if (loc.wide) {
243 if (loc.fp) {
244 id = greenland::IntrinsicHelper::CopyDouble;
245 } else {
246 id = greenland::IntrinsicHelper::CopyLong;
247 }
248 } else {
249 if (loc.fp) {
250 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700251 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700252 id = greenland::IntrinsicHelper::CopyObj;
253 } else {
254 id = greenland::IntrinsicHelper::CopyInt;
255 }
256 }
257 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
258 return cUnit->irb->CreateCall(intr, src);
259}
260
buzbee32412962012-06-26 16:27:56 -0700261void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
262{
263 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
264 greenland::IntrinsicHelper::GetException);
265 llvm::Value* res = cUnit->irb->CreateCall(func);
266 defineValue(cUnit, res, rlDest.origSReg);
267}
268
269void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
270{
271 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
272 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
273 greenland::IntrinsicHelper::Throw);
274 cUnit->irb->CreateCall(func, src);
275 cUnit->irb->CreateUnreachable();
276}
277
buzbee8fa0fda2012-06-27 15:44:52 -0700278void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
279 greenland::IntrinsicHelper::IntrinsicId id,
280 RegLocation rlSrc)
281{
282 llvm::SmallVector<llvm::Value*, 2> args;
283 args.push_back(cUnit->irb->getInt32(optFlags));
284 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
285 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
286 cUnit->irb->CreateCall(func, args);
287}
288
buzbee76592632012-06-29 15:18:35 -0700289void convertArrayLength(CompilationUnit* cUnit, int optFlags,
290 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700291{
292 llvm::SmallVector<llvm::Value*, 2> args;
293 args.push_back(cUnit->irb->getInt32(optFlags));
294 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
295 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
296 greenland::IntrinsicHelper::ArrayLength);
buzbee76592632012-06-29 15:18:35 -0700297 llvm::Value* res = cUnit->irb->CreateCall(func, args);
298 defineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700299}
300
buzbee32412962012-06-26 16:27:56 -0700301void convertThrowVerificationError(CompilationUnit* cUnit, int info1, int info2)
302{
303 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
304 greenland::IntrinsicHelper::Throw);
305 llvm::SmallVector<llvm::Value*, 2> args;
306 args.push_back(cUnit->irb->getInt32(info1));
307 args.push_back(cUnit->irb->getInt32(info2));
308 cUnit->irb->CreateCall(func, args);
309 cUnit->irb->CreateUnreachable();
310}
311
buzbee2cfc6392012-05-07 14:51:40 -0700312void emitSuspendCheck(CompilationUnit* cUnit)
313{
314 greenland::IntrinsicHelper::IntrinsicId id =
315 greenland::IntrinsicHelper::CheckSuspend;
316 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
317 cUnit->irb->CreateCall(intr);
318}
319
320llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
321 llvm::Value* src1, llvm::Value* src2)
322{
323 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700324 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700325 switch(cc) {
326 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
327 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
328 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
329 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
330 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
331 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
332 default: LOG(FATAL) << "Unexpected cc value " << cc;
333 }
334 return res;
335}
336
337void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
338 ConditionCode cc, RegLocation rlSrc1,
339 RegLocation rlSrc2)
340{
341 if (bb->taken->startOffset <= mir->offset) {
342 emitSuspendCheck(cUnit);
343 }
344 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
345 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
346 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
347 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
348 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
349 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700350 // Don't redo the fallthrough branch in the BB driver
351 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700352}
353
354void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
355 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
356{
357 if (bb->taken->startOffset <= mir->offset) {
358 emitSuspendCheck(cUnit);
359 }
360 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
361 llvm::Value* src2;
362 if (rlSrc1.ref) {
363 src2 = cUnit->irb->GetJNull();
364 } else {
365 src2 = cUnit->irb->getInt32(0);
366 }
367 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
buzbee2cfc6392012-05-07 14:51:40 -0700368 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
369 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700370 // Don't redo the fallthrough branch in the BB driver
371 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700372}
373
374llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
375 llvm::Value* src1, llvm::Value* src2)
376{
377 greenland::IntrinsicHelper::IntrinsicId id;
378 if (isLong) {
379 if (isDiv) {
380 id = greenland::IntrinsicHelper::DivLong;
381 } else {
382 id = greenland::IntrinsicHelper::RemLong;
383 }
384 } else if (isDiv) {
385 id = greenland::IntrinsicHelper::DivInt;
386 } else {
387 id = greenland::IntrinsicHelper::RemInt;
388 }
389 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
390 llvm::SmallVector<llvm::Value*, 2>args;
391 args.push_back(src1);
392 args.push_back(src2);
393 return cUnit->irb->CreateCall(intr, args);
394}
395
396llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
397 llvm::Value* src1, llvm::Value* src2)
398{
399 llvm::Value* res = NULL;
400 switch(op) {
401 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
402 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700403 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700404 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
405 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
406 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
407 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
408 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
409 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700410 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
411 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
412 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700413 default:
414 LOG(FATAL) << "Invalid op " << op;
415 }
416 return res;
417}
418
419void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
420 RegLocation rlSrc1, RegLocation rlSrc2)
421{
422 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
423 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
424 llvm::Value* res = NULL;
425 switch(op) {
426 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
427 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
428 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
429 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
430 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
431 default:
432 LOG(FATAL) << "Invalid op " << op;
433 }
434 defineValue(cUnit, res, rlDest.origSReg);
435}
436
buzbee4f1181f2012-06-22 13:52:12 -0700437void convertShift(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
438 RegLocation rlSrc1, RegLocation rlSrc2)
439{
440 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
buzbee101305f2012-06-28 18:00:56 -0700441 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
442 /*
443 * TODO: Figure out how best to handle constraining the shift
444 * amount to 31 for int and 63 for long. We take care of this
445 * inline for int and in the out-of-line handler for longs, so
446 * it's a bit of a waste to generate llvm bitcode for this.
447 * Yet more intrinsics?
448 */
449 UNIMPLEMENTED(WARNING) << "llvm shift mismatch";
buzbee4f1181f2012-06-22 13:52:12 -0700450 if (rlDest.wide) {
buzbee101305f2012-06-28 18:00:56 -0700451 // llvm thinks the shift could should be in 64 bits.
452 src2 = cUnit->irb->CreateZExt(src2, cUnit->irb->getInt64Ty());
buzbee4f1181f2012-06-22 13:52:12 -0700453 }
buzbee101305f2012-06-28 18:00:56 -0700454 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
buzbee4f1181f2012-06-22 13:52:12 -0700455 defineValue(cUnit, res, rlDest.origSReg);
456}
457
buzbee2cfc6392012-05-07 14:51:40 -0700458void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
459 RegLocation rlSrc1, RegLocation rlSrc2)
460{
461 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
462 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700463 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700464 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
465 defineValue(cUnit, res, rlDest.origSReg);
466}
467
buzbeeb03f4872012-06-11 15:22:11 -0700468void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
469{
470 int index = -1;
471 DCHECK(newVal != NULL);
472 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
473 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
474 if (cUnit->shadowMap[i] == vReg) {
475 index = i;
476 break;
477 }
478 }
Elliott Hughes74847412012-06-20 18:10:21 -0700479 DCHECK_NE(index, -1) << "Corrupt shadowMap";
buzbeeb03f4872012-06-11 15:22:11 -0700480 greenland::IntrinsicHelper::IntrinsicId id =
481 greenland::IntrinsicHelper::SetShadowFrameEntry;
482 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
483 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
484 llvm::Value* args[] = { newVal, tableSlot };
485 cUnit->irb->CreateCall(func, args);
486}
487
buzbee2cfc6392012-05-07 14:51:40 -0700488void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
489 RegLocation rlSrc1, int32_t imm)
490{
491 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
492 llvm::Value* src2 = cUnit->irb->getInt32(imm);
493 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
494 defineValue(cUnit, res, rlDest.origSReg);
495}
496
buzbee101305f2012-06-28 18:00:56 -0700497/*
498 * Process arguments for invoke. Note: this code is also used to
499 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
500 * The requirements are similar.
501 */
buzbee6969d502012-06-15 16:40:31 -0700502void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700503 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700504{
505 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
506 llvm::SmallVector<llvm::Value*, 10> args;
507 // Insert the invokeType
508 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
509 // Insert the method_idx
510 args.push_back(cUnit->irb->getInt32(info->index));
511 // Insert the optimization flags
512 args.push_back(cUnit->irb->getInt32(info->optFlags));
513 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700514 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700515 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
516 args.push_back(val);
517 i += info->args[i].wide ? 2 : 1;
518 }
519 /*
520 * Choose the invoke return type based on actual usage. Note: may
521 * be different than shorty. For example, if a function return value
522 * is not used, we'll treat this as a void invoke.
523 */
524 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700525 if (isFilledNewArray) {
526 id = greenland::IntrinsicHelper::FilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700527 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700528 id = greenland::IntrinsicHelper::HLInvokeVoid;
529 } else {
530 if (info->result.wide) {
531 if (info->result.fp) {
532 id = greenland::IntrinsicHelper::HLInvokeDouble;
533 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700534 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700535 }
536 } else if (info->result.ref) {
537 id = greenland::IntrinsicHelper::HLInvokeObj;
538 } else if (info->result.fp) {
539 id = greenland::IntrinsicHelper::HLInvokeFloat;
540 } else {
541 id = greenland::IntrinsicHelper::HLInvokeInt;
542 }
543 }
544 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
545 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
546 if (info->result.location != kLocInvalid) {
547 defineValue(cUnit, res, info->result.origSReg);
548 }
549}
550
buzbee101305f2012-06-28 18:00:56 -0700551void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
552 greenland::IntrinsicHelper::IntrinsicId id,
553 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700554{
buzbee6969d502012-06-15 16:40:31 -0700555 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700556 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700557 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
558 defineValue(cUnit, res, rlDest.origSReg);
559}
560
buzbee101305f2012-06-28 18:00:56 -0700561void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
562 RegLocation rlSrc)
563{
564 greenland::IntrinsicHelper::IntrinsicId id;
565 id = greenland::IntrinsicHelper::CheckCast;
566 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
567 llvm::SmallVector<llvm::Value*, 2> args;
568 args.push_back(cUnit->irb->getInt32(type_idx));
569 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
570 cUnit->irb->CreateCall(intr, args);
571}
572
buzbee8fa0fda2012-06-27 15:44:52 -0700573void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
574 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700575{
576 greenland::IntrinsicHelper::IntrinsicId id;
577 id = greenland::IntrinsicHelper::NewInstance;
578 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
579 llvm::Value* index = cUnit->irb->getInt32(type_idx);
580 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
581 defineValue(cUnit, res, rlDest.origSReg);
582}
583
buzbee8fa0fda2012-06-27 15:44:52 -0700584void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
585 RegLocation rlDest, RegLocation rlSrc)
586{
587 greenland::IntrinsicHelper::IntrinsicId id;
588 id = greenland::IntrinsicHelper::NewArray;
589 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
590 llvm::SmallVector<llvm::Value*, 2> args;
591 args.push_back(cUnit->irb->getInt32(type_idx));
592 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
593 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
594 defineValue(cUnit, res, rlDest.origSReg);
595}
596
597void convertAget(CompilationUnit* cUnit, int optFlags,
598 greenland::IntrinsicHelper::IntrinsicId id,
599 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
600{
601 llvm::SmallVector<llvm::Value*, 3> args;
602 args.push_back(cUnit->irb->getInt32(optFlags));
603 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
604 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
605 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
606 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
607 defineValue(cUnit, res, rlDest.origSReg);
608}
609
610void convertAput(CompilationUnit* cUnit, int optFlags,
611 greenland::IntrinsicHelper::IntrinsicId id,
612 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
613{
614 llvm::SmallVector<llvm::Value*, 4> args;
615 args.push_back(cUnit->irb->getInt32(optFlags));
616 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
617 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
618 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
619 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
620 cUnit->irb->CreateCall(intr, args);
621}
622
buzbee101305f2012-06-28 18:00:56 -0700623void convertIget(CompilationUnit* cUnit, int optFlags,
624 greenland::IntrinsicHelper::IntrinsicId id,
625 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
626{
627 llvm::SmallVector<llvm::Value*, 3> args;
628 args.push_back(cUnit->irb->getInt32(optFlags));
629 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
630 args.push_back(cUnit->irb->getInt32(fieldIndex));
631 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
632 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
633 defineValue(cUnit, res, rlDest.origSReg);
634}
635
636void convertIput(CompilationUnit* cUnit, int optFlags,
637 greenland::IntrinsicHelper::IntrinsicId id,
638 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
639{
640 llvm::SmallVector<llvm::Value*, 4> args;
641 args.push_back(cUnit->irb->getInt32(optFlags));
642 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
643 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
644 args.push_back(cUnit->irb->getInt32(fieldIndex));
645 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
646 cUnit->irb->CreateCall(intr, args);
647}
648
buzbee8fa0fda2012-06-27 15:44:52 -0700649void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
650 RegLocation rlDest, RegLocation rlSrc)
651{
652 greenland::IntrinsicHelper::IntrinsicId id;
653 id = greenland::IntrinsicHelper::InstanceOf;
654 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
655 llvm::SmallVector<llvm::Value*, 2> args;
656 args.push_back(cUnit->irb->getInt32(type_idx));
657 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
658 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
659 defineValue(cUnit, res, rlDest.origSReg);
660}
661
buzbee101305f2012-06-28 18:00:56 -0700662void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
663 RegLocation rlSrc)
664{
665 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
666 cUnit->irb->getInt64Ty());
667 defineValue(cUnit, res, rlDest.origSReg);
668}
669
buzbee76592632012-06-29 15:18:35 -0700670void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
671 RegLocation rlSrc)
672{
673 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
674 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
675 defineValue(cUnit, res, rlDest.origSReg);
676}
677
678void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
679 RegLocation rlSrc)
680{
681 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
682 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
683 defineValue(cUnit, res, rlDest.origSReg);
684}
685
686void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
687 RegLocation rlSrc)
688{
689 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
690 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
691 defineValue(cUnit, res, rlDest.origSReg);
692}
693
694void convertWideComparison(CompilationUnit* cUnit,
695 greenland::IntrinsicHelper::IntrinsicId id,
696 RegLocation rlDest, RegLocation rlSrc1,
697 RegLocation rlSrc2)
698{
699 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
700 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
701 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
702 llvm::SmallVector<llvm::Value*, 2> args;
703 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
704 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
705 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
706 defineValue(cUnit, res, rlDest.origSReg);
707}
708
buzbee101305f2012-06-28 18:00:56 -0700709void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
710 RegLocation rlSrc,
711 greenland::IntrinsicHelper::IntrinsicId id)
712{
713 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700714 llvm::Value* res =
715 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
716 defineValue(cUnit, res, rlDest.origSReg);
717}
718
719void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
720 RegLocation rlSrc)
721{
722 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
723 defineValue(cUnit, res, rlDest.origSReg);
724}
725
726void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
727 RegLocation rlSrc)
728{
729 llvm::Value* res =
730 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
731 defineValue(cUnit, res, rlDest.origSReg);
732}
733
734void convertFPToInt(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
735 RegLocation rlSrc)
736{
737 llvm::Value* res =
738 cUnit->irb->CreateFPToSI(getLLVMValue(cUnit, rlSrc.origSReg), ty);
739 defineValue(cUnit, res, rlDest.origSReg);
740}
741
742
743void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
744 RegLocation rlSrc)
745{
746 llvm::Value* res =
747 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
748 defineValue(cUnit, res, rlDest.origSReg);
749}
750
751void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
752 RegLocation rlSrc)
753{
754 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
755 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700756 defineValue(cUnit, res, rlDest.origSReg);
757}
758
buzbee2cfc6392012-05-07 14:51:40 -0700759/*
760 * Target-independent code generation. Use only high-level
761 * load/store utilities here, or target-dependent genXX() handlers
762 * when necessary.
763 */
764bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
765 llvm::BasicBlock* llvmBB, LIR* labelList)
766{
767 bool res = false; // Assume success
768 RegLocation rlSrc[3];
769 RegLocation rlDest = badLoc;
770 RegLocation rlResult = badLoc;
771 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee32412962012-06-26 16:27:56 -0700772 uint32_t vA = mir->dalvikInsn.vA;
buzbee6969d502012-06-15 16:40:31 -0700773 uint32_t vB = mir->dalvikInsn.vB;
774 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700775 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700776
buzbeeb03f4872012-06-11 15:22:11 -0700777 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700778
779 /* Prep Src and Dest locations */
780 int nextSreg = 0;
781 int nextLoc = 0;
782 int attrs = oatDataFlowAttributes[opcode];
783 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
784 if (attrs & DF_UA) {
785 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700786 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700787 nextSreg+= 2;
788 } else {
789 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
790 nextSreg++;
791 }
792 }
793 if (attrs & DF_UB) {
794 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700795 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700796 nextSreg+= 2;
797 } else {
798 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
799 nextSreg++;
800 }
801 }
802 if (attrs & DF_UC) {
803 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700804 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700805 } else {
806 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
807 }
808 }
809 if (attrs & DF_DA) {
810 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700811 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700812 } else {
buzbee15bf9802012-06-12 17:49:27 -0700813 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700814 if (rlDest.ref) {
815 objectDefinition = true;
816 }
buzbee2cfc6392012-05-07 14:51:40 -0700817 }
818 }
819
820 switch (opcode) {
821 case Instruction::NOP:
822 break;
823
824 case Instruction::MOVE:
825 case Instruction::MOVE_OBJECT:
826 case Instruction::MOVE_16:
827 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700828 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700829 case Instruction::MOVE_FROM16:
830 case Instruction::MOVE_WIDE:
831 case Instruction::MOVE_WIDE_16:
832 case Instruction::MOVE_WIDE_FROM16: {
833 /*
834 * Moves/copies are meaningless in pure SSA register form,
835 * but we need to preserve them for the conversion back into
836 * MIR (at least until we stop using the Dalvik register maps).
837 * Insert a dummy intrinsic copy call, which will be recognized
838 * by the quick path and removed by the portable path.
839 */
840 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
841 llvm::Value* res = emitCopy(cUnit, src, rlDest);
842 defineValue(cUnit, res, rlDest.origSReg);
843 }
844 break;
845
846 case Instruction::CONST:
847 case Instruction::CONST_4:
848 case Instruction::CONST_16: {
buzbee6969d502012-06-15 16:40:31 -0700849 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700850 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
851 defineValue(cUnit, res, rlDest.origSReg);
852 }
853 break;
854
855 case Instruction::CONST_WIDE_16:
856 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700857 // Sign extend to 64 bits
858 int64_t imm = static_cast<int32_t>(vB);
859 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700860 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
861 defineValue(cUnit, res, rlDest.origSReg);
862 }
863 break;
864
865 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700866 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700867 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
868 defineValue(cUnit, res, rlDest.origSReg);
869 }
870 break;
871
872 case Instruction::CONST_WIDE: {
873 llvm::Constant* immValue =
874 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
875 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
876 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700877 }
878 break;
buzbee2cfc6392012-05-07 14:51:40 -0700879 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700880 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700881 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
882 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
883 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700884 }
885 break;
886
buzbee8fa0fda2012-06-27 15:44:52 -0700887 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700888 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700889 rlSrc[0]);
890 break;
891 case Instruction::SPUT:
892 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700893 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700894 rlSrc[0]);
895 } else {
buzbee76592632012-06-29 15:18:35 -0700896 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700897 }
898 break;
899 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700900 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700901 rlSrc[0]);
902 break;
903 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700904 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700905 break;
906 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -0700907 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700908 break;
909 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -0700910 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700911 break;
912 case Instruction::SPUT_WIDE:
913 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700914 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -0700915 rlSrc[0]);
916 } else {
buzbee76592632012-06-29 15:18:35 -0700917 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -0700918 rlSrc[0]);
919 }
920 break;
921
922 case Instruction::SGET_OBJECT:
923 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
924 break;
925 case Instruction::SGET:
926 if (rlDest.fp) {
927 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
928 } else {
929 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
930 }
931 break;
932 case Instruction::SGET_BOOLEAN:
933 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
934 break;
935 case Instruction::SGET_BYTE:
936 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
937 break;
938 case Instruction::SGET_CHAR:
939 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
940 break;
941 case Instruction::SGET_SHORT:
942 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
943 break;
944 case Instruction::SGET_WIDE:
945 if (rlDest.fp) {
946 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
947 rlDest);
948 } else {
949 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -0700950 }
951 break;
buzbee2cfc6392012-05-07 14:51:40 -0700952
953 case Instruction::RETURN_WIDE:
954 case Instruction::RETURN:
955 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -0700956 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700957 emitSuspendCheck(cUnit);
958 }
buzbeeb03f4872012-06-11 15:22:11 -0700959 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700960 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
961 bb->hasReturn = true;
962 }
963 break;
964
965 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -0700966 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700967 emitSuspendCheck(cUnit);
968 }
buzbeeb03f4872012-06-11 15:22:11 -0700969 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700970 cUnit->irb->CreateRetVoid();
971 bb->hasReturn = true;
972 }
973 break;
974
975 case Instruction::IF_EQ:
976 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
977 break;
978 case Instruction::IF_NE:
979 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
980 break;
981 case Instruction::IF_LT:
982 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
983 break;
984 case Instruction::IF_GE:
985 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
986 break;
987 case Instruction::IF_GT:
988 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
989 break;
990 case Instruction::IF_LE:
991 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
992 break;
993 case Instruction::IF_EQZ:
994 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
995 break;
996 case Instruction::IF_NEZ:
997 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
998 break;
999 case Instruction::IF_LTZ:
1000 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1001 break;
1002 case Instruction::IF_GEZ:
1003 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1004 break;
1005 case Instruction::IF_GTZ:
1006 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1007 break;
1008 case Instruction::IF_LEZ:
1009 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1010 break;
1011
1012 case Instruction::GOTO:
1013 case Instruction::GOTO_16:
1014 case Instruction::GOTO_32: {
1015 if (bb->taken->startOffset <= bb->startOffset) {
1016 emitSuspendCheck(cUnit);
1017 }
1018 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1019 }
1020 break;
1021
1022 case Instruction::ADD_LONG:
1023 case Instruction::ADD_LONG_2ADDR:
1024 case Instruction::ADD_INT:
1025 case Instruction::ADD_INT_2ADDR:
1026 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1027 break;
1028 case Instruction::SUB_LONG:
1029 case Instruction::SUB_LONG_2ADDR:
1030 case Instruction::SUB_INT:
1031 case Instruction::SUB_INT_2ADDR:
1032 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1033 break;
1034 case Instruction::MUL_LONG:
1035 case Instruction::MUL_LONG_2ADDR:
1036 case Instruction::MUL_INT:
1037 case Instruction::MUL_INT_2ADDR:
1038 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1039 break;
1040 case Instruction::DIV_LONG:
1041 case Instruction::DIV_LONG_2ADDR:
1042 case Instruction::DIV_INT:
1043 case Instruction::DIV_INT_2ADDR:
1044 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1045 break;
1046 case Instruction::REM_LONG:
1047 case Instruction::REM_LONG_2ADDR:
1048 case Instruction::REM_INT:
1049 case Instruction::REM_INT_2ADDR:
1050 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1051 break;
1052 case Instruction::AND_LONG:
1053 case Instruction::AND_LONG_2ADDR:
1054 case Instruction::AND_INT:
1055 case Instruction::AND_INT_2ADDR:
1056 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1057 break;
1058 case Instruction::OR_LONG:
1059 case Instruction::OR_LONG_2ADDR:
1060 case Instruction::OR_INT:
1061 case Instruction::OR_INT_2ADDR:
1062 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1063 break;
1064 case Instruction::XOR_LONG:
1065 case Instruction::XOR_LONG_2ADDR:
1066 case Instruction::XOR_INT:
1067 case Instruction::XOR_INT_2ADDR:
1068 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1069 break;
1070 case Instruction::SHL_LONG:
1071 case Instruction::SHL_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001072 convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
1073 break;
buzbee2cfc6392012-05-07 14:51:40 -07001074 case Instruction::SHL_INT:
1075 case Instruction::SHL_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001076 convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001077 break;
1078 case Instruction::SHR_LONG:
1079 case Instruction::SHR_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001080 convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
1081 break;
buzbee2cfc6392012-05-07 14:51:40 -07001082 case Instruction::SHR_INT:
1083 case Instruction::SHR_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001084 convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001085 break;
1086 case Instruction::USHR_LONG:
1087 case Instruction::USHR_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001088 convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
1089 break;
buzbee2cfc6392012-05-07 14:51:40 -07001090 case Instruction::USHR_INT:
1091 case Instruction::USHR_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001092 convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001093 break;
1094
1095 case Instruction::ADD_INT_LIT16:
1096 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001097 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001098 break;
1099 case Instruction::RSUB_INT:
1100 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001101 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001102 break;
1103 case Instruction::MUL_INT_LIT16:
1104 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001105 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001106 break;
1107 case Instruction::DIV_INT_LIT16:
1108 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001109 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001110 break;
1111 case Instruction::REM_INT_LIT16:
1112 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001113 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001114 break;
1115 case Instruction::AND_INT_LIT16:
1116 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001117 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001118 break;
1119 case Instruction::OR_INT_LIT16:
1120 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001121 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001122 break;
1123 case Instruction::XOR_INT_LIT16:
1124 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001125 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001126 break;
1127 case Instruction::SHL_INT_LIT8:
buzbee4f1181f2012-06-22 13:52:12 -07001128 convertArithOpLit(cUnit, kOpLsl, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001129 break;
1130 case Instruction::SHR_INT_LIT8:
buzbee101305f2012-06-28 18:00:56 -07001131 convertArithOpLit(cUnit, kOpAsr, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001132 break;
1133 case Instruction::USHR_INT_LIT8:
buzbee101305f2012-06-28 18:00:56 -07001134 convertArithOpLit(cUnit, kOpLsr, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001135 break;
1136
1137 case Instruction::ADD_FLOAT:
1138 case Instruction::ADD_FLOAT_2ADDR:
1139 case Instruction::ADD_DOUBLE:
1140 case Instruction::ADD_DOUBLE_2ADDR:
1141 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1142 break;
1143
1144 case Instruction::SUB_FLOAT:
1145 case Instruction::SUB_FLOAT_2ADDR:
1146 case Instruction::SUB_DOUBLE:
1147 case Instruction::SUB_DOUBLE_2ADDR:
1148 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1149 break;
1150
1151 case Instruction::MUL_FLOAT:
1152 case Instruction::MUL_FLOAT_2ADDR:
1153 case Instruction::MUL_DOUBLE:
1154 case Instruction::MUL_DOUBLE_2ADDR:
1155 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1156 break;
1157
1158 case Instruction::DIV_FLOAT:
1159 case Instruction::DIV_FLOAT_2ADDR:
1160 case Instruction::DIV_DOUBLE:
1161 case Instruction::DIV_DOUBLE_2ADDR:
1162 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1163 break;
1164
1165 case Instruction::REM_FLOAT:
1166 case Instruction::REM_FLOAT_2ADDR:
1167 case Instruction::REM_DOUBLE:
1168 case Instruction::REM_DOUBLE_2ADDR:
1169 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1170 break;
1171
buzbee6969d502012-06-15 16:40:31 -07001172 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001173 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1174 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001175 break;
1176 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001177 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1178 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001179 break;
1180
1181 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001182 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1183 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001184 break;
1185 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001186 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1187 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001188 break;
1189
1190 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001191 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1192 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001193 break;
1194 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001195 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1196 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001197 break;
1198
1199 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001200 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1201 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001202 break;
1203 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001204 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1205 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001206 break;
1207
1208 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001209 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1210 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001211 break;
1212 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001213 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1214 false /* NewFilledArray */);
1215 break;
1216 case Instruction::FILLED_NEW_ARRAY:
1217 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1218 true /* NewFilledArray */);
1219 break;
1220 case Instruction::FILLED_NEW_ARRAY_RANGE:
1221 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1222 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001223 break;
1224
1225 case Instruction::CONST_STRING:
1226 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001227 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1228 rlDest);
1229 break;
1230
1231 case Instruction::CONST_CLASS:
1232 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1233 rlDest);
1234 break;
1235
1236 case Instruction::CHECK_CAST:
1237 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001238 break;
1239
buzbee4f1181f2012-06-22 13:52:12 -07001240 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001241 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001242 break;
1243
buzbee32412962012-06-26 16:27:56 -07001244 case Instruction::MOVE_EXCEPTION:
1245 convertMoveException(cUnit, rlDest);
1246 break;
1247
1248 case Instruction::THROW:
1249 convertThrow(cUnit, rlSrc[0]);
1250 break;
1251
1252 case Instruction::THROW_VERIFICATION_ERROR:
1253 convertThrowVerificationError(cUnit, vA, vB);
1254 break;
buzbee6969d502012-06-15 16:40:31 -07001255
buzbee2cfc6392012-05-07 14:51:40 -07001256 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001257 case Instruction::MOVE_RESULT:
1258 case Instruction::MOVE_RESULT_OBJECT:
buzbee8fa0fda2012-06-27 15:44:52 -07001259 CHECK(false) << "Unexpected MOVE_RESULT";
buzbee2cfc6392012-05-07 14:51:40 -07001260 break;
1261
1262 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001263 convertMonitorEnterExit(cUnit, optFlags,
1264 greenland::IntrinsicHelper::MonitorEnter,
1265 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001266 break;
1267
1268 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001269 convertMonitorEnterExit(cUnit, optFlags,
1270 greenland::IntrinsicHelper::MonitorExit,
1271 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001272 break;
1273
1274 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001275 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001276 break;
1277
1278 case Instruction::NEW_ARRAY:
1279 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1280 break;
1281
1282 case Instruction::INSTANCE_OF:
1283 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1284 break;
1285
1286 case Instruction::AGET:
1287 if (rlDest.fp) {
1288 convertAget(cUnit, optFlags,
1289 greenland::IntrinsicHelper::HLArrayGetFloat,
1290 rlDest, rlSrc[0], rlSrc[1]);
1291 } else {
1292 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1293 rlDest, rlSrc[0], rlSrc[1]);
1294 }
1295 break;
1296 case Instruction::AGET_OBJECT:
1297 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1298 rlDest, rlSrc[0], rlSrc[1]);
1299 break;
1300 case Instruction::AGET_BOOLEAN:
1301 convertAget(cUnit, optFlags,
1302 greenland::IntrinsicHelper::HLArrayGetBoolean,
1303 rlDest, rlSrc[0], rlSrc[1]);
1304 break;
1305 case Instruction::AGET_BYTE:
1306 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1307 rlDest, rlSrc[0], rlSrc[1]);
1308 break;
1309 case Instruction::AGET_CHAR:
1310 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1311 rlDest, rlSrc[0], rlSrc[1]);
1312 break;
1313 case Instruction::AGET_SHORT:
1314 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1315 rlDest, rlSrc[0], rlSrc[1]);
1316 break;
1317 case Instruction::AGET_WIDE:
1318 if (rlDest.fp) {
1319 convertAget(cUnit, optFlags,
1320 greenland::IntrinsicHelper::HLArrayGetDouble,
1321 rlDest, rlSrc[0], rlSrc[1]);
1322 } else {
1323 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1324 rlDest, rlSrc[0], rlSrc[1]);
1325 }
1326 break;
1327
1328 case Instruction::APUT:
1329 if (rlSrc[0].fp) {
1330 convertAput(cUnit, optFlags,
1331 greenland::IntrinsicHelper::HLArrayPutFloat,
1332 rlSrc[0], rlSrc[1], rlSrc[2]);
1333 } else {
1334 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1335 rlSrc[0], rlSrc[1], rlSrc[2]);
1336 }
1337 break;
1338 case Instruction::APUT_OBJECT:
1339 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1340 rlSrc[0], rlSrc[1], rlSrc[2]);
1341 break;
1342 case Instruction::APUT_BOOLEAN:
1343 convertAput(cUnit, optFlags,
1344 greenland::IntrinsicHelper::HLArrayPutBoolean,
1345 rlSrc[0], rlSrc[1], rlSrc[2]);
1346 break;
1347 case Instruction::APUT_BYTE:
1348 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1349 rlSrc[0], rlSrc[1], rlSrc[2]);
1350 break;
1351 case Instruction::APUT_CHAR:
1352 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1353 rlSrc[0], rlSrc[1], rlSrc[2]);
1354 break;
1355 case Instruction::APUT_SHORT:
1356 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1357 rlSrc[0], rlSrc[1], rlSrc[2]);
1358 break;
1359 case Instruction::APUT_WIDE:
1360 if (rlSrc[0].fp) {
1361 convertAput(cUnit, optFlags,
1362 greenland::IntrinsicHelper::HLArrayPutDouble,
1363 rlSrc[0], rlSrc[1], rlSrc[2]);
1364 } else {
1365 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1366 rlSrc[0], rlSrc[1], rlSrc[2]);
1367 }
1368 break;
1369
buzbee101305f2012-06-28 18:00:56 -07001370 case Instruction::IGET:
1371 if (rlDest.fp) {
1372 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001373 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001374 } else {
1375 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001376 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001377 }
buzbee2cfc6392012-05-07 14:51:40 -07001378 break;
buzbee101305f2012-06-28 18:00:56 -07001379 case Instruction::IGET_OBJECT:
1380 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001381 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001382 break;
1383 case Instruction::IGET_BOOLEAN:
1384 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001385 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001386 break;
1387 case Instruction::IGET_BYTE:
1388 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001389 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001390 break;
1391 case Instruction::IGET_CHAR:
1392 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001393 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001394 break;
1395 case Instruction::IGET_SHORT:
1396 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001397 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001398 break;
1399 case Instruction::IGET_WIDE:
1400 if (rlDest.fp) {
1401 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001402 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001403 } else {
1404 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001405 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001406 }
1407 break;
1408 case Instruction::IPUT:
1409 if (rlDest.fp) {
1410 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1411 rlSrc[0], rlSrc[1], vC);
1412 } else {
1413 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1414 rlSrc[0], rlSrc[1], vC);
1415 }
1416 break;
1417 case Instruction::IPUT_OBJECT:
1418 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1419 rlSrc[0], rlSrc[1], vC);
1420 break;
1421 case Instruction::IPUT_BOOLEAN:
1422 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1423 rlSrc[0], rlSrc[1], vC);
1424 break;
1425 case Instruction::IPUT_BYTE:
1426 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1427 rlSrc[0], rlSrc[1], vC);
1428 break;
1429 case Instruction::IPUT_CHAR:
1430 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1431 rlSrc[0], rlSrc[1], vC);
1432 break;
1433 case Instruction::IPUT_SHORT:
1434 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1435 rlSrc[0], rlSrc[1], vC);
1436 break;
1437 case Instruction::IPUT_WIDE:
1438 if (rlDest.fp) {
1439 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1440 rlSrc[0], rlSrc[1], vC);
1441 } else {
1442 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1443 rlSrc[0], rlSrc[1], vC);
1444 }
buzbee2cfc6392012-05-07 14:51:40 -07001445 break;
1446
1447 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001448 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001449 break;
1450
buzbee76592632012-06-29 15:18:35 -07001451 case Instruction::LONG_TO_INT:
1452 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1453 break;
1454
buzbee101305f2012-06-28 18:00:56 -07001455 case Instruction::INT_TO_LONG:
1456 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001457 break;
1458
buzbee101305f2012-06-28 18:00:56 -07001459 case Instruction::INT_TO_CHAR:
1460 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1461 greenland::IntrinsicHelper::IntToChar);
1462 break;
1463 case Instruction::INT_TO_BYTE:
1464 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1465 greenland::IntrinsicHelper::IntToByte);
1466 break;
1467 case Instruction::INT_TO_SHORT:
1468 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1469 greenland::IntrinsicHelper::IntToShort);
1470 break;
1471
buzbee76592632012-06-29 15:18:35 -07001472 case Instruction::INT_TO_FLOAT:
1473 case Instruction::LONG_TO_FLOAT:
1474 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001475 break;
1476
buzbee76592632012-06-29 15:18:35 -07001477 case Instruction::INT_TO_DOUBLE:
1478 case Instruction::LONG_TO_DOUBLE:
1479 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001480 break;
1481
buzbee76592632012-06-29 15:18:35 -07001482 case Instruction::FLOAT_TO_DOUBLE:
1483 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001484 break;
1485
buzbee76592632012-06-29 15:18:35 -07001486 case Instruction::DOUBLE_TO_FLOAT:
1487 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001488 break;
1489
1490 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001491 case Instruction::NEG_INT:
1492 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001493 break;
1494
1495 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001496 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001497 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001498 break;
1499
buzbee76592632012-06-29 15:18:35 -07001500 case Instruction::NOT_LONG:
1501 case Instruction::NOT_INT:
1502 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001503 break;
1504
buzbee2cfc6392012-05-07 14:51:40 -07001505 case Instruction::FLOAT_TO_INT:
buzbee2cfc6392012-05-07 14:51:40 -07001506 case Instruction::DOUBLE_TO_INT:
buzbee76592632012-06-29 15:18:35 -07001507 convertFPToInt(cUnit, cUnit->irb->getInt32Ty(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001508 break;
1509
buzbee76592632012-06-29 15:18:35 -07001510 case Instruction::FLOAT_TO_LONG:
1511 case Instruction::DOUBLE_TO_LONG:
1512 convertFPToInt(cUnit, cUnit->irb->getInt64Ty(), rlDest, rlSrc[0]);
1513 break;
1514
1515 case Instruction::CMPL_FLOAT:
1516 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1517 rlDest, rlSrc[0], rlSrc[1]);
1518 break;
1519 case Instruction::CMPG_FLOAT:
1520 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1521 rlDest, rlSrc[0], rlSrc[1]);
1522 break;
1523 case Instruction::CMPL_DOUBLE:
1524 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1525 rlDest, rlSrc[0], rlSrc[1]);
1526 break;
1527 case Instruction::CMPG_DOUBLE:
1528 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1529 rlDest, rlSrc[0], rlSrc[1]);
1530 break;
1531 case Instruction::CMP_LONG:
1532 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1533 rlDest, rlSrc[0], rlSrc[1]);
1534 break;
1535
buzbee76592632012-06-29 15:18:35 -07001536 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001537 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001538 break;
1539
buzbeef58c12c2012-07-03 15:06:29 -07001540#if 0
1541
buzbee76592632012-06-29 15:18:35 -07001542 case Instruction::SPARSE_SWITCH:
1543 genSparseSwitch(cUnit, vB, rlSrc[0], labelList);
1544 break;
buzbee2cfc6392012-05-07 14:51:40 -07001545#endif
1546
1547 default:
buzbee32412962012-06-26 16:27:56 -07001548 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001549 res = true;
1550 }
buzbeeb03f4872012-06-11 15:22:11 -07001551 if (objectDefinition) {
1552 setShadowFrameEntry(cUnit, (llvm::Value*)
1553 cUnit->llvmValues.elemList[rlDest.origSReg]);
1554 }
buzbee2cfc6392012-05-07 14:51:40 -07001555 return res;
1556}
1557
1558/* Extended MIR instructions like PHI */
1559void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1560 llvm::BasicBlock* llvmBB)
1561{
1562
1563 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1564 case kMirOpPhi: {
1565 int* incoming = (int*)mir->dalvikInsn.vB;
1566 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
1567 llvm::Type* phiType =
1568 llvmTypeFromLocRec(cUnit, rlDest);
1569 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1570 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1571 RegLocation loc;
1572 if (rlDest.wide) {
buzbee15bf9802012-06-12 17:49:27 -07001573 loc = oatGetSrcWide(cUnit, mir, i);
buzbee2cfc6392012-05-07 14:51:40 -07001574 i++;
1575 } else {
1576 loc = oatGetSrc(cUnit, mir, i);
1577 }
1578 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
1579 getLLVMBlock(cUnit, incoming[i]));
1580 }
1581 defineValue(cUnit, phi, rlDest.origSReg);
1582 break;
1583 }
1584 case kMirOpCopy: {
1585 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1586 break;
1587 }
1588#if defined(TARGET_ARM)
1589 case kMirOpFusedCmplFloat:
1590 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1591 break;
1592 case kMirOpFusedCmpgFloat:
1593 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1594 break;
1595 case kMirOpFusedCmplDouble:
1596 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1597 break;
1598 case kMirOpFusedCmpgDouble:
1599 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1600 break;
1601 case kMirOpFusedCmpLong:
1602 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1603 break;
1604#endif
1605 default:
1606 break;
1607 }
1608}
1609
1610void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1611{
1612 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001613 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001614 arrayRef.push_back(cUnit->irb->getInt32(offset));
1615 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1616 cUnit->irb->SetDexOffset(node);
1617}
1618
1619// Attach method info as metadata to special intrinsic
1620void setMethodInfo(CompilationUnit* cUnit)
1621{
1622 // We don't want dex offset on this
1623 cUnit->irb->SetDexOffset(NULL);
1624 greenland::IntrinsicHelper::IntrinsicId id;
1625 id = greenland::IntrinsicHelper::MethodInfo;
1626 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1627 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1628 llvm::SmallVector<llvm::Value*, 2> regInfo;
1629 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1630 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1631 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1632 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1633 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1634 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1635 inst->setMetadata("RegInfo", regInfoNode);
1636 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1637 llvm::SmallVector<llvm::Value*, 50> pmap;
1638 for (int i = 0; i < promoSize; i++) {
1639 PromotionMap* p = &cUnit->promotionMap[i];
1640 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1641 ((p->fpReg & 0xff) << 16) |
1642 ((p->coreReg & 0xff) << 8) |
1643 ((p->fpLocation & 0xf) << 4) |
1644 (p->coreLocation & 0xf);
1645 pmap.push_back(cUnit->irb->getInt32(mapData));
1646 }
1647 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1648 inst->setMetadata("PromotionMap", mapNode);
1649 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1650}
1651
1652/* Handle the content in each basic block */
1653bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1654{
1655 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
1656 cUnit->irb->SetInsertPoint(llvmBB);
1657 setDexOffset(cUnit, bb->startOffset);
1658
1659 if (bb->blockType == kEntryBlock) {
1660 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001661 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1662 cUnit->numDalvikRegisters, true,
1663 kAllocMisc);
1664 for (int i = 0; i < cUnit->numSSARegs; i++) {
1665 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1666 }
1667 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1668 if (canBeRef[i]) {
1669 cUnit->numShadowFrameEntries++;
1670 }
1671 }
1672 if (cUnit->numShadowFrameEntries > 0) {
1673 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1674 cUnit->numShadowFrameEntries, true,
1675 kAllocMisc);
1676 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1677 if (canBeRef[i]) {
1678 cUnit->shadowMap[j++] = i;
1679 }
1680 }
1681 greenland::IntrinsicHelper::IntrinsicId id =
1682 greenland::IntrinsicHelper::AllocaShadowFrame;
1683 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1684 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1685 cUnit->irb->CreateCall(func, entries);
1686 }
buzbee2cfc6392012-05-07 14:51:40 -07001687 } else if (bb->blockType == kExitBlock) {
1688 /*
1689 * Because of the differences between how MIR/LIR and llvm handle exit
1690 * blocks, we won't explicitly covert them. On the llvm-to-lir
1691 * path, it will need to be regenereated.
1692 */
1693 return false;
buzbee6969d502012-06-15 16:40:31 -07001694 } else if (bb->blockType == kExceptionHandling) {
1695 /*
1696 * Because we're deferring null checking, delete the associated empty
1697 * exception block.
1698 * TODO: add new block type for exception blocks that we generate
1699 * greenland code for.
1700 */
1701 llvmBB->eraseFromParent();
1702 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001703 }
1704
1705 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1706
1707 setDexOffset(cUnit, mir->offset);
1708
1709 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
1710 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
1711
1712 /* If we're compiling for the debugger, generate an update callout */
1713 if (cUnit->genDebugger) {
1714 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1715 //genDebuggerUpdate(cUnit, mir->offset);
1716 }
1717
1718 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
1719 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1720 continue;
1721 }
1722
1723 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1724 NULL /* labelList */);
1725 if (notHandled) {
1726 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
1727 mir->offset, dalvikOpcode,
1728 Instruction::Name(dalvikOpcode),
1729 dalvikFormat);
1730 }
1731 }
1732
buzbee6969d502012-06-15 16:40:31 -07001733 if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001734 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1735 }
1736
1737 return false;
1738}
1739
buzbee4f4dfc72012-07-02 14:54:44 -07001740char remapShorty(char shortyType) {
1741 /*
1742 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1743 * and longs/doubles are represented as a pair of registers. When sub-word
1744 * arguments (and method results) are passed, they are extended to Dalvik
1745 * virtual register containers. Because llvm is picky about type consistency,
1746 * we must either cast the "real" type to 32-bit container multiple Dalvik
1747 * register types, or always use the expanded values.
1748 * Here, we're doing the latter. We map the shorty signature to container
1749 * types (which is valid so long as we always do a real expansion of passed
1750 * arguments and field loads).
1751 */
1752 switch(shortyType) {
1753 case 'Z' : shortyType = 'I'; break;
1754 case 'B' : shortyType = 'I'; break;
1755 case 'S' : shortyType = 'I'; break;
1756 case 'C' : shortyType = 'I'; break;
1757 default: break;
1758 }
1759 return shortyType;
1760}
1761
buzbee2cfc6392012-05-07 14:51:40 -07001762llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1763
1764 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001765 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001766 greenland::kAccurate);
1767
1768 // Get argument type
1769 std::vector<llvm::Type*> args_type;
1770
1771 // method object
1772 args_type.push_back(cUnit->irb->GetJMethodTy());
1773
1774 // Do we have a "this"?
1775 if ((cUnit->access_flags & kAccStatic) == 0) {
1776 args_type.push_back(cUnit->irb->GetJObjectTy());
1777 }
1778
1779 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001780 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001781 greenland::kAccurate));
1782 }
1783
1784 return llvm::FunctionType::get(ret_type, args_type, false);
1785}
1786
1787bool createFunction(CompilationUnit* cUnit) {
1788 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1789 /* with_signature */ false));
1790 llvm::FunctionType* func_type = getFunctionType(cUnit);
1791
1792 if (func_type == NULL) {
1793 return false;
1794 }
1795
1796 cUnit->func = llvm::Function::Create(func_type,
1797 llvm::Function::ExternalLinkage,
1798 func_name, cUnit->module);
1799
1800 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1801 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1802
1803 arg_iter->setName("method");
1804 ++arg_iter;
1805
1806 int startSReg = cUnit->numRegs;
1807
1808 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1809 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1810 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1811 }
1812
1813 return true;
1814}
1815
1816bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1817{
1818 // Skip the exit block
1819 if (bb->blockType == kExitBlock) {
1820 cUnit->idToBlockMap.Put(bb->id, NULL);
1821 } else {
1822 int offset = bb->startOffset;
1823 bool entryBlock = (bb->blockType == kEntryBlock);
1824 llvm::BasicBlock* llvmBB =
1825 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
Elliott Hughes74847412012-06-20 18:10:21 -07001826 StringPrintf(kLabelFormat, offset, bb->id),
buzbee2cfc6392012-05-07 14:51:40 -07001827 cUnit->func);
1828 if (entryBlock) {
1829 cUnit->entryBB = llvmBB;
1830 cUnit->placeholderBB =
1831 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
1832 cUnit->func);
1833 }
1834 cUnit->idToBlockMap.Put(bb->id, llvmBB);
1835 }
1836 return false;
1837}
1838
1839
1840/*
1841 * Convert MIR to LLVM_IR
1842 * o For each ssa name, create LLVM named value. Type these
1843 * appropriately, and ignore high half of wide and double operands.
1844 * o For each MIR basic block, create an LLVM basic block.
1845 * o Iterate through the MIR a basic block at a time, setting arguments
1846 * to recovered ssa name.
1847 */
1848void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
1849{
1850 initIR(cUnit);
1851 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
1852
1853 // Create the function
1854 createFunction(cUnit);
1855
1856 // Create an LLVM basic block for each MIR block in dfs preorder
1857 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
1858 kPreOrderDFSTraversal, false /* isIterative */);
1859 /*
1860 * Create an llvm named value for each MIR SSA name. Note: we'll use
1861 * placeholders for all non-argument values (because we haven't seen
1862 * the definition yet).
1863 */
1864 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
1865 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1866 arg_iter++; /* Skip path method */
1867 for (int i = 0; i < cUnit->numSSARegs; i++) {
1868 llvm::Value* val;
1869 llvm::Type* ty = llvmTypeFromLocRec(cUnit, cUnit->regLocation[i]);
1870 if (i < cUnit->numRegs) {
1871 // Skip non-argument _0 names - should never be a use
1872 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)0);
1873 } else if (i >= (cUnit->numRegs + cUnit->numIns)) {
1874 // Handle SSA defs, skipping Method* and compiler temps
1875 if (SRegToVReg(cUnit, i) < 0) {
1876 val = NULL;
1877 } else {
1878 val = cUnit->irb->CreateLoad(cUnit->irb->CreateAlloca(ty, 0));
1879 val->setName(llvmSSAName(cUnit, i));
1880 }
1881 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
1882 if (cUnit->regLocation[i].wide) {
1883 // Skip high half of wide values
1884 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
1885 i++;
1886 }
1887 } else {
1888 // Recover previously-created argument values
1889 llvm::Value* argVal = arg_iter++;
1890 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
buzbee4f4dfc72012-07-02 14:54:44 -07001891 if (cUnit->regLocation[i].wide) {
1892 // Skip high half of wide values.
1893 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
1894 i++;
1895 }
buzbee2cfc6392012-05-07 14:51:40 -07001896 }
1897 }
1898 cUnit->irb->CreateBr(cUnit->placeholderBB);
1899
1900 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
1901 kPreOrderDFSTraversal, false /* Iterative */);
1902
1903 cUnit->placeholderBB->eraseFromParent();
1904
1905 llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction);
1906
buzbeead8f15e2012-06-18 14:49:45 -07001907 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
1908 // Write bitcode to file
1909 std::string errmsg;
1910 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
1911 oatReplaceSpecialChars(fname);
1912 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07001913 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07001914
buzbeead8f15e2012-06-18 14:49:45 -07001915 llvm::OwningPtr<llvm::tool_output_file> out_file(
1916 new llvm::tool_output_file(fname.c_str(), errmsg,
1917 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07001918
buzbeead8f15e2012-06-18 14:49:45 -07001919 if (!errmsg.empty()) {
1920 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
1921 }
1922
1923 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
1924 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07001925 }
buzbee2cfc6392012-05-07 14:51:40 -07001926}
1927
1928RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
1929 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07001930 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001931 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
1932 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07001933 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07001934 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07001935 // FIXME: need to be more robust, handle FP and be in a position to
1936 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07001937 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
1938 memset(&res, 0, sizeof(res));
1939 res.location = kLocPhysReg;
1940 res.lowReg = oatAllocTemp(cUnit);
1941 res.home = true;
1942 res.sRegLow = INVALID_SREG;
1943 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07001944 llvm::Type* ty = val->getType();
1945 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
1946 (ty == cUnit->irb->getDoubleTy()));
1947 if (res.wide) {
1948 res.highReg = oatAllocTemp(cUnit);
1949 }
buzbee4f1181f2012-06-22 13:52:12 -07001950 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07001951 } else {
1952 DCHECK_EQ(valName[0], 'v');
1953 int baseSReg = INVALID_SREG;
1954 sscanf(valName.c_str(), "v%d_", &baseSReg);
1955 res = cUnit->regLocation[baseSReg];
1956 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07001957 }
1958 } else {
1959 res = it->second;
1960 }
1961 return res;
1962}
1963
1964Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
1965{
1966 Instruction::Code res = Instruction::NOP;
1967 if (isWide) {
1968 switch(op) {
1969 case kOpAdd: res = Instruction::ADD_LONG; break;
1970 case kOpSub: res = Instruction::SUB_LONG; break;
1971 case kOpMul: res = Instruction::MUL_LONG; break;
1972 case kOpDiv: res = Instruction::DIV_LONG; break;
1973 case kOpRem: res = Instruction::REM_LONG; break;
1974 case kOpAnd: res = Instruction::AND_LONG; break;
1975 case kOpOr: res = Instruction::OR_LONG; break;
1976 case kOpXor: res = Instruction::XOR_LONG; break;
1977 case kOpLsl: res = Instruction::SHL_LONG; break;
1978 case kOpLsr: res = Instruction::USHR_LONG; break;
1979 case kOpAsr: res = Instruction::SHR_LONG; break;
1980 default: LOG(FATAL) << "Unexpected OpKind " << op;
1981 }
1982 } else if (isConst){
1983 switch(op) {
1984 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
1985 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
1986 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
1987 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
1988 case kOpRem: res = Instruction::REM_INT_LIT16; break;
1989 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
1990 case kOpOr: res = Instruction::OR_INT_LIT16; break;
1991 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
1992 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
1993 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
1994 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
1995 default: LOG(FATAL) << "Unexpected OpKind " << op;
1996 }
1997 } else {
1998 switch(op) {
1999 case kOpAdd: res = Instruction::ADD_INT; break;
2000 case kOpSub: res = Instruction::SUB_INT; break;
2001 case kOpMul: res = Instruction::MUL_INT; break;
2002 case kOpDiv: res = Instruction::DIV_INT; break;
2003 case kOpRem: res = Instruction::REM_INT; break;
2004 case kOpAnd: res = Instruction::AND_INT; break;
2005 case kOpOr: res = Instruction::OR_INT; break;
2006 case kOpXor: res = Instruction::XOR_INT; break;
2007 case kOpLsl: res = Instruction::SHL_INT; break;
2008 case kOpLsr: res = Instruction::USHR_INT; break;
2009 case kOpAsr: res = Instruction::SHR_INT; break;
2010 default: LOG(FATAL) << "Unexpected OpKind " << op;
2011 }
2012 }
2013 return res;
2014}
2015
buzbee4f1181f2012-06-22 13:52:12 -07002016Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2017{
2018 Instruction::Code res = Instruction::NOP;
2019 if (isWide) {
2020 switch(op) {
2021 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2022 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2023 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2024 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2025 case kOpRem: res = Instruction::REM_DOUBLE; break;
2026 default: LOG(FATAL) << "Unexpected OpKind " << op;
2027 }
2028 } else {
2029 switch(op) {
2030 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2031 case kOpSub: res = Instruction::SUB_FLOAT; break;
2032 case kOpMul: res = Instruction::MUL_FLOAT; break;
2033 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2034 case kOpRem: res = Instruction::REM_FLOAT; break;
2035 default: LOG(FATAL) << "Unexpected OpKind " << op;
2036 }
2037 }
2038 return res;
2039}
2040
2041void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2042{
2043 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002044 /*
2045 * Normally, we won't ever generate an FP operation with an immediate
2046 * operand (not supported in Dex instruction set). However, the IR builder
2047 * may insert them - in particular for createNegFP. Recognize this case
2048 * and deal with it.
2049 */
2050 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2051 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2052 DCHECK(op2C == NULL);
2053 if ((op1C != NULL) && (op == kOpSub)) {
2054 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2055 if (rlDest.wide) {
2056 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2057 } else {
2058 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2059 }
buzbee4f1181f2012-06-22 13:52:12 -07002060 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002061 DCHECK(op1C == NULL);
2062 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2063 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2064 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2065 if (rlDest.wide) {
2066 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2067 } else {
2068 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2069 }
buzbee4f1181f2012-06-22 13:52:12 -07002070 }
2071}
2072
buzbee101305f2012-06-28 18:00:56 -07002073void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2074 Instruction::Code opcode)
2075{
2076 RegLocation rlDest = getLoc(cUnit, inst);
2077 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2078 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2079}
2080
buzbee76592632012-06-29 15:18:35 -07002081void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2082{
2083 RegLocation rlDest = getLoc(cUnit, inst);
2084 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2085 Instruction::Code opcode;
2086 if (rlDest.wide) {
2087 if (rlSrc.wide) {
2088 opcode = Instruction::LONG_TO_DOUBLE;
2089 } else {
2090 opcode = Instruction::INT_TO_DOUBLE;
2091 }
2092 } else {
2093 if (rlSrc.wide) {
2094 opcode = Instruction::LONG_TO_FLOAT;
2095 } else {
2096 opcode = Instruction::INT_TO_FLOAT;
2097 }
2098 }
2099 genConversion(cUnit, opcode, rlDest, rlSrc);
2100}
2101
2102void cvtFPToInt(CompilationUnit* cUnit, llvm::Instruction* inst)
2103{
2104 RegLocation rlDest = getLoc(cUnit, inst);
2105 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2106 Instruction::Code opcode;
2107 if (rlDest.wide) {
2108 if (rlSrc.wide) {
2109 opcode = Instruction::DOUBLE_TO_LONG;
2110 } else {
2111 opcode = Instruction::FLOAT_TO_LONG;
2112 }
2113 } else {
2114 if (rlSrc.wide) {
2115 opcode = Instruction::DOUBLE_TO_INT;
2116 } else {
2117 opcode = Instruction::FLOAT_TO_INT;
2118 }
2119 }
2120 genConversion(cUnit, opcode, rlDest, rlSrc);
2121}
2122
2123void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2124{
2125 RegLocation rlDest = getLoc(cUnit, inst);
2126 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2127 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2128}
2129
2130void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2131{
2132 RegLocation rlDest = getLoc(cUnit, inst);
2133 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2134 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2135 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2136 storeValue(cUnit, rlDest, rlSrc);
2137}
2138
2139void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2140{
2141 RegLocation rlDest = getLoc(cUnit, inst);
2142 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2143 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2144}
2145
2146
buzbee101305f2012-06-28 18:00:56 -07002147void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2148{
2149 // TODO: evaluate src/tgt types and add general support for more than int to long
2150 RegLocation rlDest = getLoc(cUnit, inst);
2151 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2152 DCHECK(rlDest.wide);
2153 DCHECK(!rlSrc.wide);
2154 DCHECK(!rlDest.fp);
2155 DCHECK(!rlSrc.fp);
2156 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2157 if (rlSrc.location == kLocPhysReg) {
2158 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2159 } else {
2160 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2161 }
2162 if (isSigned) {
2163 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2164 } else {
2165 loadConstant(cUnit, rlResult.highReg, 0);
2166 }
2167 storeValueWide(cUnit, rlDest, rlResult);
2168}
2169
buzbee2cfc6392012-05-07 14:51:40 -07002170void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2171{
2172 RegLocation rlDest = getLoc(cUnit, inst);
2173 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002174 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002175 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2176 if ((op == kOpSub) && (lhsImm != NULL)) {
2177 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002178 if (rlSrc1.wide) {
2179 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2180 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2181 } else {
2182 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2183 lhsImm->getSExtValue());
2184 }
buzbee4f1181f2012-06-22 13:52:12 -07002185 return;
2186 }
2187 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002188 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2189 llvm::Value* rhs = inst->getOperand(1);
2190 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2191 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
2192 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, src2->getSExtValue());
2193 } else {
2194 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
2195 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2196 if (rlDest.wide) {
2197 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2198 } else {
2199 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2200 }
2201 }
2202}
2203
buzbee101305f2012-06-28 18:00:56 -07002204void cvtShiftOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2205{
2206 if (inst->getType() == cUnit->irb->getInt64Ty()) {
2207 /*
2208 * llvm wants the shift amount to be 64 bits, whereas we've constained
2209 * it to be in 6 bits. It should always be held as an unnamed temp
2210 * at this point that was the result of a previous UExt. We'll backtrack
2211 * to find the pre-extension value and use that.
2212 * TODO: probably better to handle this in cvtIntExt() or just intrinsify
2213 */
2214 RegLocation rlDest = getLoc(cUnit, inst);
2215 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2216 RegLocation rlShift = getLoc(cUnit, inst->getOperand(1));
2217 DCHECK(rlShift.wide);
2218 DCHECK_EQ(rlShift.sRegLow, INVALID_SREG);
2219 // Now, free the temp registers - we won't need them.
2220 // TODO: kill the dead extend ops
2221 oatFreeTemp(cUnit, rlShift.lowReg);
2222 oatFreeTemp(cUnit, rlShift.highReg);
2223 // Get the pre-extend operand
2224 llvm::Instruction* extInst =
2225 llvm::dyn_cast<llvm::Instruction>(inst->getOperand(1));
2226 DCHECK(extInst != NULL);
2227 rlShift = getLoc(cUnit, extInst->getOperand(0));
2228 DCHECK(!rlShift.wide);
2229 Instruction::Code opcode;
2230 if (op == kOpLsl)
2231 opcode = Instruction::SHL_LONG;
2232 else if (op == kOpAsr)
2233 opcode = Instruction::SHR_LONG;
2234 else {
2235 DCHECK_EQ(op, kOpLsr);
2236 opcode = Instruction::USHR_LONG;
2237 }
2238 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2239 } else {
2240 cvtBinOp(cUnit, op, inst);
2241 }
2242}
2243
buzbee2cfc6392012-05-07 14:51:40 -07002244void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2245{
2246 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2247 DCHECK(brInst != NULL);
2248 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2249 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2250 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2251}
2252
2253void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2254{
2255 // Nop - these have already been processed
2256}
2257
2258void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2259{
2260 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2261 llvm::Value* retVal = retInst->getReturnValue();
2262 if (retVal != NULL) {
2263 RegLocation rlSrc = getLoc(cUnit, retVal);
2264 if (rlSrc.wide) {
2265 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2266 } else {
2267 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2268 }
2269 }
2270 genExitSequence(cUnit);
2271}
2272
2273ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2274{
2275 ConditionCode res = kCondAl;
2276 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002277 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002278 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2279 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2280 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002281 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002282 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002283 default: LOG(FATAL) << "Unexpected llvm condition";
2284 }
2285 return res;
2286}
2287
2288void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2289{
2290 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2291 UNIMPLEMENTED(FATAL);
2292}
2293
2294void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2295 llvm::BranchInst* brInst)
2296{
2297 // Get targets
2298 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2299 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2300 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2301 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2302 // Get comparison operands
2303 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2304 ConditionCode cond = getCond(iCmpInst->getPredicate());
2305 llvm::Value* lhs = iCmpInst->getOperand(0);
2306 // Not expecting a constant as 1st operand
2307 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2308 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2309 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2310 llvm::Value* rhs = inst->getOperand(1);
2311#if defined(TARGET_MIPS)
2312 // Compare and branch in one shot
2313 (void)taken;
2314 (void)cond;
2315 (void)rhs;
2316 UNIMPLEMENTED(FATAL);
2317#else
2318 //Compare, then branch
2319 // TODO: handle fused CMP_LONG/IF_xxZ case
2320 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2321 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
2322 } else {
2323 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2324 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2325 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2326 }
2327 opCondBranch(cUnit, cond, taken);
2328#endif
2329 // Fallthrough
2330 opUnconditionalBranch(cUnit, fallThrough);
2331}
2332
2333void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2334 llvm::Function* callee)
2335{
2336 UNIMPLEMENTED(FATAL);
2337}
2338
buzbee2cfc6392012-05-07 14:51:40 -07002339void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2340{
buzbee4f1181f2012-06-22 13:52:12 -07002341 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002342 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2343 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002344 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2345 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002346 if (rlSrc.wide) {
2347 storeValueWide(cUnit, rlDest, rlSrc);
2348 } else {
2349 storeValue(cUnit, rlDest, rlSrc);
2350 }
2351}
2352
2353// Note: Immediate arg is a ConstantInt regardless of result type
2354void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2355{
buzbee4f1181f2012-06-22 13:52:12 -07002356 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002357 llvm::ConstantInt* src =
2358 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2359 uint64_t immval = src->getZExtValue();
2360 RegLocation rlDest = getLoc(cUnit, callInst);
2361 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2362 if (rlDest.wide) {
2363 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2364 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2365 storeValueWide(cUnit, rlDest, rlResult);
2366 } else {
2367 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2368 storeValue(cUnit, rlDest, rlResult);
2369 }
2370}
2371
buzbee101305f2012-06-28 18:00:56 -07002372void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2373 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002374{
buzbee4f1181f2012-06-22 13:52:12 -07002375 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002376 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002377 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002378 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002379 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002380 if (isString) {
2381 genConstString(cUnit, index, rlDest);
2382 } else {
2383 genConstClass(cUnit, index, rlDest);
2384 }
2385}
2386
2387void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2388{
2389 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2390 llvm::ConstantInt* offsetVal =
2391 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2392 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2393 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002394}
2395
buzbee4f1181f2012-06-22 13:52:12 -07002396void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2397{
buzbee32412962012-06-26 16:27:56 -07002398 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002399 llvm::ConstantInt* typeIdxVal =
2400 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2401 uint32_t typeIdx = typeIdxVal->getZExtValue();
2402 RegLocation rlDest = getLoc(cUnit, callInst);
2403 genNewInstance(cUnit, typeIdx, rlDest);
2404}
2405
buzbee8fa0fda2012-06-27 15:44:52 -07002406void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2407{
2408 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2409 llvm::ConstantInt* typeIdxVal =
2410 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2411 uint32_t typeIdx = typeIdxVal->getZExtValue();
2412 llvm::Value* len = callInst->getArgOperand(1);
2413 RegLocation rlLen = getLoc(cUnit, len);
2414 RegLocation rlDest = getLoc(cUnit, callInst);
2415 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2416}
2417
2418void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2419{
2420 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2421 llvm::ConstantInt* typeIdxVal =
2422 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2423 uint32_t typeIdx = typeIdxVal->getZExtValue();
2424 llvm::Value* src = callInst->getArgOperand(1);
2425 RegLocation rlSrc = getLoc(cUnit, src);
2426 RegLocation rlDest = getLoc(cUnit, callInst);
2427 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2428}
2429
buzbee32412962012-06-26 16:27:56 -07002430void cvtThrowVerificationError(CompilationUnit* cUnit, llvm::CallInst* callInst)
2431{
2432 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2433 llvm::ConstantInt* info1 =
2434 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2435 llvm::ConstantInt* info2 =
2436 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2437 genThrowVerificationError(cUnit, info1->getZExtValue(), info2->getZExtValue());
2438}
2439
2440void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2441{
2442 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2443 llvm::Value* src = callInst->getArgOperand(0);
2444 RegLocation rlSrc = getLoc(cUnit, src);
2445 genThrow(cUnit, rlSrc);
2446}
2447
buzbee8fa0fda2012-06-27 15:44:52 -07002448void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2449 llvm::CallInst* callInst)
2450{
2451 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2452 llvm::ConstantInt* optFlags =
2453 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2454 llvm::Value* src = callInst->getArgOperand(1);
2455 RegLocation rlSrc = getLoc(cUnit, src);
2456 if (isEnter) {
2457 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2458 } else {
2459 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2460 }
2461}
2462
buzbee76592632012-06-29 15:18:35 -07002463void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002464{
2465 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2466 llvm::ConstantInt* optFlags =
2467 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2468 llvm::Value* src = callInst->getArgOperand(1);
2469 RegLocation rlSrc = getLoc(cUnit, src);
2470 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2471 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2472 RegLocation rlDest = getLoc(cUnit, callInst);
2473 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2474 int lenOffset = Array::LengthOffset().Int32Value();
2475 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2476 storeValue(cUnit, rlDest, rlResult);
2477}
2478
buzbee32412962012-06-26 16:27:56 -07002479void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2480{
2481 DCHECK_EQ(callInst->getNumArgOperands(), 0U);
2482 int exOffset = Thread::ExceptionOffset().Int32Value();
2483 RegLocation rlDest = getLoc(cUnit, callInst);
2484 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2485#if defined(TARGET_X86)
2486 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
2487 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
2488#else
2489 int resetReg = oatAllocTemp(cUnit);
2490 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
2491 loadConstant(cUnit, resetReg, 0);
2492 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
2493 oatFreeTemp(cUnit, resetReg);
2494#endif
2495 storeValue(cUnit, rlDest, rlResult);
2496}
2497
buzbee4f1181f2012-06-22 13:52:12 -07002498void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2499 bool isObject)
2500{
buzbee32412962012-06-26 16:27:56 -07002501 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002502 llvm::ConstantInt* typeIdxVal =
2503 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2504 uint32_t typeIdx = typeIdxVal->getZExtValue();
2505 RegLocation rlDest = getLoc(cUnit, callInst);
2506 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2507}
2508
buzbee8fa0fda2012-06-27 15:44:52 -07002509void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2510 bool isObject)
2511{
2512 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2513 llvm::ConstantInt* typeIdxVal =
2514 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2515 uint32_t typeIdx = typeIdxVal->getZExtValue();
2516 llvm::Value* src = callInst->getArgOperand(1);
2517 RegLocation rlSrc = getLoc(cUnit, src);
2518 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2519}
2520
2521void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2522 int scale)
2523{
2524 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2525 llvm::ConstantInt* optFlags =
2526 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2527 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2528 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2529 RegLocation rlDest = getLoc(cUnit, callInst);
2530 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2531 rlDest, scale);
2532}
2533
2534void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2535 int scale)
2536{
2537 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2538 llvm::ConstantInt* optFlags =
2539 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2540 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2541 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2542 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
2543 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2544 rlSrc, scale);
2545}
2546
buzbee101305f2012-06-28 18:00:56 -07002547void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2548 bool isWide, bool isObj)
2549{
2550 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2551 llvm::ConstantInt* optFlags =
2552 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2553 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2554 llvm::ConstantInt* fieldIdx =
2555 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2556 RegLocation rlDest = getLoc(cUnit, callInst);
2557 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2558 size, rlDest, rlObj, isWide, isObj);
2559}
2560
2561void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2562 bool isWide, bool isObj)
2563{
2564 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2565 llvm::ConstantInt* optFlags =
2566 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2567 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2568 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2569 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002570 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002571 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2572 size, rlSrc, rlObj, isWide, isObj);
2573}
2574
2575void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2576{
2577 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2578 llvm::ConstantInt* typeIdx =
2579 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2580 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2581 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2582}
2583
buzbee76592632012-06-29 15:18:35 -07002584void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2585 Instruction::Code opcode)
2586{
2587 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2588 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2589 RegLocation rlDest = getLoc(cUnit, callInst);
2590 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2591}
2592
2593void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2594{
2595 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2596 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2597 RegLocation rlDest = getLoc(cUnit, callInst);
2598 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2599}
2600
buzbeef58c12c2012-07-03 15:06:29 -07002601void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2602{
2603 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2604 DCHECK(swInst != NULL);
2605 llvm::Value* testVal = swInst->getCondition();
2606 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2607 DCHECK(tableOffsetNode != NULL);
2608 llvm::ConstantInt* tableOffsetValue =
2609 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2610 int32_t tableOffset = tableOffsetValue->getSExtValue();
2611 RegLocation rlSrc = getLoc(cUnit, testVal);
2612 genPackedSwitch(cUnit, tableOffset, rlSrc);
2613}
2614
buzbee6969d502012-06-15 16:40:31 -07002615void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002616 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002617{
2618 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2619 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002620 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002621 info->result.location = kLocInvalid;
2622 } else {
2623 info->result = getLoc(cUnit, callInst);
2624 }
2625 llvm::ConstantInt* invokeTypeVal =
2626 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2627 llvm::ConstantInt* methodIndexVal =
2628 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2629 llvm::ConstantInt* optFlagsVal =
2630 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2631 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2632 info->index = methodIndexVal->getZExtValue();
2633 info->optFlags = optFlagsVal->getZExtValue();
2634 info->offset = cUnit->currentDalvikOffset;
2635
buzbee6969d502012-06-15 16:40:31 -07002636 // Count the argument words, and then build argument array.
2637 info->numArgWords = 0;
2638 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2639 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2640 info->numArgWords += tLoc.wide ? 2 : 1;
2641 }
2642 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2643 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2644 // Now, fill in the location records, synthesizing high loc of wide vals
2645 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002646 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002647 if (info->args[next].wide) {
2648 next++;
2649 // TODO: Might make sense to mark this as an invalid loc
2650 info->args[next].origSReg = info->args[next-1].origSReg+1;
2651 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2652 }
2653 next++;
2654 }
buzbee4f4dfc72012-07-02 14:54:44 -07002655 // TODO - rework such that we no longer need isRange
2656 info->isRange = (info->numArgWords > 5);
2657
buzbee76592632012-06-29 15:18:35 -07002658 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002659 genFilledNewArray(cUnit, info);
2660 } else {
2661 genInvoke(cUnit, info);
2662 }
buzbee6969d502012-06-15 16:40:31 -07002663}
2664
buzbeead8f15e2012-06-18 14:49:45 -07002665/* Look up the RegLocation associated with a Value. Must already be defined */
2666RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2667{
2668 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2669 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2670 return it->second;
2671}
2672
buzbee2cfc6392012-05-07 14:51:40 -07002673bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2674{
2675 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2676 // Define the starting label
2677 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2678 // Extract the starting offset from the block's name
2679 if (!isEntry) {
2680 const char* blockName = bb->getName().str().c_str();
2681 int dummy;
Elliott Hughes74847412012-06-20 18:10:21 -07002682 sscanf(blockName, kLabelFormat, &blockLabel->operands[0], &dummy);
buzbee2cfc6392012-05-07 14:51:40 -07002683 }
2684 // Set the label kind
2685 blockLabel->opcode = kPseudoNormalBlockLabel;
2686 // Insert the label
2687 oatAppendLIR(cUnit, blockLabel);
2688
2689 // Free temp registers and reset redundant store tracking */
2690 oatResetRegPool(cUnit);
2691 oatResetDefTracking(cUnit);
2692
2693 //TODO: restore oat incoming liveness optimization
2694 oatClobberAllRegs(cUnit);
2695
buzbee6969d502012-06-15 16:40:31 -07002696 LIR* headLIR = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07002697
2698 if (isEntry) {
2699 cUnit->currentDalvikOffset = 0;
buzbeead8f15e2012-06-18 14:49:45 -07002700 RegLocation* argLocs = (RegLocation*)
2701 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2702 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2703 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2704 for (unsigned i = 0; it != it_end; ++it) {
2705 llvm::Value* val = it;
2706 argLocs[i++] = valToLoc(cUnit, val);
2707 llvm::Type* ty = val->getType();
2708 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2709 argLocs[i++].sRegLow = INVALID_SREG;
2710 }
2711 }
2712 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
buzbee2cfc6392012-05-07 14:51:40 -07002713 }
2714
2715 // Visit all of the instructions in the block
2716 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2717 llvm::Instruction* inst = it;
2718 llvm::BasicBlock::iterator nextIt = ++it;
2719 // Extract the Dalvik offset from the instruction
2720 uint32_t opcode = inst->getOpcode();
2721 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2722 if (dexOffsetNode != NULL) {
2723 llvm::ConstantInt* dexOffsetValue =
2724 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2725 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2726 }
2727
buzbee6969d502012-06-15 16:40:31 -07002728 oatResetRegPool(cUnit);
2729 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2730 oatClobberAllRegs(cUnit);
2731 }
2732
2733 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2734 oatResetDefTracking(cUnit);
2735 }
2736
2737#ifndef NDEBUG
2738 /* Reset temp tracking sanity check */
2739 cUnit->liveSReg = INVALID_SREG;
2740#endif
2741
2742 LIR* boundaryLIR;
2743 const char* instStr = "boundary";
2744 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
2745 (intptr_t) instStr);
2746 cUnit->boundaryMap.Overwrite(cUnit->currentDalvikOffset, boundaryLIR);
2747
2748 /* Remember the first LIR for thisl block*/
2749 if (headLIR == NULL) {
2750 headLIR = boundaryLIR;
2751 headLIR->defMask = ENCODE_ALL;
2752 }
2753
buzbee2cfc6392012-05-07 14:51:40 -07002754 switch(opcode) {
2755
2756 case llvm::Instruction::ICmp: {
2757 llvm::Instruction* nextInst = nextIt;
2758 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2759 if (brInst != NULL /* and... */) {
2760 cvtICmpBr(cUnit, inst, brInst);
2761 ++it;
2762 } else {
2763 cvtICmp(cUnit, inst);
2764 }
2765 }
2766 break;
2767
2768 case llvm::Instruction::Call: {
2769 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2770 llvm::Function* callee = callInst->getCalledFunction();
2771 greenland::IntrinsicHelper::IntrinsicId id =
2772 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2773 switch (id) {
buzbeeb03f4872012-06-11 15:22:11 -07002774 case greenland::IntrinsicHelper::AllocaShadowFrame:
2775 case greenland::IntrinsicHelper::SetShadowFrameEntry:
buzbee6969d502012-06-15 16:40:31 -07002776 case greenland::IntrinsicHelper::PopShadowFrame:
buzbeeb03f4872012-06-11 15:22:11 -07002777 // Ignore shadow frame stuff for quick compiler
2778 break;
buzbee2cfc6392012-05-07 14:51:40 -07002779 case greenland::IntrinsicHelper::CopyInt:
2780 case greenland::IntrinsicHelper::CopyObj:
2781 case greenland::IntrinsicHelper::CopyFloat:
2782 case greenland::IntrinsicHelper::CopyLong:
2783 case greenland::IntrinsicHelper::CopyDouble:
2784 cvtCopy(cUnit, callInst);
2785 break;
2786 case greenland::IntrinsicHelper::ConstInt:
2787 case greenland::IntrinsicHelper::ConstObj:
2788 case greenland::IntrinsicHelper::ConstLong:
2789 case greenland::IntrinsicHelper::ConstFloat:
2790 case greenland::IntrinsicHelper::ConstDouble:
2791 cvtConst(cUnit, callInst);
2792 break;
buzbee4f1181f2012-06-22 13:52:12 -07002793 case greenland::IntrinsicHelper::DivInt:
2794 case greenland::IntrinsicHelper::DivLong:
2795 cvtBinOp(cUnit, kOpDiv, inst);
2796 break;
2797 case greenland::IntrinsicHelper::RemInt:
2798 case greenland::IntrinsicHelper::RemLong:
2799 cvtBinOp(cUnit, kOpRem, inst);
2800 break;
buzbee2cfc6392012-05-07 14:51:40 -07002801 case greenland::IntrinsicHelper::MethodInfo:
buzbeead8f15e2012-06-18 14:49:45 -07002802 // Already dealt with - just ignore it here.
buzbee2cfc6392012-05-07 14:51:40 -07002803 break;
2804 case greenland::IntrinsicHelper::CheckSuspend:
2805 genSuspendTest(cUnit, 0 /* optFlags already applied */);
2806 break;
buzbee4f1181f2012-06-22 13:52:12 -07002807 case greenland::IntrinsicHelper::HLInvokeObj:
buzbee8fa0fda2012-06-27 15:44:52 -07002808 case greenland::IntrinsicHelper::HLInvokeFloat:
2809 case greenland::IntrinsicHelper::HLInvokeDouble:
2810 case greenland::IntrinsicHelper::HLInvokeLong:
2811 case greenland::IntrinsicHelper::HLInvokeInt:
buzbee101305f2012-06-28 18:00:56 -07002812 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
buzbee4f1181f2012-06-22 13:52:12 -07002813 break;
buzbee6969d502012-06-15 16:40:31 -07002814 case greenland::IntrinsicHelper::HLInvokeVoid:
buzbee101305f2012-06-28 18:00:56 -07002815 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
2816 break;
2817 case greenland::IntrinsicHelper::FilledNewArray:
2818 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
2819 break;
2820 case greenland::IntrinsicHelper::FillArrayData:
2821 cvtFillArrayData(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07002822 break;
2823 case greenland::IntrinsicHelper::ConstString:
buzbee101305f2012-06-28 18:00:56 -07002824 cvtConstObject(cUnit, callInst, true /* isString */);
2825 break;
2826 case greenland::IntrinsicHelper::ConstClass:
2827 cvtConstObject(cUnit, callInst, false /* isString */);
2828 break;
2829 case greenland::IntrinsicHelper::CheckCast:
2830 cvtCheckCast(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07002831 break;
buzbee4f1181f2012-06-22 13:52:12 -07002832 case greenland::IntrinsicHelper::NewInstance:
2833 cvtNewInstance(cUnit, callInst);
2834 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002835 case greenland::IntrinsicHelper::HLSgetObject:
buzbee4f1181f2012-06-22 13:52:12 -07002836 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
2837 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002838 case greenland::IntrinsicHelper::HLSget:
2839 case greenland::IntrinsicHelper::HLSgetFloat:
2840 case greenland::IntrinsicHelper::HLSgetBoolean:
2841 case greenland::IntrinsicHelper::HLSgetByte:
2842 case greenland::IntrinsicHelper::HLSgetChar:
2843 case greenland::IntrinsicHelper::HLSgetShort:
2844 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
2845 break;
2846 case greenland::IntrinsicHelper::HLSgetWide:
2847 case greenland::IntrinsicHelper::HLSgetDouble:
2848 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
2849 break;
buzbee76592632012-06-29 15:18:35 -07002850 case greenland::IntrinsicHelper::HLSput:
2851 case greenland::IntrinsicHelper::HLSputFloat:
2852 case greenland::IntrinsicHelper::HLSputBoolean:
2853 case greenland::IntrinsicHelper::HLSputByte:
2854 case greenland::IntrinsicHelper::HLSputChar:
2855 case greenland::IntrinsicHelper::HLSputShort:
2856 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
2857 break;
2858 case greenland::IntrinsicHelper::HLSputWide:
2859 case greenland::IntrinsicHelper::HLSputDouble:
2860 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
2861 break;
buzbee32412962012-06-26 16:27:56 -07002862 case greenland::IntrinsicHelper::GetException:
2863 cvtMoveException(cUnit, callInst);
2864 break;
2865 case greenland::IntrinsicHelper::Throw:
2866 cvtThrow(cUnit, callInst);
2867 break;
2868 case greenland::IntrinsicHelper::ThrowVerificationError:
buzbee8fa0fda2012-06-27 15:44:52 -07002869 cvtThrowVerificationError(cUnit, callInst);
buzbee32412962012-06-26 16:27:56 -07002870 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002871 case greenland::IntrinsicHelper::MonitorEnter:
2872 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
2873 break;
2874 case greenland::IntrinsicHelper::MonitorExit:
2875 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
2876 break;
2877 case greenland::IntrinsicHelper::ArrayLength:
buzbee76592632012-06-29 15:18:35 -07002878 cvtArrayLength(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07002879 break;
2880 case greenland::IntrinsicHelper::NewArray:
2881 cvtNewArray(cUnit, callInst);
2882 break;
2883 case greenland::IntrinsicHelper::InstanceOf:
2884 cvtInstanceOf(cUnit, callInst);
2885 break;
2886
2887 case greenland::IntrinsicHelper::HLArrayGet:
2888 case greenland::IntrinsicHelper::HLArrayGetObject:
2889 case greenland::IntrinsicHelper::HLArrayGetFloat:
2890 cvtAget(cUnit, callInst, kWord, 2);
2891 break;
2892 case greenland::IntrinsicHelper::HLArrayGetWide:
2893 case greenland::IntrinsicHelper::HLArrayGetDouble:
2894 cvtAget(cUnit, callInst, kLong, 3);
2895 break;
2896 case greenland::IntrinsicHelper::HLArrayGetBoolean:
2897 cvtAget(cUnit, callInst, kUnsignedByte, 0);
2898 break;
2899 case greenland::IntrinsicHelper::HLArrayGetByte:
2900 cvtAget(cUnit, callInst, kSignedByte, 0);
2901 break;
2902 case greenland::IntrinsicHelper::HLArrayGetChar:
2903 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
2904 break;
2905 case greenland::IntrinsicHelper::HLArrayGetShort:
2906 cvtAget(cUnit, callInst, kSignedHalf, 1);
2907 break;
2908
2909 case greenland::IntrinsicHelper::HLArrayPut:
2910 case greenland::IntrinsicHelper::HLArrayPutObject:
2911 case greenland::IntrinsicHelper::HLArrayPutFloat:
2912 cvtAput(cUnit, callInst, kWord, 2);
2913 break;
2914 case greenland::IntrinsicHelper::HLArrayPutWide:
2915 case greenland::IntrinsicHelper::HLArrayPutDouble:
2916 cvtAput(cUnit, callInst, kLong, 3);
2917 break;
2918 case greenland::IntrinsicHelper::HLArrayPutBoolean:
2919 cvtAput(cUnit, callInst, kUnsignedByte, 0);
2920 break;
2921 case greenland::IntrinsicHelper::HLArrayPutByte:
2922 cvtAput(cUnit, callInst, kSignedByte, 0);
2923 break;
2924 case greenland::IntrinsicHelper::HLArrayPutChar:
2925 cvtAput(cUnit, callInst, kUnsignedHalf, 1);
2926 break;
2927 case greenland::IntrinsicHelper::HLArrayPutShort:
2928 cvtAput(cUnit, callInst, kSignedHalf, 1);
2929 break;
2930
buzbee101305f2012-06-28 18:00:56 -07002931 case greenland::IntrinsicHelper::HLIGet:
2932 case greenland::IntrinsicHelper::HLIGetFloat:
2933 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
2934 break;
2935 case greenland::IntrinsicHelper::HLIGetObject:
2936 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
2937 break;
2938 case greenland::IntrinsicHelper::HLIGetWide:
2939 case greenland::IntrinsicHelper::HLIGetDouble:
2940 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
2941 break;
2942 case greenland::IntrinsicHelper::HLIGetBoolean:
2943 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
2944 false /* obj */);
2945 break;
2946 case greenland::IntrinsicHelper::HLIGetByte:
2947 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
2948 false /* obj */);
2949 break;
2950 case greenland::IntrinsicHelper::HLIGetChar:
2951 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
2952 false /* obj */);
2953 break;
2954 case greenland::IntrinsicHelper::HLIGetShort:
2955 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
2956 false /* obj */);
2957 break;
2958
2959 case greenland::IntrinsicHelper::HLIPut:
2960 case greenland::IntrinsicHelper::HLIPutFloat:
2961 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
2962 break;
2963 case greenland::IntrinsicHelper::HLIPutObject:
2964 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
2965 break;
2966 case greenland::IntrinsicHelper::HLIPutWide:
2967 case greenland::IntrinsicHelper::HLIPutDouble:
2968 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
2969 break;
2970 case greenland::IntrinsicHelper::HLIPutBoolean:
2971 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
2972 false /* obj */);
2973 break;
2974 case greenland::IntrinsicHelper::HLIPutByte:
2975 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
2976 false /* obj */);
2977 break;
2978 case greenland::IntrinsicHelper::HLIPutChar:
2979 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
2980 false /* obj */);
2981 break;
2982 case greenland::IntrinsicHelper::HLIPutShort:
2983 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
2984 false /* obj */);
2985 break;
2986
2987 case greenland::IntrinsicHelper::IntToChar:
2988 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
2989 break;
2990 case greenland::IntrinsicHelper::IntToShort:
2991 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
2992 break;
2993 case greenland::IntrinsicHelper::IntToByte:
2994 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
2995 break;
2996
buzbee76592632012-06-29 15:18:35 -07002997 case greenland::IntrinsicHelper::CmplFloat:
2998 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
2999 break;
3000 case greenland::IntrinsicHelper::CmpgFloat:
3001 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3002 break;
3003 case greenland::IntrinsicHelper::CmplDouble:
3004 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3005 break;
3006 case greenland::IntrinsicHelper::CmpgDouble:
3007 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3008 break;
3009
3010 case greenland::IntrinsicHelper::CmpLong:
3011 cvtLongCompare(cUnit, callInst);
3012 break;
3013
buzbee2cfc6392012-05-07 14:51:40 -07003014 case greenland::IntrinsicHelper::UnknownId:
3015 cvtCall(cUnit, callInst, callee);
3016 break;
3017 default:
3018 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
3019 << cUnit->intrinsic_helper->GetName(id);
3020 }
3021 }
3022 break;
3023
3024 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3025 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3026 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3027 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3028 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3029 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3030 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3031 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3032 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
buzbee101305f2012-06-28 18:00:56 -07003033 case llvm::Instruction::Shl: cvtShiftOp(cUnit, kOpLsl, inst); break;
3034 case llvm::Instruction::LShr: cvtShiftOp(cUnit, kOpLsr, inst); break;
3035 case llvm::Instruction::AShr: cvtShiftOp(cUnit, kOpAsr, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003036 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3037 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
buzbee4f1181f2012-06-22 13:52:12 -07003038 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3039 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3040 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3041 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3042 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
buzbee76592632012-06-29 15:18:35 -07003043 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
3044 case llvm::Instruction::FPToSI: cvtFPToInt(cUnit, inst); break;
3045 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3046 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3047 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003048
buzbee101305f2012-06-28 18:00:56 -07003049 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3050 break;
3051 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3052 break;
3053
buzbeef58c12c2012-07-03 15:06:29 -07003054 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3055
buzbee32412962012-06-26 16:27:56 -07003056 case llvm::Instruction::Unreachable:
3057 break; // FIXME: can we really ignore these?
3058
buzbee2cfc6392012-05-07 14:51:40 -07003059 case llvm::Instruction::Invoke:
buzbee2cfc6392012-05-07 14:51:40 -07003060 case llvm::Instruction::FPToUI:
buzbee2cfc6392012-05-07 14:51:40 -07003061 case llvm::Instruction::UIToFP:
buzbee2cfc6392012-05-07 14:51:40 -07003062 case llvm::Instruction::PtrToInt:
3063 case llvm::Instruction::IntToPtr:
buzbee2cfc6392012-05-07 14:51:40 -07003064 case llvm::Instruction::FCmp:
buzbee2cfc6392012-05-07 14:51:40 -07003065 case llvm::Instruction::URem:
3066 case llvm::Instruction::UDiv:
3067 case llvm::Instruction::Resume:
buzbee2cfc6392012-05-07 14:51:40 -07003068 case llvm::Instruction::Alloca:
3069 case llvm::Instruction::GetElementPtr:
3070 case llvm::Instruction::Fence:
3071 case llvm::Instruction::AtomicCmpXchg:
3072 case llvm::Instruction::AtomicRMW:
3073 case llvm::Instruction::BitCast:
3074 case llvm::Instruction::VAArg:
3075 case llvm::Instruction::Select:
3076 case llvm::Instruction::UserOp1:
3077 case llvm::Instruction::UserOp2:
3078 case llvm::Instruction::ExtractElement:
3079 case llvm::Instruction::InsertElement:
3080 case llvm::Instruction::ShuffleVector:
3081 case llvm::Instruction::ExtractValue:
3082 case llvm::Instruction::InsertValue:
3083 case llvm::Instruction::LandingPad:
3084 case llvm::Instruction::IndirectBr:
3085 case llvm::Instruction::Load:
3086 case llvm::Instruction::Store:
3087 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3088
3089 default:
3090 LOG(FATAL) << "Unknown llvm opcode: " << opcode; break;
3091 }
3092 }
buzbee6969d502012-06-15 16:40:31 -07003093
3094 if (headLIR != NULL) {
3095 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
3096 }
buzbee2cfc6392012-05-07 14:51:40 -07003097 return false;
3098}
3099
3100/*
3101 * Convert LLVM_IR to MIR:
3102 * o Iterate through the LLVM_IR and construct a graph using
3103 * standard MIR building blocks.
3104 * o Perform a basic-block optimization pass to remove unnecessary
3105 * store/load sequences.
3106 * o Convert the LLVM Value operands into RegLocations where applicable.
3107 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3108 * o Perform register promotion
3109 * o Iterate through the graph a basic block at a time, generating
3110 * LIR.
3111 * o Assemble LIR as usual.
3112 * o Profit.
3113 */
3114void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3115{
buzbeead8f15e2012-06-18 14:49:45 -07003116 llvm::Function* func = cUnit->func;
3117 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003118 // Allocate a list for LIR basic block labels
3119 cUnit->blockLabelList =
3120 (void*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3121 LIR* labelList = (LIR*)cUnit->blockLabelList;
3122 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003123 for (llvm::Function::iterator i = func->begin(),
3124 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003125 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3126 &labelList[nextLabel++]);
3127 }
buzbeead8f15e2012-06-18 14:49:45 -07003128
3129 /*
3130 * Keep honest - clear regLocations, Value => RegLocation,
3131 * promotion map and VmapTables.
3132 */
3133 cUnit->locMap.clear(); // Start fresh
3134 cUnit->regLocation = NULL;
3135 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3136 i++) {
3137 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3138 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3139 }
3140 cUnit->coreSpillMask = 0;
3141 cUnit->numCoreSpills = 0;
3142 cUnit->fpSpillMask = 0;
3143 cUnit->numFPSpills = 0;
3144 cUnit->coreVmapTable.clear();
3145 cUnit->fpVmapTable.clear();
3146 oatAdjustSpillMask(cUnit);
3147 cUnit->frameSize = oatComputeFrameSize(cUnit);
3148
3149 /*
3150 * At this point, we've lost all knowledge of register promotion.
3151 * Rebuild that info from the MethodInfo intrinsic (if it
3152 * exists - not required for correctness).
3153 */
3154 // TODO: find and recover MethodInfo.
3155
3156 // Create RegLocations for arguments
3157 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3158 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3159 for (; it != it_end; ++it) {
3160 llvm::Value* val = it;
3161 createLocFromValue(cUnit, val);
3162 }
3163 // Create RegLocations for all non-argument defintions
3164 for (llvm::inst_iterator i = llvm::inst_begin(func),
3165 e = llvm::inst_end(func); i != e; ++i) {
3166 llvm::Value* val = &*i;
3167 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3168 createLocFromValue(cUnit, val);
3169 }
3170 }
3171
buzbee2cfc6392012-05-07 14:51:40 -07003172 // Walk the blocks, generating code.
3173 for (llvm::Function::iterator i = cUnit->func->begin(),
3174 e = cUnit->func->end(); i != e; ++i) {
3175 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3176 }
3177
3178 handleSuspendLaunchpads(cUnit);
3179
3180 handleThrowLaunchpads(cUnit);
3181
3182 handleIntrinsicLaunchpads(cUnit);
3183
3184 freeIR(cUnit);
3185}
3186
3187
3188} // namespace art
3189
3190#endif // ART_USE_QUICK_COMPILER