blob: cf7b6ff8ad74ac287c18b3936276eb00bb8c7aca [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
buzbeea1da8a52012-07-09 14:00:21 -0700175void convertSparseSwitch(CompilationUnit* cUnit, BasicBlock* bb,
176 int32_t tableOffset, RegLocation rlSrc)
177{
178 const Instruction::SparseSwitchPayload* payload =
179 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
180 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
181
182 const int32_t* keys = payload->GetKeys();
183 const int32_t* targets = payload->GetTargets();
184
185 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
186
187 llvm::SwitchInst* sw =
188 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
189 payload->case_count);
190
191 for (size_t i = 0; i < payload->case_count; ++i) {
192 llvm::BasicBlock* llvmBB =
193 findCaseTarget(cUnit, cUnit->currentDalvikOffset + targets[i]);
194 sw->addCase(cUnit->irb->getInt32(keys[i]), llvmBB);
195 }
196 llvm::MDNode* switchNode =
197 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
198 sw->setMetadata("SwitchTable", switchNode);
199 bb->taken = NULL;
200 bb->fallThrough = NULL;
201}
202
buzbee8fa0fda2012-06-27 15:44:52 -0700203void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
204 greenland::IntrinsicHelper::IntrinsicId id,
205 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700206{
buzbee8fa0fda2012-06-27 15:44:52 -0700207 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700208 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700209 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
210 defineValue(cUnit, res, rlDest.origSReg);
211}
212
213void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
214 greenland::IntrinsicHelper::IntrinsicId id,
215 RegLocation rlSrc)
216{
217 llvm::SmallVector<llvm::Value*, 2> args;
218 args.push_back(cUnit->irb->getInt32(fieldIndex));
219 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
220 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
221 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700222}
223
buzbee101305f2012-06-28 18:00:56 -0700224void convertFillArrayData(CompilationUnit* cUnit, int32_t offset,
225 RegLocation rlArray)
226{
227 greenland::IntrinsicHelper::IntrinsicId id;
228 id = greenland::IntrinsicHelper::FillArrayData;
229 llvm::SmallVector<llvm::Value*, 2> args;
230 args.push_back(cUnit->irb->getInt32(offset));
231 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
232 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
233 cUnit->irb->CreateCall(intr, args);
234}
235
buzbee2cfc6392012-05-07 14:51:40 -0700236llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
237 RegLocation loc)
238{
239 greenland::IntrinsicHelper::IntrinsicId id;
240 if (loc.wide) {
241 if (loc.fp) {
242 id = greenland::IntrinsicHelper::ConstDouble;
243 } else {
244 id = greenland::IntrinsicHelper::ConstLong;
245 }
246 } else {
247 if (loc.fp) {
248 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700249 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700250 id = greenland::IntrinsicHelper::ConstObj;
251 } else {
252 id = greenland::IntrinsicHelper::ConstInt;
253 }
254 }
255 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
256 return cUnit->irb->CreateCall(intr, src);
257}
buzbeeb03f4872012-06-11 15:22:11 -0700258
259void emitPopShadowFrame(CompilationUnit* cUnit)
260{
261 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
262 greenland::IntrinsicHelper::PopShadowFrame);
263 cUnit->irb->CreateCall(intr);
264}
265
buzbee2cfc6392012-05-07 14:51:40 -0700266llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
267 RegLocation loc)
268{
269 greenland::IntrinsicHelper::IntrinsicId id;
270 if (loc.wide) {
271 if (loc.fp) {
272 id = greenland::IntrinsicHelper::CopyDouble;
273 } else {
274 id = greenland::IntrinsicHelper::CopyLong;
275 }
276 } else {
277 if (loc.fp) {
278 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700279 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700280 id = greenland::IntrinsicHelper::CopyObj;
281 } else {
282 id = greenland::IntrinsicHelper::CopyInt;
283 }
284 }
285 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
286 return cUnit->irb->CreateCall(intr, src);
287}
288
buzbee32412962012-06-26 16:27:56 -0700289void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
290{
291 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
292 greenland::IntrinsicHelper::GetException);
293 llvm::Value* res = cUnit->irb->CreateCall(func);
294 defineValue(cUnit, res, rlDest.origSReg);
295}
296
297void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
298{
299 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
300 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
301 greenland::IntrinsicHelper::Throw);
302 cUnit->irb->CreateCall(func, src);
303 cUnit->irb->CreateUnreachable();
304}
305
buzbee8fa0fda2012-06-27 15:44:52 -0700306void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
307 greenland::IntrinsicHelper::IntrinsicId id,
308 RegLocation rlSrc)
309{
310 llvm::SmallVector<llvm::Value*, 2> args;
311 args.push_back(cUnit->irb->getInt32(optFlags));
312 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
313 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
314 cUnit->irb->CreateCall(func, args);
315}
316
buzbee76592632012-06-29 15:18:35 -0700317void convertArrayLength(CompilationUnit* cUnit, int optFlags,
318 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700319{
320 llvm::SmallVector<llvm::Value*, 2> args;
321 args.push_back(cUnit->irb->getInt32(optFlags));
322 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
323 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
324 greenland::IntrinsicHelper::ArrayLength);
buzbee76592632012-06-29 15:18:35 -0700325 llvm::Value* res = cUnit->irb->CreateCall(func, args);
326 defineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700327}
328
buzbee32412962012-06-26 16:27:56 -0700329void convertThrowVerificationError(CompilationUnit* cUnit, int info1, int info2)
330{
331 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
buzbeea1da8a52012-07-09 14:00:21 -0700332 greenland::IntrinsicHelper::ThrowVerificationError);
buzbee32412962012-06-26 16:27:56 -0700333 llvm::SmallVector<llvm::Value*, 2> args;
334 args.push_back(cUnit->irb->getInt32(info1));
335 args.push_back(cUnit->irb->getInt32(info2));
336 cUnit->irb->CreateCall(func, args);
337 cUnit->irb->CreateUnreachable();
338}
339
buzbee2cfc6392012-05-07 14:51:40 -0700340void emitSuspendCheck(CompilationUnit* cUnit)
341{
342 greenland::IntrinsicHelper::IntrinsicId id =
343 greenland::IntrinsicHelper::CheckSuspend;
344 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
345 cUnit->irb->CreateCall(intr);
346}
347
348llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
349 llvm::Value* src1, llvm::Value* src2)
350{
351 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700352 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700353 switch(cc) {
354 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
355 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
356 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
357 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
358 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
359 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
360 default: LOG(FATAL) << "Unexpected cc value " << cc;
361 }
362 return res;
363}
364
365void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
366 ConditionCode cc, RegLocation rlSrc1,
367 RegLocation rlSrc2)
368{
369 if (bb->taken->startOffset <= mir->offset) {
370 emitSuspendCheck(cUnit);
371 }
372 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
373 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
374 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
375 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
376 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
377 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700378 // Don't redo the fallthrough branch in the BB driver
379 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700380}
381
382void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
383 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
384{
385 if (bb->taken->startOffset <= mir->offset) {
386 emitSuspendCheck(cUnit);
387 }
388 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
389 llvm::Value* src2;
390 if (rlSrc1.ref) {
391 src2 = cUnit->irb->GetJNull();
392 } else {
393 src2 = cUnit->irb->getInt32(0);
394 }
395 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
buzbee2cfc6392012-05-07 14:51:40 -0700396 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
397 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700398 // Don't redo the fallthrough branch in the BB driver
399 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700400}
401
402llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
403 llvm::Value* src1, llvm::Value* src2)
404{
405 greenland::IntrinsicHelper::IntrinsicId id;
406 if (isLong) {
407 if (isDiv) {
408 id = greenland::IntrinsicHelper::DivLong;
409 } else {
410 id = greenland::IntrinsicHelper::RemLong;
411 }
412 } else if (isDiv) {
413 id = greenland::IntrinsicHelper::DivInt;
414 } else {
415 id = greenland::IntrinsicHelper::RemInt;
416 }
417 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
418 llvm::SmallVector<llvm::Value*, 2>args;
419 args.push_back(src1);
420 args.push_back(src2);
421 return cUnit->irb->CreateCall(intr, args);
422}
423
424llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
425 llvm::Value* src1, llvm::Value* src2)
426{
427 llvm::Value* res = NULL;
428 switch(op) {
429 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
430 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700431 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700432 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
433 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
434 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
435 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
436 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
437 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700438 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
439 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
440 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700441 default:
442 LOG(FATAL) << "Invalid op " << op;
443 }
444 return res;
445}
446
447void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
448 RegLocation rlSrc1, RegLocation rlSrc2)
449{
450 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
451 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
452 llvm::Value* res = NULL;
453 switch(op) {
454 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
455 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
456 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
457 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
458 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
459 default:
460 LOG(FATAL) << "Invalid op " << op;
461 }
462 defineValue(cUnit, res, rlDest.origSReg);
463}
464
buzbee4f1181f2012-06-22 13:52:12 -0700465void convertShift(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
466 RegLocation rlSrc1, RegLocation rlSrc2)
467{
468 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
buzbee101305f2012-06-28 18:00:56 -0700469 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
470 /*
471 * TODO: Figure out how best to handle constraining the shift
472 * amount to 31 for int and 63 for long. We take care of this
473 * inline for int and in the out-of-line handler for longs, so
474 * it's a bit of a waste to generate llvm bitcode for this.
475 * Yet more intrinsics?
476 */
477 UNIMPLEMENTED(WARNING) << "llvm shift mismatch";
buzbee4f1181f2012-06-22 13:52:12 -0700478 if (rlDest.wide) {
buzbee101305f2012-06-28 18:00:56 -0700479 // llvm thinks the shift could should be in 64 bits.
480 src2 = cUnit->irb->CreateZExt(src2, cUnit->irb->getInt64Ty());
buzbee4f1181f2012-06-22 13:52:12 -0700481 }
buzbee101305f2012-06-28 18:00:56 -0700482 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
buzbee4f1181f2012-06-22 13:52:12 -0700483 defineValue(cUnit, res, rlDest.origSReg);
484}
485
buzbee2cfc6392012-05-07 14:51:40 -0700486void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
487 RegLocation rlSrc1, RegLocation rlSrc2)
488{
489 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
490 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700491 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700492 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
493 defineValue(cUnit, res, rlDest.origSReg);
494}
495
buzbeeb03f4872012-06-11 15:22:11 -0700496void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
497{
498 int index = -1;
499 DCHECK(newVal != NULL);
500 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
501 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
502 if (cUnit->shadowMap[i] == vReg) {
503 index = i;
504 break;
505 }
506 }
Elliott Hughes74847412012-06-20 18:10:21 -0700507 DCHECK_NE(index, -1) << "Corrupt shadowMap";
buzbeeb03f4872012-06-11 15:22:11 -0700508 greenland::IntrinsicHelper::IntrinsicId id =
509 greenland::IntrinsicHelper::SetShadowFrameEntry;
510 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
511 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
512 llvm::Value* args[] = { newVal, tableSlot };
513 cUnit->irb->CreateCall(func, args);
514}
515
buzbee2cfc6392012-05-07 14:51:40 -0700516void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
517 RegLocation rlSrc1, int32_t imm)
518{
519 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
520 llvm::Value* src2 = cUnit->irb->getInt32(imm);
521 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
522 defineValue(cUnit, res, rlDest.origSReg);
523}
524
buzbee101305f2012-06-28 18:00:56 -0700525/*
526 * Process arguments for invoke. Note: this code is also used to
527 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
528 * The requirements are similar.
529 */
buzbee6969d502012-06-15 16:40:31 -0700530void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700531 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700532{
533 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
534 llvm::SmallVector<llvm::Value*, 10> args;
535 // Insert the invokeType
536 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
537 // Insert the method_idx
538 args.push_back(cUnit->irb->getInt32(info->index));
539 // Insert the optimization flags
540 args.push_back(cUnit->irb->getInt32(info->optFlags));
541 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700542 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700543 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
544 args.push_back(val);
545 i += info->args[i].wide ? 2 : 1;
546 }
547 /*
548 * Choose the invoke return type based on actual usage. Note: may
549 * be different than shorty. For example, if a function return value
550 * is not used, we'll treat this as a void invoke.
551 */
552 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700553 if (isFilledNewArray) {
554 id = greenland::IntrinsicHelper::FilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700555 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700556 id = greenland::IntrinsicHelper::HLInvokeVoid;
557 } else {
558 if (info->result.wide) {
559 if (info->result.fp) {
560 id = greenland::IntrinsicHelper::HLInvokeDouble;
561 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700562 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700563 }
564 } else if (info->result.ref) {
565 id = greenland::IntrinsicHelper::HLInvokeObj;
566 } else if (info->result.fp) {
567 id = greenland::IntrinsicHelper::HLInvokeFloat;
568 } else {
569 id = greenland::IntrinsicHelper::HLInvokeInt;
570 }
571 }
572 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
573 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
574 if (info->result.location != kLocInvalid) {
575 defineValue(cUnit, res, info->result.origSReg);
576 }
577}
578
buzbee101305f2012-06-28 18:00:56 -0700579void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
580 greenland::IntrinsicHelper::IntrinsicId id,
581 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700582{
buzbee6969d502012-06-15 16:40:31 -0700583 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700584 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700585 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
586 defineValue(cUnit, res, rlDest.origSReg);
587}
588
buzbee101305f2012-06-28 18:00:56 -0700589void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
590 RegLocation rlSrc)
591{
592 greenland::IntrinsicHelper::IntrinsicId id;
593 id = greenland::IntrinsicHelper::CheckCast;
594 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
595 llvm::SmallVector<llvm::Value*, 2> args;
596 args.push_back(cUnit->irb->getInt32(type_idx));
597 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
598 cUnit->irb->CreateCall(intr, args);
599}
600
buzbee8fa0fda2012-06-27 15:44:52 -0700601void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
602 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700603{
604 greenland::IntrinsicHelper::IntrinsicId id;
605 id = greenland::IntrinsicHelper::NewInstance;
606 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
607 llvm::Value* index = cUnit->irb->getInt32(type_idx);
608 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
609 defineValue(cUnit, res, rlDest.origSReg);
610}
611
buzbee8fa0fda2012-06-27 15:44:52 -0700612void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
613 RegLocation rlDest, RegLocation rlSrc)
614{
615 greenland::IntrinsicHelper::IntrinsicId id;
616 id = greenland::IntrinsicHelper::NewArray;
617 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
618 llvm::SmallVector<llvm::Value*, 2> args;
619 args.push_back(cUnit->irb->getInt32(type_idx));
620 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
621 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
622 defineValue(cUnit, res, rlDest.origSReg);
623}
624
625void convertAget(CompilationUnit* cUnit, int optFlags,
626 greenland::IntrinsicHelper::IntrinsicId id,
627 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
628{
629 llvm::SmallVector<llvm::Value*, 3> args;
630 args.push_back(cUnit->irb->getInt32(optFlags));
631 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
632 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
633 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
634 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
635 defineValue(cUnit, res, rlDest.origSReg);
636}
637
638void convertAput(CompilationUnit* cUnit, int optFlags,
639 greenland::IntrinsicHelper::IntrinsicId id,
640 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
641{
642 llvm::SmallVector<llvm::Value*, 4> args;
643 args.push_back(cUnit->irb->getInt32(optFlags));
644 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
645 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
646 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
647 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
648 cUnit->irb->CreateCall(intr, args);
649}
650
buzbee101305f2012-06-28 18:00:56 -0700651void convertIget(CompilationUnit* cUnit, int optFlags,
652 greenland::IntrinsicHelper::IntrinsicId id,
653 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
654{
655 llvm::SmallVector<llvm::Value*, 3> args;
656 args.push_back(cUnit->irb->getInt32(optFlags));
657 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
658 args.push_back(cUnit->irb->getInt32(fieldIndex));
659 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
660 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
661 defineValue(cUnit, res, rlDest.origSReg);
662}
663
664void convertIput(CompilationUnit* cUnit, int optFlags,
665 greenland::IntrinsicHelper::IntrinsicId id,
666 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
667{
668 llvm::SmallVector<llvm::Value*, 4> args;
669 args.push_back(cUnit->irb->getInt32(optFlags));
670 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
671 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
672 args.push_back(cUnit->irb->getInt32(fieldIndex));
673 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
674 cUnit->irb->CreateCall(intr, args);
675}
676
buzbee8fa0fda2012-06-27 15:44:52 -0700677void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
678 RegLocation rlDest, RegLocation rlSrc)
679{
680 greenland::IntrinsicHelper::IntrinsicId id;
681 id = greenland::IntrinsicHelper::InstanceOf;
682 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
683 llvm::SmallVector<llvm::Value*, 2> args;
684 args.push_back(cUnit->irb->getInt32(type_idx));
685 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
686 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
687 defineValue(cUnit, res, rlDest.origSReg);
688}
689
buzbee101305f2012-06-28 18:00:56 -0700690void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
691 RegLocation rlSrc)
692{
693 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
694 cUnit->irb->getInt64Ty());
695 defineValue(cUnit, res, rlDest.origSReg);
696}
697
buzbee76592632012-06-29 15:18:35 -0700698void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
699 RegLocation rlSrc)
700{
701 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
702 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
703 defineValue(cUnit, res, rlDest.origSReg);
704}
705
706void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
707 RegLocation rlSrc)
708{
709 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
710 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
711 defineValue(cUnit, res, rlDest.origSReg);
712}
713
714void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
715 RegLocation rlSrc)
716{
717 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
718 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
719 defineValue(cUnit, res, rlDest.origSReg);
720}
721
722void convertWideComparison(CompilationUnit* cUnit,
723 greenland::IntrinsicHelper::IntrinsicId id,
724 RegLocation rlDest, RegLocation rlSrc1,
725 RegLocation rlSrc2)
726{
727 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
728 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
729 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
730 llvm::SmallVector<llvm::Value*, 2> args;
731 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
732 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
733 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
734 defineValue(cUnit, res, rlDest.origSReg);
735}
736
buzbee101305f2012-06-28 18:00:56 -0700737void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
738 RegLocation rlSrc,
739 greenland::IntrinsicHelper::IntrinsicId id)
740{
741 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700742 llvm::Value* res =
743 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
744 defineValue(cUnit, res, rlDest.origSReg);
745}
746
747void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
748 RegLocation rlSrc)
749{
750 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
751 defineValue(cUnit, res, rlDest.origSReg);
752}
753
754void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
755 RegLocation rlSrc)
756{
757 llvm::Value* res =
758 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
759 defineValue(cUnit, res, rlDest.origSReg);
760}
761
762void convertFPToInt(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
763 RegLocation rlSrc)
764{
765 llvm::Value* res =
766 cUnit->irb->CreateFPToSI(getLLVMValue(cUnit, rlSrc.origSReg), ty);
767 defineValue(cUnit, res, rlDest.origSReg);
768}
769
770
771void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
772 RegLocation rlSrc)
773{
774 llvm::Value* res =
775 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
776 defineValue(cUnit, res, rlDest.origSReg);
777}
778
779void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
780 RegLocation rlSrc)
781{
782 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
783 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700784 defineValue(cUnit, res, rlDest.origSReg);
785}
786
buzbee2cfc6392012-05-07 14:51:40 -0700787/*
788 * Target-independent code generation. Use only high-level
789 * load/store utilities here, or target-dependent genXX() handlers
790 * when necessary.
791 */
792bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
793 llvm::BasicBlock* llvmBB, LIR* labelList)
794{
795 bool res = false; // Assume success
796 RegLocation rlSrc[3];
797 RegLocation rlDest = badLoc;
798 RegLocation rlResult = badLoc;
799 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee32412962012-06-26 16:27:56 -0700800 uint32_t vA = mir->dalvikInsn.vA;
buzbee6969d502012-06-15 16:40:31 -0700801 uint32_t vB = mir->dalvikInsn.vB;
802 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700803 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700804
buzbeeb03f4872012-06-11 15:22:11 -0700805 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700806
807 /* Prep Src and Dest locations */
808 int nextSreg = 0;
809 int nextLoc = 0;
810 int attrs = oatDataFlowAttributes[opcode];
811 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
812 if (attrs & DF_UA) {
813 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700814 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700815 nextSreg+= 2;
816 } else {
817 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
818 nextSreg++;
819 }
820 }
821 if (attrs & DF_UB) {
822 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700823 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700824 nextSreg+= 2;
825 } else {
826 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
827 nextSreg++;
828 }
829 }
830 if (attrs & DF_UC) {
831 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700832 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700833 } else {
834 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
835 }
836 }
837 if (attrs & DF_DA) {
838 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700839 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700840 } else {
buzbee15bf9802012-06-12 17:49:27 -0700841 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700842 if (rlDest.ref) {
843 objectDefinition = true;
844 }
buzbee2cfc6392012-05-07 14:51:40 -0700845 }
846 }
847
848 switch (opcode) {
849 case Instruction::NOP:
850 break;
851
852 case Instruction::MOVE:
853 case Instruction::MOVE_OBJECT:
854 case Instruction::MOVE_16:
855 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700856 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700857 case Instruction::MOVE_FROM16:
858 case Instruction::MOVE_WIDE:
859 case Instruction::MOVE_WIDE_16:
860 case Instruction::MOVE_WIDE_FROM16: {
861 /*
862 * Moves/copies are meaningless in pure SSA register form,
863 * but we need to preserve them for the conversion back into
864 * MIR (at least until we stop using the Dalvik register maps).
865 * Insert a dummy intrinsic copy call, which will be recognized
866 * by the quick path and removed by the portable path.
867 */
868 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
869 llvm::Value* res = emitCopy(cUnit, src, rlDest);
870 defineValue(cUnit, res, rlDest.origSReg);
871 }
872 break;
873
874 case Instruction::CONST:
875 case Instruction::CONST_4:
876 case Instruction::CONST_16: {
buzbee6969d502012-06-15 16:40:31 -0700877 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700878 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
879 defineValue(cUnit, res, rlDest.origSReg);
880 }
881 break;
882
883 case Instruction::CONST_WIDE_16:
884 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700885 // Sign extend to 64 bits
886 int64_t imm = static_cast<int32_t>(vB);
887 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700888 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
889 defineValue(cUnit, res, rlDest.origSReg);
890 }
891 break;
892
893 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700894 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700895 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
896 defineValue(cUnit, res, rlDest.origSReg);
897 }
898 break;
899
900 case Instruction::CONST_WIDE: {
901 llvm::Constant* immValue =
902 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
903 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
904 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700905 }
906 break;
buzbee2cfc6392012-05-07 14:51:40 -0700907 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700908 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700909 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
910 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
911 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700912 }
913 break;
914
buzbee8fa0fda2012-06-27 15:44:52 -0700915 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700916 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700917 rlSrc[0]);
918 break;
919 case Instruction::SPUT:
920 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700921 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700922 rlSrc[0]);
923 } else {
buzbee76592632012-06-29 15:18:35 -0700924 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700925 }
926 break;
927 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700928 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700929 rlSrc[0]);
930 break;
931 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700932 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700933 break;
934 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -0700935 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700936 break;
937 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -0700938 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700939 break;
940 case Instruction::SPUT_WIDE:
941 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700942 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -0700943 rlSrc[0]);
944 } else {
buzbee76592632012-06-29 15:18:35 -0700945 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -0700946 rlSrc[0]);
947 }
948 break;
949
950 case Instruction::SGET_OBJECT:
951 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
952 break;
953 case Instruction::SGET:
954 if (rlDest.fp) {
955 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
956 } else {
957 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
958 }
959 break;
960 case Instruction::SGET_BOOLEAN:
961 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
962 break;
963 case Instruction::SGET_BYTE:
964 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
965 break;
966 case Instruction::SGET_CHAR:
967 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
968 break;
969 case Instruction::SGET_SHORT:
970 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
971 break;
972 case Instruction::SGET_WIDE:
973 if (rlDest.fp) {
974 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
975 rlDest);
976 } else {
977 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -0700978 }
979 break;
buzbee2cfc6392012-05-07 14:51:40 -0700980
981 case Instruction::RETURN_WIDE:
982 case Instruction::RETURN:
983 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -0700984 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700985 emitSuspendCheck(cUnit);
986 }
buzbeeb03f4872012-06-11 15:22:11 -0700987 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700988 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
989 bb->hasReturn = true;
990 }
991 break;
992
993 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -0700994 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -0700995 emitSuspendCheck(cUnit);
996 }
buzbeeb03f4872012-06-11 15:22:11 -0700997 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -0700998 cUnit->irb->CreateRetVoid();
999 bb->hasReturn = true;
1000 }
1001 break;
1002
1003 case Instruction::IF_EQ:
1004 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1005 break;
1006 case Instruction::IF_NE:
1007 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1008 break;
1009 case Instruction::IF_LT:
1010 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1011 break;
1012 case Instruction::IF_GE:
1013 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1014 break;
1015 case Instruction::IF_GT:
1016 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1017 break;
1018 case Instruction::IF_LE:
1019 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1020 break;
1021 case Instruction::IF_EQZ:
1022 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1023 break;
1024 case Instruction::IF_NEZ:
1025 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1026 break;
1027 case Instruction::IF_LTZ:
1028 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1029 break;
1030 case Instruction::IF_GEZ:
1031 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1032 break;
1033 case Instruction::IF_GTZ:
1034 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1035 break;
1036 case Instruction::IF_LEZ:
1037 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1038 break;
1039
1040 case Instruction::GOTO:
1041 case Instruction::GOTO_16:
1042 case Instruction::GOTO_32: {
1043 if (bb->taken->startOffset <= bb->startOffset) {
1044 emitSuspendCheck(cUnit);
1045 }
1046 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1047 }
1048 break;
1049
1050 case Instruction::ADD_LONG:
1051 case Instruction::ADD_LONG_2ADDR:
1052 case Instruction::ADD_INT:
1053 case Instruction::ADD_INT_2ADDR:
1054 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1055 break;
1056 case Instruction::SUB_LONG:
1057 case Instruction::SUB_LONG_2ADDR:
1058 case Instruction::SUB_INT:
1059 case Instruction::SUB_INT_2ADDR:
1060 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1061 break;
1062 case Instruction::MUL_LONG:
1063 case Instruction::MUL_LONG_2ADDR:
1064 case Instruction::MUL_INT:
1065 case Instruction::MUL_INT_2ADDR:
1066 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1067 break;
1068 case Instruction::DIV_LONG:
1069 case Instruction::DIV_LONG_2ADDR:
1070 case Instruction::DIV_INT:
1071 case Instruction::DIV_INT_2ADDR:
1072 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1073 break;
1074 case Instruction::REM_LONG:
1075 case Instruction::REM_LONG_2ADDR:
1076 case Instruction::REM_INT:
1077 case Instruction::REM_INT_2ADDR:
1078 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1079 break;
1080 case Instruction::AND_LONG:
1081 case Instruction::AND_LONG_2ADDR:
1082 case Instruction::AND_INT:
1083 case Instruction::AND_INT_2ADDR:
1084 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1085 break;
1086 case Instruction::OR_LONG:
1087 case Instruction::OR_LONG_2ADDR:
1088 case Instruction::OR_INT:
1089 case Instruction::OR_INT_2ADDR:
1090 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1091 break;
1092 case Instruction::XOR_LONG:
1093 case Instruction::XOR_LONG_2ADDR:
1094 case Instruction::XOR_INT:
1095 case Instruction::XOR_INT_2ADDR:
1096 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1097 break;
1098 case Instruction::SHL_LONG:
1099 case Instruction::SHL_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001100 convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
1101 break;
buzbee2cfc6392012-05-07 14:51:40 -07001102 case Instruction::SHL_INT:
1103 case Instruction::SHL_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001104 convertShift(cUnit, kOpLsl, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001105 break;
1106 case Instruction::SHR_LONG:
1107 case Instruction::SHR_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001108 convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
1109 break;
buzbee2cfc6392012-05-07 14:51:40 -07001110 case Instruction::SHR_INT:
1111 case Instruction::SHR_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001112 convertShift(cUnit, kOpAsr, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001113 break;
1114 case Instruction::USHR_LONG:
1115 case Instruction::USHR_LONG_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001116 convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
1117 break;
buzbee2cfc6392012-05-07 14:51:40 -07001118 case Instruction::USHR_INT:
1119 case Instruction::USHR_INT_2ADDR:
buzbee4f1181f2012-06-22 13:52:12 -07001120 convertShift(cUnit, kOpLsr, rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001121 break;
1122
1123 case Instruction::ADD_INT_LIT16:
1124 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001125 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001126 break;
1127 case Instruction::RSUB_INT:
1128 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001129 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001130 break;
1131 case Instruction::MUL_INT_LIT16:
1132 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001133 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001134 break;
1135 case Instruction::DIV_INT_LIT16:
1136 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001137 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001138 break;
1139 case Instruction::REM_INT_LIT16:
1140 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001141 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001142 break;
1143 case Instruction::AND_INT_LIT16:
1144 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001145 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001146 break;
1147 case Instruction::OR_INT_LIT16:
1148 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001149 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001150 break;
1151 case Instruction::XOR_INT_LIT16:
1152 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001153 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001154 break;
1155 case Instruction::SHL_INT_LIT8:
buzbee4f1181f2012-06-22 13:52:12 -07001156 convertArithOpLit(cUnit, kOpLsl, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001157 break;
1158 case Instruction::SHR_INT_LIT8:
buzbee101305f2012-06-28 18:00:56 -07001159 convertArithOpLit(cUnit, kOpAsr, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001160 break;
1161 case Instruction::USHR_INT_LIT8:
buzbee101305f2012-06-28 18:00:56 -07001162 convertArithOpLit(cUnit, kOpLsr, rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001163 break;
1164
1165 case Instruction::ADD_FLOAT:
1166 case Instruction::ADD_FLOAT_2ADDR:
1167 case Instruction::ADD_DOUBLE:
1168 case Instruction::ADD_DOUBLE_2ADDR:
1169 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1170 break;
1171
1172 case Instruction::SUB_FLOAT:
1173 case Instruction::SUB_FLOAT_2ADDR:
1174 case Instruction::SUB_DOUBLE:
1175 case Instruction::SUB_DOUBLE_2ADDR:
1176 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1177 break;
1178
1179 case Instruction::MUL_FLOAT:
1180 case Instruction::MUL_FLOAT_2ADDR:
1181 case Instruction::MUL_DOUBLE:
1182 case Instruction::MUL_DOUBLE_2ADDR:
1183 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1184 break;
1185
1186 case Instruction::DIV_FLOAT:
1187 case Instruction::DIV_FLOAT_2ADDR:
1188 case Instruction::DIV_DOUBLE:
1189 case Instruction::DIV_DOUBLE_2ADDR:
1190 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1191 break;
1192
1193 case Instruction::REM_FLOAT:
1194 case Instruction::REM_FLOAT_2ADDR:
1195 case Instruction::REM_DOUBLE:
1196 case Instruction::REM_DOUBLE_2ADDR:
1197 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1198 break;
1199
buzbee6969d502012-06-15 16:40:31 -07001200 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001201 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1202 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001203 break;
1204 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001205 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1206 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001207 break;
1208
1209 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001210 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1211 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001212 break;
1213 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001214 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1215 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001216 break;
1217
1218 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001219 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1220 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001221 break;
1222 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001223 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1224 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001225 break;
1226
1227 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001228 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1229 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001230 break;
1231 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001232 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1233 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001234 break;
1235
1236 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001237 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1238 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001239 break;
1240 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001241 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1242 false /* NewFilledArray */);
1243 break;
1244 case Instruction::FILLED_NEW_ARRAY:
1245 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1246 true /* NewFilledArray */);
1247 break;
1248 case Instruction::FILLED_NEW_ARRAY_RANGE:
1249 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1250 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001251 break;
1252
1253 case Instruction::CONST_STRING:
1254 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001255 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1256 rlDest);
1257 break;
1258
1259 case Instruction::CONST_CLASS:
1260 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1261 rlDest);
1262 break;
1263
1264 case Instruction::CHECK_CAST:
1265 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001266 break;
1267
buzbee4f1181f2012-06-22 13:52:12 -07001268 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001269 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001270 break;
1271
buzbee32412962012-06-26 16:27:56 -07001272 case Instruction::MOVE_EXCEPTION:
1273 convertMoveException(cUnit, rlDest);
1274 break;
1275
1276 case Instruction::THROW:
1277 convertThrow(cUnit, rlSrc[0]);
1278 break;
1279
1280 case Instruction::THROW_VERIFICATION_ERROR:
1281 convertThrowVerificationError(cUnit, vA, vB);
1282 break;
buzbee6969d502012-06-15 16:40:31 -07001283
buzbee2cfc6392012-05-07 14:51:40 -07001284 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001285 case Instruction::MOVE_RESULT:
1286 case Instruction::MOVE_RESULT_OBJECT:
buzbee8fa0fda2012-06-27 15:44:52 -07001287 CHECK(false) << "Unexpected MOVE_RESULT";
buzbee2cfc6392012-05-07 14:51:40 -07001288 break;
1289
1290 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001291 convertMonitorEnterExit(cUnit, optFlags,
1292 greenland::IntrinsicHelper::MonitorEnter,
1293 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001294 break;
1295
1296 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001297 convertMonitorEnterExit(cUnit, optFlags,
1298 greenland::IntrinsicHelper::MonitorExit,
1299 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001300 break;
1301
1302 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001303 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001304 break;
1305
1306 case Instruction::NEW_ARRAY:
1307 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1308 break;
1309
1310 case Instruction::INSTANCE_OF:
1311 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1312 break;
1313
1314 case Instruction::AGET:
1315 if (rlDest.fp) {
1316 convertAget(cUnit, optFlags,
1317 greenland::IntrinsicHelper::HLArrayGetFloat,
1318 rlDest, rlSrc[0], rlSrc[1]);
1319 } else {
1320 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1321 rlDest, rlSrc[0], rlSrc[1]);
1322 }
1323 break;
1324 case Instruction::AGET_OBJECT:
1325 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1326 rlDest, rlSrc[0], rlSrc[1]);
1327 break;
1328 case Instruction::AGET_BOOLEAN:
1329 convertAget(cUnit, optFlags,
1330 greenland::IntrinsicHelper::HLArrayGetBoolean,
1331 rlDest, rlSrc[0], rlSrc[1]);
1332 break;
1333 case Instruction::AGET_BYTE:
1334 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1335 rlDest, rlSrc[0], rlSrc[1]);
1336 break;
1337 case Instruction::AGET_CHAR:
1338 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1339 rlDest, rlSrc[0], rlSrc[1]);
1340 break;
1341 case Instruction::AGET_SHORT:
1342 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1343 rlDest, rlSrc[0], rlSrc[1]);
1344 break;
1345 case Instruction::AGET_WIDE:
1346 if (rlDest.fp) {
1347 convertAget(cUnit, optFlags,
1348 greenland::IntrinsicHelper::HLArrayGetDouble,
1349 rlDest, rlSrc[0], rlSrc[1]);
1350 } else {
1351 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1352 rlDest, rlSrc[0], rlSrc[1]);
1353 }
1354 break;
1355
1356 case Instruction::APUT:
1357 if (rlSrc[0].fp) {
1358 convertAput(cUnit, optFlags,
1359 greenland::IntrinsicHelper::HLArrayPutFloat,
1360 rlSrc[0], rlSrc[1], rlSrc[2]);
1361 } else {
1362 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1363 rlSrc[0], rlSrc[1], rlSrc[2]);
1364 }
1365 break;
1366 case Instruction::APUT_OBJECT:
1367 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1368 rlSrc[0], rlSrc[1], rlSrc[2]);
1369 break;
1370 case Instruction::APUT_BOOLEAN:
1371 convertAput(cUnit, optFlags,
1372 greenland::IntrinsicHelper::HLArrayPutBoolean,
1373 rlSrc[0], rlSrc[1], rlSrc[2]);
1374 break;
1375 case Instruction::APUT_BYTE:
1376 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1377 rlSrc[0], rlSrc[1], rlSrc[2]);
1378 break;
1379 case Instruction::APUT_CHAR:
1380 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1381 rlSrc[0], rlSrc[1], rlSrc[2]);
1382 break;
1383 case Instruction::APUT_SHORT:
1384 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1385 rlSrc[0], rlSrc[1], rlSrc[2]);
1386 break;
1387 case Instruction::APUT_WIDE:
1388 if (rlSrc[0].fp) {
1389 convertAput(cUnit, optFlags,
1390 greenland::IntrinsicHelper::HLArrayPutDouble,
1391 rlSrc[0], rlSrc[1], rlSrc[2]);
1392 } else {
1393 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1394 rlSrc[0], rlSrc[1], rlSrc[2]);
1395 }
1396 break;
1397
buzbee101305f2012-06-28 18:00:56 -07001398 case Instruction::IGET:
1399 if (rlDest.fp) {
1400 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001401 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001402 } else {
1403 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001404 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001405 }
buzbee2cfc6392012-05-07 14:51:40 -07001406 break;
buzbee101305f2012-06-28 18:00:56 -07001407 case Instruction::IGET_OBJECT:
1408 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001409 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001410 break;
1411 case Instruction::IGET_BOOLEAN:
1412 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001413 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001414 break;
1415 case Instruction::IGET_BYTE:
1416 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001417 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001418 break;
1419 case Instruction::IGET_CHAR:
1420 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001421 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001422 break;
1423 case Instruction::IGET_SHORT:
1424 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001425 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001426 break;
1427 case Instruction::IGET_WIDE:
1428 if (rlDest.fp) {
1429 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001430 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001431 } else {
1432 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001433 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001434 }
1435 break;
1436 case Instruction::IPUT:
1437 if (rlDest.fp) {
1438 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1439 rlSrc[0], rlSrc[1], vC);
1440 } else {
1441 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1442 rlSrc[0], rlSrc[1], vC);
1443 }
1444 break;
1445 case Instruction::IPUT_OBJECT:
1446 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1447 rlSrc[0], rlSrc[1], vC);
1448 break;
1449 case Instruction::IPUT_BOOLEAN:
1450 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1451 rlSrc[0], rlSrc[1], vC);
1452 break;
1453 case Instruction::IPUT_BYTE:
1454 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1455 rlSrc[0], rlSrc[1], vC);
1456 break;
1457 case Instruction::IPUT_CHAR:
1458 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1459 rlSrc[0], rlSrc[1], vC);
1460 break;
1461 case Instruction::IPUT_SHORT:
1462 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1463 rlSrc[0], rlSrc[1], vC);
1464 break;
1465 case Instruction::IPUT_WIDE:
1466 if (rlDest.fp) {
1467 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1468 rlSrc[0], rlSrc[1], vC);
1469 } else {
1470 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1471 rlSrc[0], rlSrc[1], vC);
1472 }
buzbee2cfc6392012-05-07 14:51:40 -07001473 break;
1474
1475 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001476 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001477 break;
1478
buzbee76592632012-06-29 15:18:35 -07001479 case Instruction::LONG_TO_INT:
1480 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1481 break;
1482
buzbee101305f2012-06-28 18:00:56 -07001483 case Instruction::INT_TO_LONG:
1484 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001485 break;
1486
buzbee101305f2012-06-28 18:00:56 -07001487 case Instruction::INT_TO_CHAR:
1488 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1489 greenland::IntrinsicHelper::IntToChar);
1490 break;
1491 case Instruction::INT_TO_BYTE:
1492 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1493 greenland::IntrinsicHelper::IntToByte);
1494 break;
1495 case Instruction::INT_TO_SHORT:
1496 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1497 greenland::IntrinsicHelper::IntToShort);
1498 break;
1499
buzbee76592632012-06-29 15:18:35 -07001500 case Instruction::INT_TO_FLOAT:
1501 case Instruction::LONG_TO_FLOAT:
1502 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001503 break;
1504
buzbee76592632012-06-29 15:18:35 -07001505 case Instruction::INT_TO_DOUBLE:
1506 case Instruction::LONG_TO_DOUBLE:
1507 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001508 break;
1509
buzbee76592632012-06-29 15:18:35 -07001510 case Instruction::FLOAT_TO_DOUBLE:
1511 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001512 break;
1513
buzbee76592632012-06-29 15:18:35 -07001514 case Instruction::DOUBLE_TO_FLOAT:
1515 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001516 break;
1517
1518 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001519 case Instruction::NEG_INT:
1520 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001521 break;
1522
1523 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001524 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001525 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001526 break;
1527
buzbee76592632012-06-29 15:18:35 -07001528 case Instruction::NOT_LONG:
1529 case Instruction::NOT_INT:
1530 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001531 break;
1532
buzbee2cfc6392012-05-07 14:51:40 -07001533 case Instruction::FLOAT_TO_INT:
buzbee2cfc6392012-05-07 14:51:40 -07001534 case Instruction::DOUBLE_TO_INT:
buzbee76592632012-06-29 15:18:35 -07001535 convertFPToInt(cUnit, cUnit->irb->getInt32Ty(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001536 break;
1537
buzbee76592632012-06-29 15:18:35 -07001538 case Instruction::FLOAT_TO_LONG:
1539 case Instruction::DOUBLE_TO_LONG:
1540 convertFPToInt(cUnit, cUnit->irb->getInt64Ty(), rlDest, rlSrc[0]);
1541 break;
1542
1543 case Instruction::CMPL_FLOAT:
1544 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1545 rlDest, rlSrc[0], rlSrc[1]);
1546 break;
1547 case Instruction::CMPG_FLOAT:
1548 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1549 rlDest, rlSrc[0], rlSrc[1]);
1550 break;
1551 case Instruction::CMPL_DOUBLE:
1552 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1553 rlDest, rlSrc[0], rlSrc[1]);
1554 break;
1555 case Instruction::CMPG_DOUBLE:
1556 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1557 rlDest, rlSrc[0], rlSrc[1]);
1558 break;
1559 case Instruction::CMP_LONG:
1560 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1561 rlDest, rlSrc[0], rlSrc[1]);
1562 break;
1563
buzbee76592632012-06-29 15:18:35 -07001564 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001565 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001566 break;
1567
1568 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001569 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001570 break;
buzbee2cfc6392012-05-07 14:51:40 -07001571
1572 default:
buzbee32412962012-06-26 16:27:56 -07001573 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001574 res = true;
1575 }
buzbeeb03f4872012-06-11 15:22:11 -07001576 if (objectDefinition) {
1577 setShadowFrameEntry(cUnit, (llvm::Value*)
1578 cUnit->llvmValues.elemList[rlDest.origSReg]);
1579 }
buzbee2cfc6392012-05-07 14:51:40 -07001580 return res;
1581}
1582
1583/* Extended MIR instructions like PHI */
1584void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1585 llvm::BasicBlock* llvmBB)
1586{
1587
1588 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1589 case kMirOpPhi: {
1590 int* incoming = (int*)mir->dalvikInsn.vB;
1591 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
1592 llvm::Type* phiType =
1593 llvmTypeFromLocRec(cUnit, rlDest);
1594 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1595 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1596 RegLocation loc;
1597 if (rlDest.wide) {
buzbee15bf9802012-06-12 17:49:27 -07001598 loc = oatGetSrcWide(cUnit, mir, i);
buzbee2cfc6392012-05-07 14:51:40 -07001599 i++;
1600 } else {
1601 loc = oatGetSrc(cUnit, mir, i);
1602 }
1603 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
1604 getLLVMBlock(cUnit, incoming[i]));
1605 }
1606 defineValue(cUnit, phi, rlDest.origSReg);
1607 break;
1608 }
1609 case kMirOpCopy: {
1610 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1611 break;
1612 }
1613#if defined(TARGET_ARM)
1614 case kMirOpFusedCmplFloat:
1615 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1616 break;
1617 case kMirOpFusedCmpgFloat:
1618 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1619 break;
1620 case kMirOpFusedCmplDouble:
1621 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1622 break;
1623 case kMirOpFusedCmpgDouble:
1624 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1625 break;
1626 case kMirOpFusedCmpLong:
1627 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1628 break;
1629#endif
1630 default:
1631 break;
1632 }
1633}
1634
1635void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1636{
1637 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001638 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001639 arrayRef.push_back(cUnit->irb->getInt32(offset));
1640 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1641 cUnit->irb->SetDexOffset(node);
1642}
1643
1644// Attach method info as metadata to special intrinsic
1645void setMethodInfo(CompilationUnit* cUnit)
1646{
1647 // We don't want dex offset on this
1648 cUnit->irb->SetDexOffset(NULL);
1649 greenland::IntrinsicHelper::IntrinsicId id;
1650 id = greenland::IntrinsicHelper::MethodInfo;
1651 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1652 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1653 llvm::SmallVector<llvm::Value*, 2> regInfo;
1654 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1655 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1656 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1657 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1658 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1659 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1660 inst->setMetadata("RegInfo", regInfoNode);
1661 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1662 llvm::SmallVector<llvm::Value*, 50> pmap;
1663 for (int i = 0; i < promoSize; i++) {
1664 PromotionMap* p = &cUnit->promotionMap[i];
1665 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1666 ((p->fpReg & 0xff) << 16) |
1667 ((p->coreReg & 0xff) << 8) |
1668 ((p->fpLocation & 0xf) << 4) |
1669 (p->coreLocation & 0xf);
1670 pmap.push_back(cUnit->irb->getInt32(mapData));
1671 }
1672 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1673 inst->setMetadata("PromotionMap", mapNode);
1674 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1675}
1676
1677/* Handle the content in each basic block */
1678bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1679{
1680 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
1681 cUnit->irb->SetInsertPoint(llvmBB);
1682 setDexOffset(cUnit, bb->startOffset);
1683
1684 if (bb->blockType == kEntryBlock) {
1685 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001686 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1687 cUnit->numDalvikRegisters, true,
1688 kAllocMisc);
1689 for (int i = 0; i < cUnit->numSSARegs; i++) {
1690 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1691 }
1692 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1693 if (canBeRef[i]) {
1694 cUnit->numShadowFrameEntries++;
1695 }
1696 }
1697 if (cUnit->numShadowFrameEntries > 0) {
1698 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1699 cUnit->numShadowFrameEntries, true,
1700 kAllocMisc);
1701 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1702 if (canBeRef[i]) {
1703 cUnit->shadowMap[j++] = i;
1704 }
1705 }
1706 greenland::IntrinsicHelper::IntrinsicId id =
1707 greenland::IntrinsicHelper::AllocaShadowFrame;
1708 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1709 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1710 cUnit->irb->CreateCall(func, entries);
1711 }
buzbee2cfc6392012-05-07 14:51:40 -07001712 } else if (bb->blockType == kExitBlock) {
1713 /*
1714 * Because of the differences between how MIR/LIR and llvm handle exit
1715 * blocks, we won't explicitly covert them. On the llvm-to-lir
1716 * path, it will need to be regenereated.
1717 */
1718 return false;
buzbee6969d502012-06-15 16:40:31 -07001719 } else if (bb->blockType == kExceptionHandling) {
1720 /*
1721 * Because we're deferring null checking, delete the associated empty
1722 * exception block.
1723 * TODO: add new block type for exception blocks that we generate
1724 * greenland code for.
1725 */
1726 llvmBB->eraseFromParent();
1727 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001728 }
1729
1730 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1731
1732 setDexOffset(cUnit, mir->offset);
1733
1734 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
1735 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
1736
1737 /* If we're compiling for the debugger, generate an update callout */
1738 if (cUnit->genDebugger) {
1739 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1740 //genDebuggerUpdate(cUnit, mir->offset);
1741 }
1742
1743 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
1744 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1745 continue;
1746 }
1747
1748 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1749 NULL /* labelList */);
1750 if (notHandled) {
1751 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
1752 mir->offset, dalvikOpcode,
1753 Instruction::Name(dalvikOpcode),
1754 dalvikFormat);
1755 }
1756 }
1757
buzbee6969d502012-06-15 16:40:31 -07001758 if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001759 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1760 }
1761
1762 return false;
1763}
1764
buzbee4f4dfc72012-07-02 14:54:44 -07001765char remapShorty(char shortyType) {
1766 /*
1767 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1768 * and longs/doubles are represented as a pair of registers. When sub-word
1769 * arguments (and method results) are passed, they are extended to Dalvik
1770 * virtual register containers. Because llvm is picky about type consistency,
1771 * we must either cast the "real" type to 32-bit container multiple Dalvik
1772 * register types, or always use the expanded values.
1773 * Here, we're doing the latter. We map the shorty signature to container
1774 * types (which is valid so long as we always do a real expansion of passed
1775 * arguments and field loads).
1776 */
1777 switch(shortyType) {
1778 case 'Z' : shortyType = 'I'; break;
1779 case 'B' : shortyType = 'I'; break;
1780 case 'S' : shortyType = 'I'; break;
1781 case 'C' : shortyType = 'I'; break;
1782 default: break;
1783 }
1784 return shortyType;
1785}
1786
buzbee2cfc6392012-05-07 14:51:40 -07001787llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1788
1789 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001790 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001791 greenland::kAccurate);
1792
1793 // Get argument type
1794 std::vector<llvm::Type*> args_type;
1795
1796 // method object
1797 args_type.push_back(cUnit->irb->GetJMethodTy());
1798
1799 // Do we have a "this"?
1800 if ((cUnit->access_flags & kAccStatic) == 0) {
1801 args_type.push_back(cUnit->irb->GetJObjectTy());
1802 }
1803
1804 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001805 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001806 greenland::kAccurate));
1807 }
1808
1809 return llvm::FunctionType::get(ret_type, args_type, false);
1810}
1811
1812bool createFunction(CompilationUnit* cUnit) {
1813 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1814 /* with_signature */ false));
1815 llvm::FunctionType* func_type = getFunctionType(cUnit);
1816
1817 if (func_type == NULL) {
1818 return false;
1819 }
1820
1821 cUnit->func = llvm::Function::Create(func_type,
1822 llvm::Function::ExternalLinkage,
1823 func_name, cUnit->module);
1824
1825 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1826 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1827
1828 arg_iter->setName("method");
1829 ++arg_iter;
1830
1831 int startSReg = cUnit->numRegs;
1832
1833 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1834 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1835 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1836 }
1837
1838 return true;
1839}
1840
1841bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1842{
1843 // Skip the exit block
1844 if (bb->blockType == kExitBlock) {
1845 cUnit->idToBlockMap.Put(bb->id, NULL);
1846 } else {
1847 int offset = bb->startOffset;
1848 bool entryBlock = (bb->blockType == kEntryBlock);
1849 llvm::BasicBlock* llvmBB =
1850 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
Elliott Hughes74847412012-06-20 18:10:21 -07001851 StringPrintf(kLabelFormat, offset, bb->id),
buzbee2cfc6392012-05-07 14:51:40 -07001852 cUnit->func);
1853 if (entryBlock) {
1854 cUnit->entryBB = llvmBB;
1855 cUnit->placeholderBB =
1856 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
1857 cUnit->func);
1858 }
1859 cUnit->idToBlockMap.Put(bb->id, llvmBB);
1860 }
1861 return false;
1862}
1863
1864
1865/*
1866 * Convert MIR to LLVM_IR
1867 * o For each ssa name, create LLVM named value. Type these
1868 * appropriately, and ignore high half of wide and double operands.
1869 * o For each MIR basic block, create an LLVM basic block.
1870 * o Iterate through the MIR a basic block at a time, setting arguments
1871 * to recovered ssa name.
1872 */
1873void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
1874{
1875 initIR(cUnit);
1876 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
1877
1878 // Create the function
1879 createFunction(cUnit);
1880
1881 // Create an LLVM basic block for each MIR block in dfs preorder
1882 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
1883 kPreOrderDFSTraversal, false /* isIterative */);
1884 /*
1885 * Create an llvm named value for each MIR SSA name. Note: we'll use
1886 * placeholders for all non-argument values (because we haven't seen
1887 * the definition yet).
1888 */
1889 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
1890 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1891 arg_iter++; /* Skip path method */
1892 for (int i = 0; i < cUnit->numSSARegs; i++) {
1893 llvm::Value* val;
1894 llvm::Type* ty = llvmTypeFromLocRec(cUnit, cUnit->regLocation[i]);
1895 if (i < cUnit->numRegs) {
1896 // Skip non-argument _0 names - should never be a use
1897 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)0);
1898 } else if (i >= (cUnit->numRegs + cUnit->numIns)) {
1899 // Handle SSA defs, skipping Method* and compiler temps
1900 if (SRegToVReg(cUnit, i) < 0) {
1901 val = NULL;
1902 } else {
1903 val = cUnit->irb->CreateLoad(cUnit->irb->CreateAlloca(ty, 0));
1904 val->setName(llvmSSAName(cUnit, i));
1905 }
1906 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
1907 if (cUnit->regLocation[i].wide) {
1908 // Skip high half of wide values
1909 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
1910 i++;
1911 }
1912 } else {
1913 // Recover previously-created argument values
1914 llvm::Value* argVal = arg_iter++;
1915 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
buzbee4f4dfc72012-07-02 14:54:44 -07001916 if (cUnit->regLocation[i].wide) {
1917 // Skip high half of wide values.
1918 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
1919 i++;
1920 }
buzbee2cfc6392012-05-07 14:51:40 -07001921 }
1922 }
1923 cUnit->irb->CreateBr(cUnit->placeholderBB);
1924
1925 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
1926 kPreOrderDFSTraversal, false /* Iterative */);
1927
1928 cUnit->placeholderBB->eraseFromParent();
1929
1930 llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction);
1931
buzbeead8f15e2012-06-18 14:49:45 -07001932 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
1933 // Write bitcode to file
1934 std::string errmsg;
1935 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
1936 oatReplaceSpecialChars(fname);
1937 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07001938 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07001939
buzbeead8f15e2012-06-18 14:49:45 -07001940 llvm::OwningPtr<llvm::tool_output_file> out_file(
1941 new llvm::tool_output_file(fname.c_str(), errmsg,
1942 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07001943
buzbeead8f15e2012-06-18 14:49:45 -07001944 if (!errmsg.empty()) {
1945 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
1946 }
1947
1948 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
1949 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07001950 }
buzbee2cfc6392012-05-07 14:51:40 -07001951}
1952
1953RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
1954 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07001955 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07001956 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
1957 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07001958 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07001959 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07001960 // FIXME: need to be more robust, handle FP and be in a position to
1961 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07001962 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
1963 memset(&res, 0, sizeof(res));
1964 res.location = kLocPhysReg;
1965 res.lowReg = oatAllocTemp(cUnit);
1966 res.home = true;
1967 res.sRegLow = INVALID_SREG;
1968 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07001969 llvm::Type* ty = val->getType();
1970 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
1971 (ty == cUnit->irb->getDoubleTy()));
1972 if (res.wide) {
1973 res.highReg = oatAllocTemp(cUnit);
1974 }
buzbee4f1181f2012-06-22 13:52:12 -07001975 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07001976 } else {
1977 DCHECK_EQ(valName[0], 'v');
1978 int baseSReg = INVALID_SREG;
1979 sscanf(valName.c_str(), "v%d_", &baseSReg);
1980 res = cUnit->regLocation[baseSReg];
1981 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07001982 }
1983 } else {
1984 res = it->second;
1985 }
1986 return res;
1987}
1988
1989Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
1990{
1991 Instruction::Code res = Instruction::NOP;
1992 if (isWide) {
1993 switch(op) {
1994 case kOpAdd: res = Instruction::ADD_LONG; break;
1995 case kOpSub: res = Instruction::SUB_LONG; break;
1996 case kOpMul: res = Instruction::MUL_LONG; break;
1997 case kOpDiv: res = Instruction::DIV_LONG; break;
1998 case kOpRem: res = Instruction::REM_LONG; break;
1999 case kOpAnd: res = Instruction::AND_LONG; break;
2000 case kOpOr: res = Instruction::OR_LONG; break;
2001 case kOpXor: res = Instruction::XOR_LONG; break;
2002 case kOpLsl: res = Instruction::SHL_LONG; break;
2003 case kOpLsr: res = Instruction::USHR_LONG; break;
2004 case kOpAsr: res = Instruction::SHR_LONG; break;
2005 default: LOG(FATAL) << "Unexpected OpKind " << op;
2006 }
2007 } else if (isConst){
2008 switch(op) {
2009 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2010 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2011 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2012 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2013 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2014 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2015 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2016 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2017 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2018 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2019 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2020 default: LOG(FATAL) << "Unexpected OpKind " << op;
2021 }
2022 } else {
2023 switch(op) {
2024 case kOpAdd: res = Instruction::ADD_INT; break;
2025 case kOpSub: res = Instruction::SUB_INT; break;
2026 case kOpMul: res = Instruction::MUL_INT; break;
2027 case kOpDiv: res = Instruction::DIV_INT; break;
2028 case kOpRem: res = Instruction::REM_INT; break;
2029 case kOpAnd: res = Instruction::AND_INT; break;
2030 case kOpOr: res = Instruction::OR_INT; break;
2031 case kOpXor: res = Instruction::XOR_INT; break;
2032 case kOpLsl: res = Instruction::SHL_INT; break;
2033 case kOpLsr: res = Instruction::USHR_INT; break;
2034 case kOpAsr: res = Instruction::SHR_INT; break;
2035 default: LOG(FATAL) << "Unexpected OpKind " << op;
2036 }
2037 }
2038 return res;
2039}
2040
buzbee4f1181f2012-06-22 13:52:12 -07002041Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2042{
2043 Instruction::Code res = Instruction::NOP;
2044 if (isWide) {
2045 switch(op) {
2046 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2047 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2048 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2049 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2050 case kOpRem: res = Instruction::REM_DOUBLE; break;
2051 default: LOG(FATAL) << "Unexpected OpKind " << op;
2052 }
2053 } else {
2054 switch(op) {
2055 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2056 case kOpSub: res = Instruction::SUB_FLOAT; break;
2057 case kOpMul: res = Instruction::MUL_FLOAT; break;
2058 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2059 case kOpRem: res = Instruction::REM_FLOAT; break;
2060 default: LOG(FATAL) << "Unexpected OpKind " << op;
2061 }
2062 }
2063 return res;
2064}
2065
2066void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2067{
2068 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002069 /*
2070 * Normally, we won't ever generate an FP operation with an immediate
2071 * operand (not supported in Dex instruction set). However, the IR builder
2072 * may insert them - in particular for createNegFP. Recognize this case
2073 * and deal with it.
2074 */
2075 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2076 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2077 DCHECK(op2C == NULL);
2078 if ((op1C != NULL) && (op == kOpSub)) {
2079 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2080 if (rlDest.wide) {
2081 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2082 } else {
2083 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2084 }
buzbee4f1181f2012-06-22 13:52:12 -07002085 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002086 DCHECK(op1C == NULL);
2087 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2088 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2089 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2090 if (rlDest.wide) {
2091 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2092 } else {
2093 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2094 }
buzbee4f1181f2012-06-22 13:52:12 -07002095 }
2096}
2097
buzbee101305f2012-06-28 18:00:56 -07002098void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2099 Instruction::Code opcode)
2100{
2101 RegLocation rlDest = getLoc(cUnit, inst);
2102 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2103 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2104}
2105
buzbee76592632012-06-29 15:18:35 -07002106void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2107{
2108 RegLocation rlDest = getLoc(cUnit, inst);
2109 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2110 Instruction::Code opcode;
2111 if (rlDest.wide) {
2112 if (rlSrc.wide) {
2113 opcode = Instruction::LONG_TO_DOUBLE;
2114 } else {
2115 opcode = Instruction::INT_TO_DOUBLE;
2116 }
2117 } else {
2118 if (rlSrc.wide) {
2119 opcode = Instruction::LONG_TO_FLOAT;
2120 } else {
2121 opcode = Instruction::INT_TO_FLOAT;
2122 }
2123 }
2124 genConversion(cUnit, opcode, rlDest, rlSrc);
2125}
2126
2127void cvtFPToInt(CompilationUnit* cUnit, llvm::Instruction* inst)
2128{
2129 RegLocation rlDest = getLoc(cUnit, inst);
2130 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2131 Instruction::Code opcode;
2132 if (rlDest.wide) {
2133 if (rlSrc.wide) {
2134 opcode = Instruction::DOUBLE_TO_LONG;
2135 } else {
2136 opcode = Instruction::FLOAT_TO_LONG;
2137 }
2138 } else {
2139 if (rlSrc.wide) {
2140 opcode = Instruction::DOUBLE_TO_INT;
2141 } else {
2142 opcode = Instruction::FLOAT_TO_INT;
2143 }
2144 }
2145 genConversion(cUnit, opcode, rlDest, rlSrc);
2146}
2147
2148void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2149{
2150 RegLocation rlDest = getLoc(cUnit, inst);
2151 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2152 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2153}
2154
2155void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2156{
2157 RegLocation rlDest = getLoc(cUnit, inst);
2158 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2159 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2160 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2161 storeValue(cUnit, rlDest, rlSrc);
2162}
2163
2164void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2165{
2166 RegLocation rlDest = getLoc(cUnit, inst);
2167 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2168 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2169}
2170
2171
buzbee101305f2012-06-28 18:00:56 -07002172void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2173{
2174 // TODO: evaluate src/tgt types and add general support for more than int to long
2175 RegLocation rlDest = getLoc(cUnit, inst);
2176 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2177 DCHECK(rlDest.wide);
2178 DCHECK(!rlSrc.wide);
2179 DCHECK(!rlDest.fp);
2180 DCHECK(!rlSrc.fp);
2181 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2182 if (rlSrc.location == kLocPhysReg) {
2183 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2184 } else {
2185 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2186 }
2187 if (isSigned) {
2188 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2189 } else {
2190 loadConstant(cUnit, rlResult.highReg, 0);
2191 }
2192 storeValueWide(cUnit, rlDest, rlResult);
2193}
2194
buzbee2cfc6392012-05-07 14:51:40 -07002195void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2196{
2197 RegLocation rlDest = getLoc(cUnit, inst);
2198 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002199 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002200 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2201 if ((op == kOpSub) && (lhsImm != NULL)) {
2202 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002203 if (rlSrc1.wide) {
2204 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2205 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2206 } else {
2207 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2208 lhsImm->getSExtValue());
2209 }
buzbee4f1181f2012-06-22 13:52:12 -07002210 return;
2211 }
2212 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002213 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2214 llvm::Value* rhs = inst->getOperand(1);
2215 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2216 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
2217 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, src2->getSExtValue());
2218 } else {
2219 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
2220 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2221 if (rlDest.wide) {
2222 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2223 } else {
2224 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2225 }
2226 }
2227}
2228
buzbee101305f2012-06-28 18:00:56 -07002229void cvtShiftOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2230{
2231 if (inst->getType() == cUnit->irb->getInt64Ty()) {
2232 /*
2233 * llvm wants the shift amount to be 64 bits, whereas we've constained
2234 * it to be in 6 bits. It should always be held as an unnamed temp
2235 * at this point that was the result of a previous UExt. We'll backtrack
2236 * to find the pre-extension value and use that.
2237 * TODO: probably better to handle this in cvtIntExt() or just intrinsify
2238 */
2239 RegLocation rlDest = getLoc(cUnit, inst);
2240 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2241 RegLocation rlShift = getLoc(cUnit, inst->getOperand(1));
2242 DCHECK(rlShift.wide);
2243 DCHECK_EQ(rlShift.sRegLow, INVALID_SREG);
2244 // Now, free the temp registers - we won't need them.
2245 // TODO: kill the dead extend ops
2246 oatFreeTemp(cUnit, rlShift.lowReg);
2247 oatFreeTemp(cUnit, rlShift.highReg);
2248 // Get the pre-extend operand
2249 llvm::Instruction* extInst =
2250 llvm::dyn_cast<llvm::Instruction>(inst->getOperand(1));
2251 DCHECK(extInst != NULL);
2252 rlShift = getLoc(cUnit, extInst->getOperand(0));
2253 DCHECK(!rlShift.wide);
2254 Instruction::Code opcode;
2255 if (op == kOpLsl)
2256 opcode = Instruction::SHL_LONG;
2257 else if (op == kOpAsr)
2258 opcode = Instruction::SHR_LONG;
2259 else {
2260 DCHECK_EQ(op, kOpLsr);
2261 opcode = Instruction::USHR_LONG;
2262 }
2263 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2264 } else {
2265 cvtBinOp(cUnit, op, inst);
2266 }
2267}
2268
buzbee2cfc6392012-05-07 14:51:40 -07002269void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2270{
2271 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2272 DCHECK(brInst != NULL);
2273 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2274 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2275 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2276}
2277
2278void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2279{
2280 // Nop - these have already been processed
2281}
2282
2283void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2284{
2285 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2286 llvm::Value* retVal = retInst->getReturnValue();
2287 if (retVal != NULL) {
2288 RegLocation rlSrc = getLoc(cUnit, retVal);
2289 if (rlSrc.wide) {
2290 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2291 } else {
2292 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2293 }
2294 }
2295 genExitSequence(cUnit);
2296}
2297
2298ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2299{
2300 ConditionCode res = kCondAl;
2301 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002302 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002303 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2304 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2305 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002306 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002307 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002308 default: LOG(FATAL) << "Unexpected llvm condition";
2309 }
2310 return res;
2311}
2312
2313void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2314{
2315 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2316 UNIMPLEMENTED(FATAL);
2317}
2318
2319void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2320 llvm::BranchInst* brInst)
2321{
2322 // Get targets
2323 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2324 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2325 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2326 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2327 // Get comparison operands
2328 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2329 ConditionCode cond = getCond(iCmpInst->getPredicate());
2330 llvm::Value* lhs = iCmpInst->getOperand(0);
2331 // Not expecting a constant as 1st operand
2332 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2333 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2334 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2335 llvm::Value* rhs = inst->getOperand(1);
2336#if defined(TARGET_MIPS)
2337 // Compare and branch in one shot
2338 (void)taken;
2339 (void)cond;
2340 (void)rhs;
2341 UNIMPLEMENTED(FATAL);
2342#else
2343 //Compare, then branch
2344 // TODO: handle fused CMP_LONG/IF_xxZ case
2345 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2346 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
2347 } else {
2348 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2349 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2350 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2351 }
2352 opCondBranch(cUnit, cond, taken);
2353#endif
2354 // Fallthrough
2355 opUnconditionalBranch(cUnit, fallThrough);
2356}
2357
2358void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2359 llvm::Function* callee)
2360{
2361 UNIMPLEMENTED(FATAL);
2362}
2363
buzbee2cfc6392012-05-07 14:51:40 -07002364void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2365{
buzbee4f1181f2012-06-22 13:52:12 -07002366 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002367 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2368 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002369 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2370 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002371 if (rlSrc.wide) {
2372 storeValueWide(cUnit, rlDest, rlSrc);
2373 } else {
2374 storeValue(cUnit, rlDest, rlSrc);
2375 }
2376}
2377
2378// Note: Immediate arg is a ConstantInt regardless of result type
2379void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2380{
buzbee4f1181f2012-06-22 13:52:12 -07002381 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002382 llvm::ConstantInt* src =
2383 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2384 uint64_t immval = src->getZExtValue();
2385 RegLocation rlDest = getLoc(cUnit, callInst);
2386 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2387 if (rlDest.wide) {
2388 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2389 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2390 storeValueWide(cUnit, rlDest, rlResult);
2391 } else {
2392 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2393 storeValue(cUnit, rlDest, rlResult);
2394 }
2395}
2396
buzbee101305f2012-06-28 18:00:56 -07002397void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2398 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002399{
buzbee4f1181f2012-06-22 13:52:12 -07002400 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002401 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002402 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002403 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002404 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002405 if (isString) {
2406 genConstString(cUnit, index, rlDest);
2407 } else {
2408 genConstClass(cUnit, index, rlDest);
2409 }
2410}
2411
2412void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2413{
2414 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2415 llvm::ConstantInt* offsetVal =
2416 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2417 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2418 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002419}
2420
buzbee4f1181f2012-06-22 13:52:12 -07002421void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2422{
buzbee32412962012-06-26 16:27:56 -07002423 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002424 llvm::ConstantInt* typeIdxVal =
2425 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2426 uint32_t typeIdx = typeIdxVal->getZExtValue();
2427 RegLocation rlDest = getLoc(cUnit, callInst);
2428 genNewInstance(cUnit, typeIdx, rlDest);
2429}
2430
buzbee8fa0fda2012-06-27 15:44:52 -07002431void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2432{
2433 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2434 llvm::ConstantInt* typeIdxVal =
2435 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2436 uint32_t typeIdx = typeIdxVal->getZExtValue();
2437 llvm::Value* len = callInst->getArgOperand(1);
2438 RegLocation rlLen = getLoc(cUnit, len);
2439 RegLocation rlDest = getLoc(cUnit, callInst);
2440 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2441}
2442
2443void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2444{
2445 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2446 llvm::ConstantInt* typeIdxVal =
2447 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2448 uint32_t typeIdx = typeIdxVal->getZExtValue();
2449 llvm::Value* src = callInst->getArgOperand(1);
2450 RegLocation rlSrc = getLoc(cUnit, src);
2451 RegLocation rlDest = getLoc(cUnit, callInst);
2452 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2453}
2454
buzbee32412962012-06-26 16:27:56 -07002455void cvtThrowVerificationError(CompilationUnit* cUnit, llvm::CallInst* callInst)
2456{
2457 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2458 llvm::ConstantInt* info1 =
2459 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2460 llvm::ConstantInt* info2 =
2461 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2462 genThrowVerificationError(cUnit, info1->getZExtValue(), info2->getZExtValue());
2463}
2464
2465void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2466{
2467 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2468 llvm::Value* src = callInst->getArgOperand(0);
2469 RegLocation rlSrc = getLoc(cUnit, src);
2470 genThrow(cUnit, rlSrc);
2471}
2472
buzbee8fa0fda2012-06-27 15:44:52 -07002473void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2474 llvm::CallInst* callInst)
2475{
2476 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2477 llvm::ConstantInt* optFlags =
2478 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2479 llvm::Value* src = callInst->getArgOperand(1);
2480 RegLocation rlSrc = getLoc(cUnit, src);
2481 if (isEnter) {
2482 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2483 } else {
2484 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2485 }
2486}
2487
buzbee76592632012-06-29 15:18:35 -07002488void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002489{
2490 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2491 llvm::ConstantInt* optFlags =
2492 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2493 llvm::Value* src = callInst->getArgOperand(1);
2494 RegLocation rlSrc = getLoc(cUnit, src);
2495 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2496 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2497 RegLocation rlDest = getLoc(cUnit, callInst);
2498 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2499 int lenOffset = Array::LengthOffset().Int32Value();
2500 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2501 storeValue(cUnit, rlDest, rlResult);
2502}
2503
buzbee32412962012-06-26 16:27:56 -07002504void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2505{
2506 DCHECK_EQ(callInst->getNumArgOperands(), 0U);
2507 int exOffset = Thread::ExceptionOffset().Int32Value();
2508 RegLocation rlDest = getLoc(cUnit, callInst);
2509 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2510#if defined(TARGET_X86)
2511 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
2512 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
2513#else
2514 int resetReg = oatAllocTemp(cUnit);
2515 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
2516 loadConstant(cUnit, resetReg, 0);
2517 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
2518 oatFreeTemp(cUnit, resetReg);
2519#endif
2520 storeValue(cUnit, rlDest, rlResult);
2521}
2522
buzbee4f1181f2012-06-22 13:52:12 -07002523void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2524 bool isObject)
2525{
buzbee32412962012-06-26 16:27:56 -07002526 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002527 llvm::ConstantInt* typeIdxVal =
2528 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2529 uint32_t typeIdx = typeIdxVal->getZExtValue();
2530 RegLocation rlDest = getLoc(cUnit, callInst);
2531 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2532}
2533
buzbee8fa0fda2012-06-27 15:44:52 -07002534void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2535 bool isObject)
2536{
2537 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2538 llvm::ConstantInt* typeIdxVal =
2539 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2540 uint32_t typeIdx = typeIdxVal->getZExtValue();
2541 llvm::Value* src = callInst->getArgOperand(1);
2542 RegLocation rlSrc = getLoc(cUnit, src);
2543 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2544}
2545
2546void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2547 int scale)
2548{
2549 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2550 llvm::ConstantInt* optFlags =
2551 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2552 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2553 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2554 RegLocation rlDest = getLoc(cUnit, callInst);
2555 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2556 rlDest, scale);
2557}
2558
2559void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2560 int scale)
2561{
2562 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2563 llvm::ConstantInt* optFlags =
2564 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2565 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2566 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2567 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
2568 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2569 rlSrc, scale);
2570}
2571
buzbee101305f2012-06-28 18:00:56 -07002572void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2573 bool isWide, bool isObj)
2574{
2575 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2576 llvm::ConstantInt* optFlags =
2577 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2578 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2579 llvm::ConstantInt* fieldIdx =
2580 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2581 RegLocation rlDest = getLoc(cUnit, callInst);
2582 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2583 size, rlDest, rlObj, isWide, isObj);
2584}
2585
2586void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2587 bool isWide, bool isObj)
2588{
2589 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2590 llvm::ConstantInt* optFlags =
2591 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2592 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2593 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2594 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002595 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002596 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2597 size, rlSrc, rlObj, isWide, isObj);
2598}
2599
2600void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2601{
2602 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2603 llvm::ConstantInt* typeIdx =
2604 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2605 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2606 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2607}
2608
buzbee76592632012-06-29 15:18:35 -07002609void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2610 Instruction::Code opcode)
2611{
2612 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2613 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2614 RegLocation rlDest = getLoc(cUnit, callInst);
2615 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2616}
2617
2618void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2619{
2620 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2621 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2622 RegLocation rlDest = getLoc(cUnit, callInst);
2623 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2624}
2625
buzbeef58c12c2012-07-03 15:06:29 -07002626void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2627{
2628 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2629 DCHECK(swInst != NULL);
2630 llvm::Value* testVal = swInst->getCondition();
2631 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2632 DCHECK(tableOffsetNode != NULL);
2633 llvm::ConstantInt* tableOffsetValue =
2634 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2635 int32_t tableOffset = tableOffsetValue->getSExtValue();
2636 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeea1da8a52012-07-09 14:00:21 -07002637 const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2638 u2 tableMagic = *table;
2639 if (tableMagic == 0x100) {
2640 genPackedSwitch(cUnit, tableOffset, rlSrc);
2641 } else {
2642 DCHECK_EQ(tableMagic, 0x200);
2643 genSparseSwitch(cUnit, tableOffset, rlSrc);
2644 }
buzbeef58c12c2012-07-03 15:06:29 -07002645}
2646
buzbee6969d502012-06-15 16:40:31 -07002647void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002648 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002649{
2650 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2651 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002652 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002653 info->result.location = kLocInvalid;
2654 } else {
2655 info->result = getLoc(cUnit, callInst);
2656 }
2657 llvm::ConstantInt* invokeTypeVal =
2658 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2659 llvm::ConstantInt* methodIndexVal =
2660 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2661 llvm::ConstantInt* optFlagsVal =
2662 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2663 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2664 info->index = methodIndexVal->getZExtValue();
2665 info->optFlags = optFlagsVal->getZExtValue();
2666 info->offset = cUnit->currentDalvikOffset;
2667
buzbee6969d502012-06-15 16:40:31 -07002668 // Count the argument words, and then build argument array.
2669 info->numArgWords = 0;
2670 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2671 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2672 info->numArgWords += tLoc.wide ? 2 : 1;
2673 }
2674 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2675 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2676 // Now, fill in the location records, synthesizing high loc of wide vals
2677 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002678 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002679 if (info->args[next].wide) {
2680 next++;
2681 // TODO: Might make sense to mark this as an invalid loc
2682 info->args[next].origSReg = info->args[next-1].origSReg+1;
2683 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2684 }
2685 next++;
2686 }
buzbee4f4dfc72012-07-02 14:54:44 -07002687 // TODO - rework such that we no longer need isRange
2688 info->isRange = (info->numArgWords > 5);
2689
buzbee76592632012-06-29 15:18:35 -07002690 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002691 genFilledNewArray(cUnit, info);
2692 } else {
2693 genInvoke(cUnit, info);
2694 }
buzbee6969d502012-06-15 16:40:31 -07002695}
2696
buzbeead8f15e2012-06-18 14:49:45 -07002697/* Look up the RegLocation associated with a Value. Must already be defined */
2698RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2699{
2700 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2701 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2702 return it->second;
2703}
2704
buzbee2cfc6392012-05-07 14:51:40 -07002705bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2706{
2707 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2708 // Define the starting label
2709 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2710 // Extract the starting offset from the block's name
2711 if (!isEntry) {
2712 const char* blockName = bb->getName().str().c_str();
2713 int dummy;
Elliott Hughes74847412012-06-20 18:10:21 -07002714 sscanf(blockName, kLabelFormat, &blockLabel->operands[0], &dummy);
buzbee2cfc6392012-05-07 14:51:40 -07002715 }
2716 // Set the label kind
2717 blockLabel->opcode = kPseudoNormalBlockLabel;
2718 // Insert the label
2719 oatAppendLIR(cUnit, blockLabel);
2720
2721 // Free temp registers and reset redundant store tracking */
2722 oatResetRegPool(cUnit);
2723 oatResetDefTracking(cUnit);
2724
2725 //TODO: restore oat incoming liveness optimization
2726 oatClobberAllRegs(cUnit);
2727
buzbee6969d502012-06-15 16:40:31 -07002728 LIR* headLIR = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07002729
2730 if (isEntry) {
2731 cUnit->currentDalvikOffset = 0;
buzbeead8f15e2012-06-18 14:49:45 -07002732 RegLocation* argLocs = (RegLocation*)
2733 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2734 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2735 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2736 for (unsigned i = 0; it != it_end; ++it) {
2737 llvm::Value* val = it;
2738 argLocs[i++] = valToLoc(cUnit, val);
2739 llvm::Type* ty = val->getType();
2740 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2741 argLocs[i++].sRegLow = INVALID_SREG;
2742 }
2743 }
2744 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
buzbee2cfc6392012-05-07 14:51:40 -07002745 }
2746
2747 // Visit all of the instructions in the block
2748 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2749 llvm::Instruction* inst = it;
2750 llvm::BasicBlock::iterator nextIt = ++it;
2751 // Extract the Dalvik offset from the instruction
2752 uint32_t opcode = inst->getOpcode();
2753 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2754 if (dexOffsetNode != NULL) {
2755 llvm::ConstantInt* dexOffsetValue =
2756 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2757 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2758 }
2759
buzbee6969d502012-06-15 16:40:31 -07002760 oatResetRegPool(cUnit);
2761 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2762 oatClobberAllRegs(cUnit);
2763 }
2764
2765 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2766 oatResetDefTracking(cUnit);
2767 }
2768
2769#ifndef NDEBUG
2770 /* Reset temp tracking sanity check */
2771 cUnit->liveSReg = INVALID_SREG;
2772#endif
2773
2774 LIR* boundaryLIR;
2775 const char* instStr = "boundary";
2776 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
2777 (intptr_t) instStr);
2778 cUnit->boundaryMap.Overwrite(cUnit->currentDalvikOffset, boundaryLIR);
2779
2780 /* Remember the first LIR for thisl block*/
2781 if (headLIR == NULL) {
2782 headLIR = boundaryLIR;
2783 headLIR->defMask = ENCODE_ALL;
2784 }
2785
buzbee2cfc6392012-05-07 14:51:40 -07002786 switch(opcode) {
2787
2788 case llvm::Instruction::ICmp: {
2789 llvm::Instruction* nextInst = nextIt;
2790 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2791 if (brInst != NULL /* and... */) {
2792 cvtICmpBr(cUnit, inst, brInst);
2793 ++it;
2794 } else {
2795 cvtICmp(cUnit, inst);
2796 }
2797 }
2798 break;
2799
2800 case llvm::Instruction::Call: {
2801 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2802 llvm::Function* callee = callInst->getCalledFunction();
2803 greenland::IntrinsicHelper::IntrinsicId id =
2804 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2805 switch (id) {
buzbeeb03f4872012-06-11 15:22:11 -07002806 case greenland::IntrinsicHelper::AllocaShadowFrame:
2807 case greenland::IntrinsicHelper::SetShadowFrameEntry:
buzbee6969d502012-06-15 16:40:31 -07002808 case greenland::IntrinsicHelper::PopShadowFrame:
buzbeeb03f4872012-06-11 15:22:11 -07002809 // Ignore shadow frame stuff for quick compiler
2810 break;
buzbee2cfc6392012-05-07 14:51:40 -07002811 case greenland::IntrinsicHelper::CopyInt:
2812 case greenland::IntrinsicHelper::CopyObj:
2813 case greenland::IntrinsicHelper::CopyFloat:
2814 case greenland::IntrinsicHelper::CopyLong:
2815 case greenland::IntrinsicHelper::CopyDouble:
2816 cvtCopy(cUnit, callInst);
2817 break;
2818 case greenland::IntrinsicHelper::ConstInt:
2819 case greenland::IntrinsicHelper::ConstObj:
2820 case greenland::IntrinsicHelper::ConstLong:
2821 case greenland::IntrinsicHelper::ConstFloat:
2822 case greenland::IntrinsicHelper::ConstDouble:
2823 cvtConst(cUnit, callInst);
2824 break;
buzbee4f1181f2012-06-22 13:52:12 -07002825 case greenland::IntrinsicHelper::DivInt:
2826 case greenland::IntrinsicHelper::DivLong:
2827 cvtBinOp(cUnit, kOpDiv, inst);
2828 break;
2829 case greenland::IntrinsicHelper::RemInt:
2830 case greenland::IntrinsicHelper::RemLong:
2831 cvtBinOp(cUnit, kOpRem, inst);
2832 break;
buzbee2cfc6392012-05-07 14:51:40 -07002833 case greenland::IntrinsicHelper::MethodInfo:
buzbeead8f15e2012-06-18 14:49:45 -07002834 // Already dealt with - just ignore it here.
buzbee2cfc6392012-05-07 14:51:40 -07002835 break;
2836 case greenland::IntrinsicHelper::CheckSuspend:
2837 genSuspendTest(cUnit, 0 /* optFlags already applied */);
2838 break;
buzbee4f1181f2012-06-22 13:52:12 -07002839 case greenland::IntrinsicHelper::HLInvokeObj:
buzbee8fa0fda2012-06-27 15:44:52 -07002840 case greenland::IntrinsicHelper::HLInvokeFloat:
2841 case greenland::IntrinsicHelper::HLInvokeDouble:
2842 case greenland::IntrinsicHelper::HLInvokeLong:
2843 case greenland::IntrinsicHelper::HLInvokeInt:
buzbee101305f2012-06-28 18:00:56 -07002844 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
buzbee4f1181f2012-06-22 13:52:12 -07002845 break;
buzbee6969d502012-06-15 16:40:31 -07002846 case greenland::IntrinsicHelper::HLInvokeVoid:
buzbee101305f2012-06-28 18:00:56 -07002847 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
2848 break;
2849 case greenland::IntrinsicHelper::FilledNewArray:
2850 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
2851 break;
2852 case greenland::IntrinsicHelper::FillArrayData:
2853 cvtFillArrayData(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07002854 break;
2855 case greenland::IntrinsicHelper::ConstString:
buzbee101305f2012-06-28 18:00:56 -07002856 cvtConstObject(cUnit, callInst, true /* isString */);
2857 break;
2858 case greenland::IntrinsicHelper::ConstClass:
2859 cvtConstObject(cUnit, callInst, false /* isString */);
2860 break;
2861 case greenland::IntrinsicHelper::CheckCast:
2862 cvtCheckCast(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07002863 break;
buzbee4f1181f2012-06-22 13:52:12 -07002864 case greenland::IntrinsicHelper::NewInstance:
2865 cvtNewInstance(cUnit, callInst);
2866 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002867 case greenland::IntrinsicHelper::HLSgetObject:
buzbee4f1181f2012-06-22 13:52:12 -07002868 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
2869 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002870 case greenland::IntrinsicHelper::HLSget:
2871 case greenland::IntrinsicHelper::HLSgetFloat:
2872 case greenland::IntrinsicHelper::HLSgetBoolean:
2873 case greenland::IntrinsicHelper::HLSgetByte:
2874 case greenland::IntrinsicHelper::HLSgetChar:
2875 case greenland::IntrinsicHelper::HLSgetShort:
2876 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
2877 break;
2878 case greenland::IntrinsicHelper::HLSgetWide:
2879 case greenland::IntrinsicHelper::HLSgetDouble:
2880 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
2881 break;
buzbee76592632012-06-29 15:18:35 -07002882 case greenland::IntrinsicHelper::HLSput:
2883 case greenland::IntrinsicHelper::HLSputFloat:
2884 case greenland::IntrinsicHelper::HLSputBoolean:
2885 case greenland::IntrinsicHelper::HLSputByte:
2886 case greenland::IntrinsicHelper::HLSputChar:
2887 case greenland::IntrinsicHelper::HLSputShort:
2888 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
2889 break;
2890 case greenland::IntrinsicHelper::HLSputWide:
2891 case greenland::IntrinsicHelper::HLSputDouble:
2892 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
2893 break;
buzbeea1da8a52012-07-09 14:00:21 -07002894 case greenland::IntrinsicHelper::HLSputObject:
2895 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
2896 break;
buzbee32412962012-06-26 16:27:56 -07002897 case greenland::IntrinsicHelper::GetException:
2898 cvtMoveException(cUnit, callInst);
2899 break;
2900 case greenland::IntrinsicHelper::Throw:
2901 cvtThrow(cUnit, callInst);
2902 break;
2903 case greenland::IntrinsicHelper::ThrowVerificationError:
buzbee8fa0fda2012-06-27 15:44:52 -07002904 cvtThrowVerificationError(cUnit, callInst);
buzbee32412962012-06-26 16:27:56 -07002905 break;
buzbee8fa0fda2012-06-27 15:44:52 -07002906 case greenland::IntrinsicHelper::MonitorEnter:
2907 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
2908 break;
2909 case greenland::IntrinsicHelper::MonitorExit:
2910 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
2911 break;
2912 case greenland::IntrinsicHelper::ArrayLength:
buzbee76592632012-06-29 15:18:35 -07002913 cvtArrayLength(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07002914 break;
2915 case greenland::IntrinsicHelper::NewArray:
2916 cvtNewArray(cUnit, callInst);
2917 break;
2918 case greenland::IntrinsicHelper::InstanceOf:
2919 cvtInstanceOf(cUnit, callInst);
2920 break;
2921
2922 case greenland::IntrinsicHelper::HLArrayGet:
2923 case greenland::IntrinsicHelper::HLArrayGetObject:
2924 case greenland::IntrinsicHelper::HLArrayGetFloat:
2925 cvtAget(cUnit, callInst, kWord, 2);
2926 break;
2927 case greenland::IntrinsicHelper::HLArrayGetWide:
2928 case greenland::IntrinsicHelper::HLArrayGetDouble:
2929 cvtAget(cUnit, callInst, kLong, 3);
2930 break;
2931 case greenland::IntrinsicHelper::HLArrayGetBoolean:
2932 cvtAget(cUnit, callInst, kUnsignedByte, 0);
2933 break;
2934 case greenland::IntrinsicHelper::HLArrayGetByte:
2935 cvtAget(cUnit, callInst, kSignedByte, 0);
2936 break;
2937 case greenland::IntrinsicHelper::HLArrayGetChar:
2938 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
2939 break;
2940 case greenland::IntrinsicHelper::HLArrayGetShort:
2941 cvtAget(cUnit, callInst, kSignedHalf, 1);
2942 break;
2943
2944 case greenland::IntrinsicHelper::HLArrayPut:
2945 case greenland::IntrinsicHelper::HLArrayPutObject:
2946 case greenland::IntrinsicHelper::HLArrayPutFloat:
2947 cvtAput(cUnit, callInst, kWord, 2);
2948 break;
2949 case greenland::IntrinsicHelper::HLArrayPutWide:
2950 case greenland::IntrinsicHelper::HLArrayPutDouble:
2951 cvtAput(cUnit, callInst, kLong, 3);
2952 break;
2953 case greenland::IntrinsicHelper::HLArrayPutBoolean:
2954 cvtAput(cUnit, callInst, kUnsignedByte, 0);
2955 break;
2956 case greenland::IntrinsicHelper::HLArrayPutByte:
2957 cvtAput(cUnit, callInst, kSignedByte, 0);
2958 break;
2959 case greenland::IntrinsicHelper::HLArrayPutChar:
2960 cvtAput(cUnit, callInst, kUnsignedHalf, 1);
2961 break;
2962 case greenland::IntrinsicHelper::HLArrayPutShort:
2963 cvtAput(cUnit, callInst, kSignedHalf, 1);
2964 break;
2965
buzbee101305f2012-06-28 18:00:56 -07002966 case greenland::IntrinsicHelper::HLIGet:
2967 case greenland::IntrinsicHelper::HLIGetFloat:
2968 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
2969 break;
2970 case greenland::IntrinsicHelper::HLIGetObject:
2971 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
2972 break;
2973 case greenland::IntrinsicHelper::HLIGetWide:
2974 case greenland::IntrinsicHelper::HLIGetDouble:
2975 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
2976 break;
2977 case greenland::IntrinsicHelper::HLIGetBoolean:
2978 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
2979 false /* obj */);
2980 break;
2981 case greenland::IntrinsicHelper::HLIGetByte:
2982 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
2983 false /* obj */);
2984 break;
2985 case greenland::IntrinsicHelper::HLIGetChar:
2986 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
2987 false /* obj */);
2988 break;
2989 case greenland::IntrinsicHelper::HLIGetShort:
2990 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
2991 false /* obj */);
2992 break;
2993
2994 case greenland::IntrinsicHelper::HLIPut:
2995 case greenland::IntrinsicHelper::HLIPutFloat:
2996 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
2997 break;
2998 case greenland::IntrinsicHelper::HLIPutObject:
2999 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3000 break;
3001 case greenland::IntrinsicHelper::HLIPutWide:
3002 case greenland::IntrinsicHelper::HLIPutDouble:
3003 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3004 break;
3005 case greenland::IntrinsicHelper::HLIPutBoolean:
3006 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3007 false /* obj */);
3008 break;
3009 case greenland::IntrinsicHelper::HLIPutByte:
3010 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3011 false /* obj */);
3012 break;
3013 case greenland::IntrinsicHelper::HLIPutChar:
3014 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3015 false /* obj */);
3016 break;
3017 case greenland::IntrinsicHelper::HLIPutShort:
3018 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3019 false /* obj */);
3020 break;
3021
3022 case greenland::IntrinsicHelper::IntToChar:
3023 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3024 break;
3025 case greenland::IntrinsicHelper::IntToShort:
3026 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3027 break;
3028 case greenland::IntrinsicHelper::IntToByte:
3029 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3030 break;
3031
buzbee76592632012-06-29 15:18:35 -07003032 case greenland::IntrinsicHelper::CmplFloat:
3033 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3034 break;
3035 case greenland::IntrinsicHelper::CmpgFloat:
3036 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3037 break;
3038 case greenland::IntrinsicHelper::CmplDouble:
3039 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3040 break;
3041 case greenland::IntrinsicHelper::CmpgDouble:
3042 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3043 break;
3044
3045 case greenland::IntrinsicHelper::CmpLong:
3046 cvtLongCompare(cUnit, callInst);
3047 break;
3048
buzbee2cfc6392012-05-07 14:51:40 -07003049 case greenland::IntrinsicHelper::UnknownId:
3050 cvtCall(cUnit, callInst, callee);
3051 break;
3052 default:
3053 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
3054 << cUnit->intrinsic_helper->GetName(id);
3055 }
3056 }
3057 break;
3058
3059 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3060 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3061 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3062 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3063 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3064 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3065 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3066 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3067 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
buzbee101305f2012-06-28 18:00:56 -07003068 case llvm::Instruction::Shl: cvtShiftOp(cUnit, kOpLsl, inst); break;
3069 case llvm::Instruction::LShr: cvtShiftOp(cUnit, kOpLsr, inst); break;
3070 case llvm::Instruction::AShr: cvtShiftOp(cUnit, kOpAsr, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003071 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3072 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
buzbee4f1181f2012-06-22 13:52:12 -07003073 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3074 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3075 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3076 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3077 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
buzbee76592632012-06-29 15:18:35 -07003078 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
3079 case llvm::Instruction::FPToSI: cvtFPToInt(cUnit, inst); break;
3080 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3081 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3082 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003083
buzbee101305f2012-06-28 18:00:56 -07003084 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3085 break;
3086 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3087 break;
3088
buzbeef58c12c2012-07-03 15:06:29 -07003089 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3090
buzbee32412962012-06-26 16:27:56 -07003091 case llvm::Instruction::Unreachable:
3092 break; // FIXME: can we really ignore these?
3093
buzbee2cfc6392012-05-07 14:51:40 -07003094 case llvm::Instruction::Invoke:
buzbee2cfc6392012-05-07 14:51:40 -07003095 case llvm::Instruction::FPToUI:
buzbee2cfc6392012-05-07 14:51:40 -07003096 case llvm::Instruction::UIToFP:
buzbee2cfc6392012-05-07 14:51:40 -07003097 case llvm::Instruction::PtrToInt:
3098 case llvm::Instruction::IntToPtr:
buzbee2cfc6392012-05-07 14:51:40 -07003099 case llvm::Instruction::FCmp:
buzbee2cfc6392012-05-07 14:51:40 -07003100 case llvm::Instruction::URem:
3101 case llvm::Instruction::UDiv:
3102 case llvm::Instruction::Resume:
buzbee2cfc6392012-05-07 14:51:40 -07003103 case llvm::Instruction::Alloca:
3104 case llvm::Instruction::GetElementPtr:
3105 case llvm::Instruction::Fence:
3106 case llvm::Instruction::AtomicCmpXchg:
3107 case llvm::Instruction::AtomicRMW:
3108 case llvm::Instruction::BitCast:
3109 case llvm::Instruction::VAArg:
3110 case llvm::Instruction::Select:
3111 case llvm::Instruction::UserOp1:
3112 case llvm::Instruction::UserOp2:
3113 case llvm::Instruction::ExtractElement:
3114 case llvm::Instruction::InsertElement:
3115 case llvm::Instruction::ShuffleVector:
3116 case llvm::Instruction::ExtractValue:
3117 case llvm::Instruction::InsertValue:
3118 case llvm::Instruction::LandingPad:
3119 case llvm::Instruction::IndirectBr:
3120 case llvm::Instruction::Load:
3121 case llvm::Instruction::Store:
3122 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3123
3124 default:
3125 LOG(FATAL) << "Unknown llvm opcode: " << opcode; break;
3126 }
3127 }
buzbee6969d502012-06-15 16:40:31 -07003128
3129 if (headLIR != NULL) {
3130 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
3131 }
buzbee2cfc6392012-05-07 14:51:40 -07003132 return false;
3133}
3134
3135/*
3136 * Convert LLVM_IR to MIR:
3137 * o Iterate through the LLVM_IR and construct a graph using
3138 * standard MIR building blocks.
3139 * o Perform a basic-block optimization pass to remove unnecessary
3140 * store/load sequences.
3141 * o Convert the LLVM Value operands into RegLocations where applicable.
3142 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3143 * o Perform register promotion
3144 * o Iterate through the graph a basic block at a time, generating
3145 * LIR.
3146 * o Assemble LIR as usual.
3147 * o Profit.
3148 */
3149void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3150{
buzbeead8f15e2012-06-18 14:49:45 -07003151 llvm::Function* func = cUnit->func;
3152 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003153 // Allocate a list for LIR basic block labels
3154 cUnit->blockLabelList =
buzbeea1da8a52012-07-09 14:00:21 -07003155 (LIR*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3156 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003157 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003158 for (llvm::Function::iterator i = func->begin(),
3159 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003160 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3161 &labelList[nextLabel++]);
3162 }
buzbeead8f15e2012-06-18 14:49:45 -07003163
3164 /*
3165 * Keep honest - clear regLocations, Value => RegLocation,
3166 * promotion map and VmapTables.
3167 */
3168 cUnit->locMap.clear(); // Start fresh
3169 cUnit->regLocation = NULL;
3170 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3171 i++) {
3172 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3173 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3174 }
3175 cUnit->coreSpillMask = 0;
3176 cUnit->numCoreSpills = 0;
3177 cUnit->fpSpillMask = 0;
3178 cUnit->numFPSpills = 0;
3179 cUnit->coreVmapTable.clear();
3180 cUnit->fpVmapTable.clear();
3181 oatAdjustSpillMask(cUnit);
3182 cUnit->frameSize = oatComputeFrameSize(cUnit);
3183
3184 /*
3185 * At this point, we've lost all knowledge of register promotion.
3186 * Rebuild that info from the MethodInfo intrinsic (if it
3187 * exists - not required for correctness).
3188 */
3189 // TODO: find and recover MethodInfo.
3190
3191 // Create RegLocations for arguments
3192 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3193 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3194 for (; it != it_end; ++it) {
3195 llvm::Value* val = it;
3196 createLocFromValue(cUnit, val);
3197 }
3198 // Create RegLocations for all non-argument defintions
3199 for (llvm::inst_iterator i = llvm::inst_begin(func),
3200 e = llvm::inst_end(func); i != e; ++i) {
3201 llvm::Value* val = &*i;
3202 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3203 createLocFromValue(cUnit, val);
3204 }
3205 }
3206
buzbee2cfc6392012-05-07 14:51:40 -07003207 // Walk the blocks, generating code.
3208 for (llvm::Function::iterator i = cUnit->func->begin(),
3209 e = cUnit->func->end(); i != e; ++i) {
3210 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3211 }
3212
3213 handleSuspendLaunchpads(cUnit);
3214
3215 handleThrowLaunchpads(cUnit);
3216
3217 handleIntrinsicLaunchpads(cUnit);
3218
3219 freeIR(cUnit);
3220}
3221
3222
3223} // namespace art
3224
3225#endif // ART_USE_QUICK_COMPILER