blob: c84d6d3ddbc436ef70ffa11773026e8a3de132f8 [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);
buzbee9a2487f2012-07-26 14:01:13 -070052 if (placeholder == NULL) {
53 // This can happen on instruction rewrite on verification failure
Bill Buzbeec9f40dd2012-08-15 11:35:25 -070054 LOG(WARNING) << "Null placeholder";
buzbee9a2487f2012-07-26 14:01:13 -070055 return;
56 }
buzbee2cfc6392012-05-07 14:51:40 -070057 placeholder->replaceAllUsesWith(val);
58 val->takeName(placeholder);
59 cUnit->llvmValues.elemList[sReg] = (intptr_t)val;
buzbee4be777b2012-07-12 14:38:18 -070060 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(placeholder);
61 DCHECK(inst != NULL);
62 inst->eraseFromParent();
buzbee2cfc6392012-05-07 14:51:40 -070063}
64
65llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
66{
67 llvm::Type* res = NULL;
68 if (loc.wide) {
69 if (loc.fp)
buzbee4f1181f2012-06-22 13:52:12 -070070 res = cUnit->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070071 else
buzbee4f1181f2012-06-22 13:52:12 -070072 res = cUnit->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070073 } else {
74 if (loc.fp) {
buzbee4f1181f2012-06-22 13:52:12 -070075 res = cUnit->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -070076 } else {
77 if (loc.ref)
78 res = cUnit->irb->GetJObjectTy();
79 else
buzbee4f1181f2012-06-22 13:52:12 -070080 res = cUnit->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -070081 }
82 }
83 return res;
84}
85
buzbeead8f15e2012-06-18 14:49:45 -070086/* Create an in-memory RegLocation from an llvm Value. */
87void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val)
88{
89 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
90 std::string s(val->getName().str());
91 const char* valName = s.c_str();
buzbeead8f15e2012-06-18 14:49:45 -070092 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
93 DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName;
94 int baseSReg = INVALID_SREG;
95 int subscript = -1;
96 sscanf(valName, "v%d_%d", &baseSReg, &subscript);
97 if ((baseSReg == INVALID_SREG) && (!strcmp(valName, "method"))) {
98 baseSReg = SSA_METHOD_BASEREG;
99 subscript = 0;
100 }
buzbeead8f15e2012-06-18 14:49:45 -0700101 DCHECK_NE(baseSReg, INVALID_SREG);
102 DCHECK_NE(subscript, -1);
103 // TODO: redo during C++'ification
104 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
105 INVALID_REG, INVALID_SREG, INVALID_SREG};
106 llvm::Type* ty = val->getType();
107 loc.wide = ((ty == cUnit->irb->getInt64Ty()) ||
108 (ty == cUnit->irb->getDoubleTy()));
109 loc.defined = true;
buzbeeca7a5e42012-08-20 11:12:18 -0700110 loc.home = false; // May change during promotion
buzbeead8f15e2012-06-18 14:49:45 -0700111 loc.sRegLow = baseSReg;
112 loc.origSReg = cUnit->locMap.size();
buzbeeca7a5e42012-08-20 11:12:18 -0700113 PromotionMap pMap = cUnit->promotionMap[baseSReg];
114 if (ty == cUnit->irb->getFloatTy()) {
115 loc.fp = true;
116 if (pMap.fpLocation == kLocPhysReg) {
117 loc.lowReg = pMap.fpReg;
118 loc.location = kLocPhysReg;
119 loc.home = true;
120 }
121 } else if (ty == cUnit->irb->getDoubleTy()) {
122 loc.fp = true;
123 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
124 if ((pMap.fpLocation == kLocPhysReg) &&
125 (pMapHigh.fpLocation == kLocPhysReg) &&
126 ((pMap.fpReg & 0x1) == 0) &&
127 (pMap.fpReg + 1 == pMapHigh.fpReg)) {
128 loc.lowReg = pMap.fpReg;
129 loc.highReg = pMapHigh.fpReg;
130 loc.location = kLocPhysReg;
131 loc.home = true;
132 }
133 } else if (ty == cUnit->irb->GetJObjectTy()) {
134 loc.ref = true;
135 if (pMap.coreLocation == kLocPhysReg) {
136 loc.lowReg = pMap.coreReg;
137 loc.location = kLocPhysReg;
138 loc.home = true;
139 }
140 } else if (ty == cUnit->irb->getInt64Ty()) {
141 loc.core = true;
142 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
143 if ((pMap.coreLocation == kLocPhysReg) &&
144 (pMapHigh.coreLocation == kLocPhysReg)) {
145 loc.lowReg = pMap.coreReg;
146 loc.highReg = pMapHigh.coreReg;
147 loc.location = kLocPhysReg;
148 loc.home = true;
149 }
150 } else {
151 loc.core = true;
152 if (pMap.coreLocation == kLocPhysReg) {
153 loc.lowReg = pMap.coreReg;
154 loc.location = kLocPhysReg;
155 loc.home = true;
156 }
157 }
158
159 if (cUnit->printMe && loc.home) {
160 if (loc.wide) {
161 LOG(INFO) << "Promoted wide " << s << " to regs " << loc.lowReg
162 << "/" << loc.highReg;
163 } else {
164 LOG(INFO) << "Promoted " << s << " to reg " << loc.lowReg;
165 }
166 }
buzbeead8f15e2012-06-18 14:49:45 -0700167 cUnit->locMap.Put(val, loc);
168}
169
buzbee2cfc6392012-05-07 14:51:40 -0700170void initIR(CompilationUnit* cUnit)
171{
172 cUnit->context = new llvm::LLVMContext();
173 cUnit->module = new llvm::Module("art", *cUnit->context);
174 llvm::StructType::create(*cUnit->context, "JavaObject");
175 llvm::StructType::create(*cUnit->context, "Method");
176 llvm::StructType::create(*cUnit->context, "Thread");
177 cUnit->intrinsic_helper =
178 new greenland::IntrinsicHelper(*cUnit->context, *cUnit->module);
179 cUnit->irb =
180 new greenland::IRBuilder(*cUnit->context, *cUnit->module,
181 *cUnit->intrinsic_helper);
182}
183
184void freeIR(CompilationUnit* cUnit)
185{
186 delete cUnit->irb;
187 delete cUnit->intrinsic_helper;
188 delete cUnit->module;
189 delete cUnit->context;
190}
191
192const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
193 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
194}
195
buzbeef58c12c2012-07-03 15:06:29 -0700196llvm::BasicBlock* findCaseTarget(CompilationUnit* cUnit, uint32_t vaddr)
197{
198 BasicBlock* bb = oatFindBlock(cUnit, vaddr);
199 DCHECK(bb != NULL);
200 return getLLVMBlock(cUnit, bb->id);
201}
202
203void convertPackedSwitch(CompilationUnit* cUnit, BasicBlock* bb,
204 int32_t tableOffset, RegLocation rlSrc)
205{
206 const Instruction::PackedSwitchPayload* payload =
207 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
208 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
209
210 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
211
212 llvm::SwitchInst* sw =
213 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
214 payload->case_count);
215
216 for (uint16_t i = 0; i < payload->case_count; ++i) {
217 llvm::BasicBlock* llvmBB =
218 findCaseTarget(cUnit, cUnit->currentDalvikOffset + payload->targets[i]);
219 sw->addCase(cUnit->irb->getInt32(payload->first_key + i), llvmBB);
220 }
221 llvm::MDNode* switchNode =
222 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
223 sw->setMetadata("SwitchTable", switchNode);
224 bb->taken = NULL;
225 bb->fallThrough = NULL;
226}
227
buzbeea1da8a52012-07-09 14:00:21 -0700228void convertSparseSwitch(CompilationUnit* cUnit, BasicBlock* bb,
229 int32_t tableOffset, RegLocation rlSrc)
230{
231 const Instruction::SparseSwitchPayload* payload =
232 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
233 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
234
235 const int32_t* keys = payload->GetKeys();
236 const int32_t* targets = payload->GetTargets();
237
238 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
239
240 llvm::SwitchInst* sw =
241 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
242 payload->case_count);
243
244 for (size_t i = 0; i < payload->case_count; ++i) {
245 llvm::BasicBlock* llvmBB =
246 findCaseTarget(cUnit, cUnit->currentDalvikOffset + targets[i]);
247 sw->addCase(cUnit->irb->getInt32(keys[i]), llvmBB);
248 }
249 llvm::MDNode* switchNode =
250 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
251 sw->setMetadata("SwitchTable", switchNode);
252 bb->taken = NULL;
253 bb->fallThrough = NULL;
254}
255
buzbee8fa0fda2012-06-27 15:44:52 -0700256void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
257 greenland::IntrinsicHelper::IntrinsicId id,
258 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700259{
buzbee8fa0fda2012-06-27 15:44:52 -0700260 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700261 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700262 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
263 defineValue(cUnit, res, rlDest.origSReg);
264}
265
266void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
267 greenland::IntrinsicHelper::IntrinsicId id,
268 RegLocation rlSrc)
269{
270 llvm::SmallVector<llvm::Value*, 2> args;
271 args.push_back(cUnit->irb->getInt32(fieldIndex));
272 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
273 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
274 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700275}
276
buzbee101305f2012-06-28 18:00:56 -0700277void convertFillArrayData(CompilationUnit* cUnit, int32_t offset,
278 RegLocation rlArray)
279{
280 greenland::IntrinsicHelper::IntrinsicId id;
281 id = greenland::IntrinsicHelper::FillArrayData;
282 llvm::SmallVector<llvm::Value*, 2> args;
283 args.push_back(cUnit->irb->getInt32(offset));
284 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
285 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
286 cUnit->irb->CreateCall(intr, args);
287}
288
buzbee2cfc6392012-05-07 14:51:40 -0700289llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
290 RegLocation loc)
291{
292 greenland::IntrinsicHelper::IntrinsicId id;
293 if (loc.wide) {
294 if (loc.fp) {
295 id = greenland::IntrinsicHelper::ConstDouble;
296 } else {
297 id = greenland::IntrinsicHelper::ConstLong;
298 }
299 } else {
300 if (loc.fp) {
301 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700302 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700303 id = greenland::IntrinsicHelper::ConstObj;
304 } else {
305 id = greenland::IntrinsicHelper::ConstInt;
306 }
307 }
308 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
309 return cUnit->irb->CreateCall(intr, src);
310}
buzbeeb03f4872012-06-11 15:22:11 -0700311
312void emitPopShadowFrame(CompilationUnit* cUnit)
313{
314 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
315 greenland::IntrinsicHelper::PopShadowFrame);
316 cUnit->irb->CreateCall(intr);
317}
318
buzbee2cfc6392012-05-07 14:51:40 -0700319llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
320 RegLocation loc)
321{
322 greenland::IntrinsicHelper::IntrinsicId id;
323 if (loc.wide) {
324 if (loc.fp) {
325 id = greenland::IntrinsicHelper::CopyDouble;
326 } else {
327 id = greenland::IntrinsicHelper::CopyLong;
328 }
329 } else {
330 if (loc.fp) {
331 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700332 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700333 id = greenland::IntrinsicHelper::CopyObj;
334 } else {
335 id = greenland::IntrinsicHelper::CopyInt;
336 }
337 }
338 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
339 return cUnit->irb->CreateCall(intr, src);
340}
341
buzbee32412962012-06-26 16:27:56 -0700342void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
343{
344 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
345 greenland::IntrinsicHelper::GetException);
346 llvm::Value* res = cUnit->irb->CreateCall(func);
347 defineValue(cUnit, res, rlDest.origSReg);
348}
349
350void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
351{
352 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
353 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
354 greenland::IntrinsicHelper::Throw);
355 cUnit->irb->CreateCall(func, src);
buzbee32412962012-06-26 16:27:56 -0700356}
357
buzbee8fa0fda2012-06-27 15:44:52 -0700358void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
359 greenland::IntrinsicHelper::IntrinsicId id,
360 RegLocation rlSrc)
361{
362 llvm::SmallVector<llvm::Value*, 2> args;
363 args.push_back(cUnit->irb->getInt32(optFlags));
364 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
365 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
366 cUnit->irb->CreateCall(func, args);
367}
368
buzbee76592632012-06-29 15:18:35 -0700369void convertArrayLength(CompilationUnit* cUnit, int optFlags,
370 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700371{
372 llvm::SmallVector<llvm::Value*, 2> args;
373 args.push_back(cUnit->irb->getInt32(optFlags));
374 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
375 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
376 greenland::IntrinsicHelper::ArrayLength);
buzbee76592632012-06-29 15:18:35 -0700377 llvm::Value* res = cUnit->irb->CreateCall(func, args);
378 defineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700379}
380
buzbee2cfc6392012-05-07 14:51:40 -0700381void emitSuspendCheck(CompilationUnit* cUnit)
382{
383 greenland::IntrinsicHelper::IntrinsicId id =
384 greenland::IntrinsicHelper::CheckSuspend;
385 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
386 cUnit->irb->CreateCall(intr);
387}
388
389llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
390 llvm::Value* src1, llvm::Value* src2)
391{
392 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700393 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700394 switch(cc) {
395 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
396 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
397 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
398 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
399 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
400 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
401 default: LOG(FATAL) << "Unexpected cc value " << cc;
402 }
403 return res;
404}
405
406void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
407 ConditionCode cc, RegLocation rlSrc1,
408 RegLocation rlSrc2)
409{
410 if (bb->taken->startOffset <= mir->offset) {
411 emitSuspendCheck(cUnit);
412 }
413 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
414 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
415 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
416 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
417 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
418 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700419 // Don't redo the fallthrough branch in the BB driver
420 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700421}
422
423void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
424 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
425{
426 if (bb->taken->startOffset <= mir->offset) {
427 emitSuspendCheck(cUnit);
428 }
429 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
430 llvm::Value* src2;
431 if (rlSrc1.ref) {
432 src2 = cUnit->irb->GetJNull();
433 } else {
434 src2 = cUnit->irb->getInt32(0);
435 }
436 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
buzbee2cfc6392012-05-07 14:51:40 -0700437 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
438 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700439 // Don't redo the fallthrough branch in the BB driver
440 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700441}
442
443llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
444 llvm::Value* src1, llvm::Value* src2)
445{
446 greenland::IntrinsicHelper::IntrinsicId id;
447 if (isLong) {
448 if (isDiv) {
449 id = greenland::IntrinsicHelper::DivLong;
450 } else {
451 id = greenland::IntrinsicHelper::RemLong;
452 }
453 } else if (isDiv) {
454 id = greenland::IntrinsicHelper::DivInt;
455 } else {
456 id = greenland::IntrinsicHelper::RemInt;
457 }
458 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
459 llvm::SmallVector<llvm::Value*, 2>args;
460 args.push_back(src1);
461 args.push_back(src2);
462 return cUnit->irb->CreateCall(intr, args);
463}
464
465llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
466 llvm::Value* src1, llvm::Value* src2)
467{
468 llvm::Value* res = NULL;
469 switch(op) {
470 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
471 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700472 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700473 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
474 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
475 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
476 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
477 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
478 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700479 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
480 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
481 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700482 default:
483 LOG(FATAL) << "Invalid op " << op;
484 }
485 return res;
486}
487
488void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
489 RegLocation rlSrc1, RegLocation rlSrc2)
490{
491 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
492 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
493 llvm::Value* res = NULL;
494 switch(op) {
495 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
496 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
497 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
498 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
499 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
500 default:
501 LOG(FATAL) << "Invalid op " << op;
502 }
503 defineValue(cUnit, res, rlDest.origSReg);
504}
505
buzbee2a83e8f2012-07-13 16:42:30 -0700506void convertShift(CompilationUnit* cUnit,
507 greenland::IntrinsicHelper::IntrinsicId id,
508 RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2)
buzbee4f1181f2012-06-22 13:52:12 -0700509{
buzbee2a83e8f2012-07-13 16:42:30 -0700510 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
511 llvm::SmallVector<llvm::Value*, 2>args;
512 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
513 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
514 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
515 defineValue(cUnit, res, rlDest.origSReg);
516}
517
518void convertShiftLit(CompilationUnit* cUnit,
519 greenland::IntrinsicHelper::IntrinsicId id,
520 RegLocation rlDest, RegLocation rlSrc, int shiftAmount)
521{
522 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
523 llvm::SmallVector<llvm::Value*, 2>args;
524 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
525 args.push_back(cUnit->irb->getInt32(shiftAmount));
526 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700527 defineValue(cUnit, res, rlDest.origSReg);
528}
529
buzbee2cfc6392012-05-07 14:51:40 -0700530void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
531 RegLocation rlSrc1, RegLocation rlSrc2)
532{
533 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
534 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700535 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700536 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
537 defineValue(cUnit, res, rlDest.origSReg);
538}
539
buzbeeb03f4872012-06-11 15:22:11 -0700540void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
541{
542 int index = -1;
543 DCHECK(newVal != NULL);
544 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
545 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
546 if (cUnit->shadowMap[i] == vReg) {
547 index = i;
548 break;
549 }
550 }
Elliott Hughes74847412012-06-20 18:10:21 -0700551 DCHECK_NE(index, -1) << "Corrupt shadowMap";
buzbeeb03f4872012-06-11 15:22:11 -0700552 greenland::IntrinsicHelper::IntrinsicId id =
553 greenland::IntrinsicHelper::SetShadowFrameEntry;
554 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
555 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
556 llvm::Value* args[] = { newVal, tableSlot };
557 cUnit->irb->CreateCall(func, args);
558}
559
buzbee2cfc6392012-05-07 14:51:40 -0700560void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
561 RegLocation rlSrc1, int32_t imm)
562{
563 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
564 llvm::Value* src2 = cUnit->irb->getInt32(imm);
565 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
566 defineValue(cUnit, res, rlDest.origSReg);
567}
568
buzbee101305f2012-06-28 18:00:56 -0700569/*
570 * Process arguments for invoke. Note: this code is also used to
571 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
572 * The requirements are similar.
573 */
buzbee6969d502012-06-15 16:40:31 -0700574void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700575 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700576{
577 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
578 llvm::SmallVector<llvm::Value*, 10> args;
579 // Insert the invokeType
580 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
581 // Insert the method_idx
582 args.push_back(cUnit->irb->getInt32(info->index));
583 // Insert the optimization flags
584 args.push_back(cUnit->irb->getInt32(info->optFlags));
585 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700586 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700587 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
588 args.push_back(val);
589 i += info->args[i].wide ? 2 : 1;
590 }
591 /*
592 * Choose the invoke return type based on actual usage. Note: may
593 * be different than shorty. For example, if a function return value
594 * is not used, we'll treat this as a void invoke.
595 */
596 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700597 if (isFilledNewArray) {
598 id = greenland::IntrinsicHelper::FilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700599 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700600 id = greenland::IntrinsicHelper::HLInvokeVoid;
601 } else {
602 if (info->result.wide) {
603 if (info->result.fp) {
604 id = greenland::IntrinsicHelper::HLInvokeDouble;
605 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700606 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700607 }
608 } else if (info->result.ref) {
609 id = greenland::IntrinsicHelper::HLInvokeObj;
610 } else if (info->result.fp) {
611 id = greenland::IntrinsicHelper::HLInvokeFloat;
612 } else {
613 id = greenland::IntrinsicHelper::HLInvokeInt;
614 }
615 }
616 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
617 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
618 if (info->result.location != kLocInvalid) {
619 defineValue(cUnit, res, info->result.origSReg);
620 }
621}
622
buzbee101305f2012-06-28 18:00:56 -0700623void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
624 greenland::IntrinsicHelper::IntrinsicId id,
625 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700626{
buzbee6969d502012-06-15 16:40:31 -0700627 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700628 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700629 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
630 defineValue(cUnit, res, rlDest.origSReg);
631}
632
buzbee101305f2012-06-28 18:00:56 -0700633void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
634 RegLocation rlSrc)
635{
636 greenland::IntrinsicHelper::IntrinsicId id;
637 id = greenland::IntrinsicHelper::CheckCast;
638 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
639 llvm::SmallVector<llvm::Value*, 2> args;
640 args.push_back(cUnit->irb->getInt32(type_idx));
641 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
642 cUnit->irb->CreateCall(intr, args);
643}
644
buzbee8fa0fda2012-06-27 15:44:52 -0700645void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
646 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700647{
648 greenland::IntrinsicHelper::IntrinsicId id;
649 id = greenland::IntrinsicHelper::NewInstance;
650 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
651 llvm::Value* index = cUnit->irb->getInt32(type_idx);
652 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
653 defineValue(cUnit, res, rlDest.origSReg);
654}
655
buzbee8fa0fda2012-06-27 15:44:52 -0700656void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
657 RegLocation rlDest, RegLocation rlSrc)
658{
659 greenland::IntrinsicHelper::IntrinsicId id;
660 id = greenland::IntrinsicHelper::NewArray;
661 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
662 llvm::SmallVector<llvm::Value*, 2> args;
663 args.push_back(cUnit->irb->getInt32(type_idx));
664 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
665 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
666 defineValue(cUnit, res, rlDest.origSReg);
667}
668
669void convertAget(CompilationUnit* cUnit, int optFlags,
670 greenland::IntrinsicHelper::IntrinsicId id,
671 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
672{
673 llvm::SmallVector<llvm::Value*, 3> args;
674 args.push_back(cUnit->irb->getInt32(optFlags));
675 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
676 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
677 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
678 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
679 defineValue(cUnit, res, rlDest.origSReg);
680}
681
682void convertAput(CompilationUnit* cUnit, int optFlags,
683 greenland::IntrinsicHelper::IntrinsicId id,
684 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
685{
686 llvm::SmallVector<llvm::Value*, 4> args;
687 args.push_back(cUnit->irb->getInt32(optFlags));
688 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
689 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
690 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
691 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
692 cUnit->irb->CreateCall(intr, args);
693}
694
buzbee101305f2012-06-28 18:00:56 -0700695void convertIget(CompilationUnit* cUnit, int optFlags,
696 greenland::IntrinsicHelper::IntrinsicId id,
697 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
698{
699 llvm::SmallVector<llvm::Value*, 3> args;
700 args.push_back(cUnit->irb->getInt32(optFlags));
701 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
702 args.push_back(cUnit->irb->getInt32(fieldIndex));
703 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
704 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
705 defineValue(cUnit, res, rlDest.origSReg);
706}
707
708void convertIput(CompilationUnit* cUnit, int optFlags,
709 greenland::IntrinsicHelper::IntrinsicId id,
710 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
711{
712 llvm::SmallVector<llvm::Value*, 4> args;
713 args.push_back(cUnit->irb->getInt32(optFlags));
714 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
715 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
716 args.push_back(cUnit->irb->getInt32(fieldIndex));
717 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
718 cUnit->irb->CreateCall(intr, args);
719}
720
buzbee8fa0fda2012-06-27 15:44:52 -0700721void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
722 RegLocation rlDest, RegLocation rlSrc)
723{
724 greenland::IntrinsicHelper::IntrinsicId id;
725 id = greenland::IntrinsicHelper::InstanceOf;
726 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
727 llvm::SmallVector<llvm::Value*, 2> args;
728 args.push_back(cUnit->irb->getInt32(type_idx));
729 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
730 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
731 defineValue(cUnit, res, rlDest.origSReg);
732}
733
buzbee101305f2012-06-28 18:00:56 -0700734void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
735 RegLocation rlSrc)
736{
737 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
738 cUnit->irb->getInt64Ty());
739 defineValue(cUnit, res, rlDest.origSReg);
740}
741
buzbee76592632012-06-29 15:18:35 -0700742void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
743 RegLocation rlSrc)
744{
745 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
746 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
747 defineValue(cUnit, res, rlDest.origSReg);
748}
749
750void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
751 RegLocation rlSrc)
752{
753 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
754 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
755 defineValue(cUnit, res, rlDest.origSReg);
756}
757
758void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
759 RegLocation rlSrc)
760{
761 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
762 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
763 defineValue(cUnit, res, rlDest.origSReg);
764}
765
766void convertWideComparison(CompilationUnit* cUnit,
767 greenland::IntrinsicHelper::IntrinsicId id,
768 RegLocation rlDest, RegLocation rlSrc1,
769 RegLocation rlSrc2)
770{
771 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
772 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
773 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
774 llvm::SmallVector<llvm::Value*, 2> args;
775 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
776 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
777 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
778 defineValue(cUnit, res, rlDest.origSReg);
779}
780
buzbee101305f2012-06-28 18:00:56 -0700781void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
782 RegLocation rlSrc,
783 greenland::IntrinsicHelper::IntrinsicId id)
784{
785 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700786 llvm::Value* res =
787 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
788 defineValue(cUnit, res, rlDest.origSReg);
789}
790
791void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
792 RegLocation rlSrc)
793{
794 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
795 defineValue(cUnit, res, rlDest.origSReg);
796}
797
798void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
799 RegLocation rlSrc)
800{
801 llvm::Value* res =
802 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
803 defineValue(cUnit, res, rlDest.origSReg);
804}
805
806void convertFPToInt(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
807 RegLocation rlSrc)
808{
809 llvm::Value* res =
810 cUnit->irb->CreateFPToSI(getLLVMValue(cUnit, rlSrc.origSReg), ty);
811 defineValue(cUnit, res, rlDest.origSReg);
812}
813
814
815void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
816 RegLocation rlSrc)
817{
818 llvm::Value* res =
819 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
820 defineValue(cUnit, res, rlDest.origSReg);
821}
822
823void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
824 RegLocation rlSrc)
825{
826 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
827 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700828 defineValue(cUnit, res, rlDest.origSReg);
829}
830
buzbee2cfc6392012-05-07 14:51:40 -0700831/*
832 * Target-independent code generation. Use only high-level
833 * load/store utilities here, or target-dependent genXX() handlers
834 * when necessary.
835 */
836bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
837 llvm::BasicBlock* llvmBB, LIR* labelList)
838{
839 bool res = false; // Assume success
840 RegLocation rlSrc[3];
841 RegLocation rlDest = badLoc;
buzbee2cfc6392012-05-07 14:51:40 -0700842 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee32412962012-06-26 16:27:56 -0700843 uint32_t vA = mir->dalvikInsn.vA;
buzbee6969d502012-06-15 16:40:31 -0700844 uint32_t vB = mir->dalvikInsn.vB;
845 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700846 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700847
buzbeeb03f4872012-06-11 15:22:11 -0700848 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700849
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700850 if (cUnit->printMe) {
851 if ((int)opcode < kMirOpFirst) {
852 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x"
853 << std::hex << (int)opcode;
854 } else {
855 LOG(INFO) << ".. opcode 0x" << std::hex << (int)opcode;
856 }
857 }
858
buzbee2cfc6392012-05-07 14:51:40 -0700859 /* Prep Src and Dest locations */
860 int nextSreg = 0;
861 int nextLoc = 0;
862 int attrs = oatDataFlowAttributes[opcode];
863 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
864 if (attrs & DF_UA) {
865 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700866 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700867 nextSreg+= 2;
868 } else {
869 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
870 nextSreg++;
871 }
872 }
873 if (attrs & DF_UB) {
874 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700875 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700876 nextSreg+= 2;
877 } else {
878 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
879 nextSreg++;
880 }
881 }
882 if (attrs & DF_UC) {
883 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700884 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700885 } else {
886 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
887 }
888 }
889 if (attrs & DF_DA) {
890 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700891 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700892 } else {
buzbee15bf9802012-06-12 17:49:27 -0700893 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700894 if (rlDest.ref) {
895 objectDefinition = true;
896 }
buzbee2cfc6392012-05-07 14:51:40 -0700897 }
898 }
899
900 switch (opcode) {
901 case Instruction::NOP:
902 break;
903
904 case Instruction::MOVE:
905 case Instruction::MOVE_OBJECT:
906 case Instruction::MOVE_16:
907 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700908 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700909 case Instruction::MOVE_FROM16:
910 case Instruction::MOVE_WIDE:
911 case Instruction::MOVE_WIDE_16:
912 case Instruction::MOVE_WIDE_FROM16: {
913 /*
914 * Moves/copies are meaningless in pure SSA register form,
915 * but we need to preserve them for the conversion back into
916 * MIR (at least until we stop using the Dalvik register maps).
917 * Insert a dummy intrinsic copy call, which will be recognized
918 * by the quick path and removed by the portable path.
919 */
920 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
921 llvm::Value* res = emitCopy(cUnit, src, rlDest);
922 defineValue(cUnit, res, rlDest.origSReg);
923 }
924 break;
925
926 case Instruction::CONST:
927 case Instruction::CONST_4:
928 case Instruction::CONST_16: {
buzbee6969d502012-06-15 16:40:31 -0700929 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700930 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
931 defineValue(cUnit, res, rlDest.origSReg);
932 }
933 break;
934
935 case Instruction::CONST_WIDE_16:
936 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700937 // Sign extend to 64 bits
938 int64_t imm = static_cast<int32_t>(vB);
939 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700940 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
941 defineValue(cUnit, res, rlDest.origSReg);
942 }
943 break;
944
945 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700946 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700947 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
948 defineValue(cUnit, res, rlDest.origSReg);
949 }
950 break;
951
952 case Instruction::CONST_WIDE: {
953 llvm::Constant* immValue =
954 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
955 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
956 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700957 }
958 break;
buzbee2cfc6392012-05-07 14:51:40 -0700959 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700960 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700961 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
962 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
963 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700964 }
965 break;
966
buzbee8fa0fda2012-06-27 15:44:52 -0700967 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700968 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700969 rlSrc[0]);
970 break;
971 case Instruction::SPUT:
972 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700973 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700974 rlSrc[0]);
975 } else {
buzbee76592632012-06-29 15:18:35 -0700976 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700977 }
978 break;
979 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700980 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700981 rlSrc[0]);
982 break;
983 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700984 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700985 break;
986 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -0700987 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700988 break;
989 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -0700990 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700991 break;
992 case Instruction::SPUT_WIDE:
993 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700994 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -0700995 rlSrc[0]);
996 } else {
buzbee76592632012-06-29 15:18:35 -0700997 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -0700998 rlSrc[0]);
999 }
1000 break;
1001
1002 case Instruction::SGET_OBJECT:
1003 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
1004 break;
1005 case Instruction::SGET:
1006 if (rlDest.fp) {
1007 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
1008 } else {
1009 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
1010 }
1011 break;
1012 case Instruction::SGET_BOOLEAN:
1013 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
1014 break;
1015 case Instruction::SGET_BYTE:
1016 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
1017 break;
1018 case Instruction::SGET_CHAR:
1019 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
1020 break;
1021 case Instruction::SGET_SHORT:
1022 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
1023 break;
1024 case Instruction::SGET_WIDE:
1025 if (rlDest.fp) {
1026 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
1027 rlDest);
1028 } else {
1029 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001030 }
1031 break;
buzbee2cfc6392012-05-07 14:51:40 -07001032
1033 case Instruction::RETURN_WIDE:
1034 case Instruction::RETURN:
1035 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -07001036 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001037 emitSuspendCheck(cUnit);
1038 }
buzbeeb03f4872012-06-11 15:22:11 -07001039 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001040 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
1041 bb->hasReturn = true;
1042 }
1043 break;
1044
1045 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -07001046 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001047 emitSuspendCheck(cUnit);
1048 }
buzbeeb03f4872012-06-11 15:22:11 -07001049 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001050 cUnit->irb->CreateRetVoid();
1051 bb->hasReturn = true;
1052 }
1053 break;
1054
1055 case Instruction::IF_EQ:
1056 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1057 break;
1058 case Instruction::IF_NE:
1059 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1060 break;
1061 case Instruction::IF_LT:
1062 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1063 break;
1064 case Instruction::IF_GE:
1065 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1066 break;
1067 case Instruction::IF_GT:
1068 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1069 break;
1070 case Instruction::IF_LE:
1071 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1072 break;
1073 case Instruction::IF_EQZ:
1074 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1075 break;
1076 case Instruction::IF_NEZ:
1077 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1078 break;
1079 case Instruction::IF_LTZ:
1080 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1081 break;
1082 case Instruction::IF_GEZ:
1083 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1084 break;
1085 case Instruction::IF_GTZ:
1086 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1087 break;
1088 case Instruction::IF_LEZ:
1089 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1090 break;
1091
1092 case Instruction::GOTO:
1093 case Instruction::GOTO_16:
1094 case Instruction::GOTO_32: {
1095 if (bb->taken->startOffset <= bb->startOffset) {
1096 emitSuspendCheck(cUnit);
1097 }
1098 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1099 }
1100 break;
1101
1102 case Instruction::ADD_LONG:
1103 case Instruction::ADD_LONG_2ADDR:
1104 case Instruction::ADD_INT:
1105 case Instruction::ADD_INT_2ADDR:
1106 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1107 break;
1108 case Instruction::SUB_LONG:
1109 case Instruction::SUB_LONG_2ADDR:
1110 case Instruction::SUB_INT:
1111 case Instruction::SUB_INT_2ADDR:
1112 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1113 break;
1114 case Instruction::MUL_LONG:
1115 case Instruction::MUL_LONG_2ADDR:
1116 case Instruction::MUL_INT:
1117 case Instruction::MUL_INT_2ADDR:
1118 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1119 break;
1120 case Instruction::DIV_LONG:
1121 case Instruction::DIV_LONG_2ADDR:
1122 case Instruction::DIV_INT:
1123 case Instruction::DIV_INT_2ADDR:
1124 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1125 break;
1126 case Instruction::REM_LONG:
1127 case Instruction::REM_LONG_2ADDR:
1128 case Instruction::REM_INT:
1129 case Instruction::REM_INT_2ADDR:
1130 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1131 break;
1132 case Instruction::AND_LONG:
1133 case Instruction::AND_LONG_2ADDR:
1134 case Instruction::AND_INT:
1135 case Instruction::AND_INT_2ADDR:
1136 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1137 break;
1138 case Instruction::OR_LONG:
1139 case Instruction::OR_LONG_2ADDR:
1140 case Instruction::OR_INT:
1141 case Instruction::OR_INT_2ADDR:
1142 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1143 break;
1144 case Instruction::XOR_LONG:
1145 case Instruction::XOR_LONG_2ADDR:
1146 case Instruction::XOR_INT:
1147 case Instruction::XOR_INT_2ADDR:
1148 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1149 break;
1150 case Instruction::SHL_LONG:
1151 case Instruction::SHL_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001152 convertShift(cUnit, greenland::IntrinsicHelper::SHLLong,
1153 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001154 break;
buzbee2cfc6392012-05-07 14:51:40 -07001155 case Instruction::SHL_INT:
1156 case Instruction::SHL_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001157 convertShift(cUnit, greenland::IntrinsicHelper::SHLInt,
1158 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001159 break;
1160 case Instruction::SHR_LONG:
1161 case Instruction::SHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001162 convertShift(cUnit, greenland::IntrinsicHelper::SHRLong,
1163 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001164 break;
buzbee2cfc6392012-05-07 14:51:40 -07001165 case Instruction::SHR_INT:
1166 case Instruction::SHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001167 convertShift(cUnit, greenland::IntrinsicHelper::SHRInt,
1168 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001169 break;
1170 case Instruction::USHR_LONG:
1171 case Instruction::USHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001172 convertShift(cUnit, greenland::IntrinsicHelper::USHRLong,
1173 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001174 break;
buzbee2cfc6392012-05-07 14:51:40 -07001175 case Instruction::USHR_INT:
1176 case Instruction::USHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001177 convertShift(cUnit, greenland::IntrinsicHelper::USHRInt,
1178 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001179 break;
1180
1181 case Instruction::ADD_INT_LIT16:
1182 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001183 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001184 break;
1185 case Instruction::RSUB_INT:
1186 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001187 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001188 break;
1189 case Instruction::MUL_INT_LIT16:
1190 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001191 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001192 break;
1193 case Instruction::DIV_INT_LIT16:
1194 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001195 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001196 break;
1197 case Instruction::REM_INT_LIT16:
1198 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001199 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001200 break;
1201 case Instruction::AND_INT_LIT16:
1202 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001203 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001204 break;
1205 case Instruction::OR_INT_LIT16:
1206 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001207 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001208 break;
1209 case Instruction::XOR_INT_LIT16:
1210 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001211 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001212 break;
1213 case Instruction::SHL_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001214 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHLInt,
1215 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001216 break;
1217 case Instruction::SHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001218 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHRInt,
1219 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001220 break;
1221 case Instruction::USHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001222 convertShiftLit(cUnit, greenland::IntrinsicHelper::USHRInt,
1223 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001224 break;
1225
1226 case Instruction::ADD_FLOAT:
1227 case Instruction::ADD_FLOAT_2ADDR:
1228 case Instruction::ADD_DOUBLE:
1229 case Instruction::ADD_DOUBLE_2ADDR:
1230 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1231 break;
1232
1233 case Instruction::SUB_FLOAT:
1234 case Instruction::SUB_FLOAT_2ADDR:
1235 case Instruction::SUB_DOUBLE:
1236 case Instruction::SUB_DOUBLE_2ADDR:
1237 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1238 break;
1239
1240 case Instruction::MUL_FLOAT:
1241 case Instruction::MUL_FLOAT_2ADDR:
1242 case Instruction::MUL_DOUBLE:
1243 case Instruction::MUL_DOUBLE_2ADDR:
1244 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1245 break;
1246
1247 case Instruction::DIV_FLOAT:
1248 case Instruction::DIV_FLOAT_2ADDR:
1249 case Instruction::DIV_DOUBLE:
1250 case Instruction::DIV_DOUBLE_2ADDR:
1251 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1252 break;
1253
1254 case Instruction::REM_FLOAT:
1255 case Instruction::REM_FLOAT_2ADDR:
1256 case Instruction::REM_DOUBLE:
1257 case Instruction::REM_DOUBLE_2ADDR:
1258 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1259 break;
1260
buzbee6969d502012-06-15 16:40:31 -07001261 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001262 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1263 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001264 break;
1265 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001266 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1267 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001268 break;
1269
1270 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001271 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1272 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001273 break;
1274 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001275 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1276 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001277 break;
1278
1279 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001280 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1281 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001282 break;
1283 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001284 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1285 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001286 break;
1287
1288 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001289 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1290 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001291 break;
1292 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001293 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1294 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001295 break;
1296
1297 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001298 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1299 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001300 break;
1301 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001302 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1303 false /* NewFilledArray */);
1304 break;
1305 case Instruction::FILLED_NEW_ARRAY:
1306 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1307 true /* NewFilledArray */);
1308 break;
1309 case Instruction::FILLED_NEW_ARRAY_RANGE:
1310 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1311 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001312 break;
1313
1314 case Instruction::CONST_STRING:
1315 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001316 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1317 rlDest);
1318 break;
1319
1320 case Instruction::CONST_CLASS:
1321 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1322 rlDest);
1323 break;
1324
1325 case Instruction::CHECK_CAST:
1326 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001327 break;
1328
buzbee4f1181f2012-06-22 13:52:12 -07001329 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001330 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001331 break;
1332
buzbee32412962012-06-26 16:27:56 -07001333 case Instruction::MOVE_EXCEPTION:
1334 convertMoveException(cUnit, rlDest);
1335 break;
1336
1337 case Instruction::THROW:
1338 convertThrow(cUnit, rlSrc[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001339 /*
1340 * If this throw is standalone, terminate.
1341 * If it might rethrow, force termination
1342 * of the following block.
1343 */
1344 if (bb->fallThrough == NULL) {
1345 cUnit->irb->CreateUnreachable();
1346 } else {
1347 bb->fallThrough->fallThrough = NULL;
1348 bb->fallThrough->taken = NULL;
1349 }
buzbee32412962012-06-26 16:27:56 -07001350 break;
1351
buzbee2cfc6392012-05-07 14:51:40 -07001352 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001353 case Instruction::MOVE_RESULT:
1354 case Instruction::MOVE_RESULT_OBJECT:
buzbee9a2487f2012-07-26 14:01:13 -07001355 /*
jeffhao9a4f0032012-08-30 16:17:40 -07001356 * All move_results should have been folded into the preceeding invoke.
buzbee9a2487f2012-07-26 14:01:13 -07001357 */
jeffhao9a4f0032012-08-30 16:17:40 -07001358 LOG(FATAL) << "Unexpected move_result";
buzbee2cfc6392012-05-07 14:51:40 -07001359 break;
1360
1361 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001362 convertMonitorEnterExit(cUnit, optFlags,
1363 greenland::IntrinsicHelper::MonitorEnter,
1364 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001365 break;
1366
1367 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001368 convertMonitorEnterExit(cUnit, optFlags,
1369 greenland::IntrinsicHelper::MonitorExit,
1370 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001371 break;
1372
1373 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001374 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001375 break;
1376
1377 case Instruction::NEW_ARRAY:
1378 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1379 break;
1380
1381 case Instruction::INSTANCE_OF:
1382 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1383 break;
1384
1385 case Instruction::AGET:
1386 if (rlDest.fp) {
1387 convertAget(cUnit, optFlags,
1388 greenland::IntrinsicHelper::HLArrayGetFloat,
1389 rlDest, rlSrc[0], rlSrc[1]);
1390 } else {
1391 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1392 rlDest, rlSrc[0], rlSrc[1]);
1393 }
1394 break;
1395 case Instruction::AGET_OBJECT:
1396 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1397 rlDest, rlSrc[0], rlSrc[1]);
1398 break;
1399 case Instruction::AGET_BOOLEAN:
1400 convertAget(cUnit, optFlags,
1401 greenland::IntrinsicHelper::HLArrayGetBoolean,
1402 rlDest, rlSrc[0], rlSrc[1]);
1403 break;
1404 case Instruction::AGET_BYTE:
1405 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1406 rlDest, rlSrc[0], rlSrc[1]);
1407 break;
1408 case Instruction::AGET_CHAR:
1409 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1410 rlDest, rlSrc[0], rlSrc[1]);
1411 break;
1412 case Instruction::AGET_SHORT:
1413 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1414 rlDest, rlSrc[0], rlSrc[1]);
1415 break;
1416 case Instruction::AGET_WIDE:
1417 if (rlDest.fp) {
1418 convertAget(cUnit, optFlags,
1419 greenland::IntrinsicHelper::HLArrayGetDouble,
1420 rlDest, rlSrc[0], rlSrc[1]);
1421 } else {
1422 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1423 rlDest, rlSrc[0], rlSrc[1]);
1424 }
1425 break;
1426
1427 case Instruction::APUT:
1428 if (rlSrc[0].fp) {
1429 convertAput(cUnit, optFlags,
1430 greenland::IntrinsicHelper::HLArrayPutFloat,
1431 rlSrc[0], rlSrc[1], rlSrc[2]);
1432 } else {
1433 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1434 rlSrc[0], rlSrc[1], rlSrc[2]);
1435 }
1436 break;
1437 case Instruction::APUT_OBJECT:
1438 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1439 rlSrc[0], rlSrc[1], rlSrc[2]);
1440 break;
1441 case Instruction::APUT_BOOLEAN:
1442 convertAput(cUnit, optFlags,
1443 greenland::IntrinsicHelper::HLArrayPutBoolean,
1444 rlSrc[0], rlSrc[1], rlSrc[2]);
1445 break;
1446 case Instruction::APUT_BYTE:
1447 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1448 rlSrc[0], rlSrc[1], rlSrc[2]);
1449 break;
1450 case Instruction::APUT_CHAR:
1451 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1452 rlSrc[0], rlSrc[1], rlSrc[2]);
1453 break;
1454 case Instruction::APUT_SHORT:
1455 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1456 rlSrc[0], rlSrc[1], rlSrc[2]);
1457 break;
1458 case Instruction::APUT_WIDE:
1459 if (rlSrc[0].fp) {
1460 convertAput(cUnit, optFlags,
1461 greenland::IntrinsicHelper::HLArrayPutDouble,
1462 rlSrc[0], rlSrc[1], rlSrc[2]);
1463 } else {
1464 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1465 rlSrc[0], rlSrc[1], rlSrc[2]);
1466 }
1467 break;
1468
buzbee101305f2012-06-28 18:00:56 -07001469 case Instruction::IGET:
1470 if (rlDest.fp) {
1471 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001472 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001473 } else {
1474 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001475 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001476 }
buzbee2cfc6392012-05-07 14:51:40 -07001477 break;
buzbee101305f2012-06-28 18:00:56 -07001478 case Instruction::IGET_OBJECT:
1479 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001480 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001481 break;
1482 case Instruction::IGET_BOOLEAN:
1483 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001484 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001485 break;
1486 case Instruction::IGET_BYTE:
1487 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001488 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001489 break;
1490 case Instruction::IGET_CHAR:
1491 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001492 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001493 break;
1494 case Instruction::IGET_SHORT:
1495 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001496 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001497 break;
1498 case Instruction::IGET_WIDE:
1499 if (rlDest.fp) {
1500 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001501 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001502 } else {
1503 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001504 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001505 }
1506 break;
1507 case Instruction::IPUT:
buzbee85eee022012-07-16 22:12:38 -07001508 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001509 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1510 rlSrc[0], rlSrc[1], vC);
1511 } else {
1512 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1513 rlSrc[0], rlSrc[1], vC);
1514 }
1515 break;
1516 case Instruction::IPUT_OBJECT:
1517 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1518 rlSrc[0], rlSrc[1], vC);
1519 break;
1520 case Instruction::IPUT_BOOLEAN:
1521 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1522 rlSrc[0], rlSrc[1], vC);
1523 break;
1524 case Instruction::IPUT_BYTE:
1525 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1526 rlSrc[0], rlSrc[1], vC);
1527 break;
1528 case Instruction::IPUT_CHAR:
1529 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1530 rlSrc[0], rlSrc[1], vC);
1531 break;
1532 case Instruction::IPUT_SHORT:
1533 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1534 rlSrc[0], rlSrc[1], vC);
1535 break;
1536 case Instruction::IPUT_WIDE:
buzbee85eee022012-07-16 22:12:38 -07001537 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001538 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1539 rlSrc[0], rlSrc[1], vC);
1540 } else {
1541 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1542 rlSrc[0], rlSrc[1], vC);
1543 }
buzbee2cfc6392012-05-07 14:51:40 -07001544 break;
1545
1546 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001547 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001548 break;
1549
buzbee76592632012-06-29 15:18:35 -07001550 case Instruction::LONG_TO_INT:
1551 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1552 break;
1553
buzbee101305f2012-06-28 18:00:56 -07001554 case Instruction::INT_TO_LONG:
1555 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001556 break;
1557
buzbee101305f2012-06-28 18:00:56 -07001558 case Instruction::INT_TO_CHAR:
1559 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1560 greenland::IntrinsicHelper::IntToChar);
1561 break;
1562 case Instruction::INT_TO_BYTE:
1563 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1564 greenland::IntrinsicHelper::IntToByte);
1565 break;
1566 case Instruction::INT_TO_SHORT:
1567 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1568 greenland::IntrinsicHelper::IntToShort);
1569 break;
1570
buzbee76592632012-06-29 15:18:35 -07001571 case Instruction::INT_TO_FLOAT:
1572 case Instruction::LONG_TO_FLOAT:
1573 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001574 break;
1575
buzbee76592632012-06-29 15:18:35 -07001576 case Instruction::INT_TO_DOUBLE:
1577 case Instruction::LONG_TO_DOUBLE:
1578 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001579 break;
1580
buzbee76592632012-06-29 15:18:35 -07001581 case Instruction::FLOAT_TO_DOUBLE:
1582 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001583 break;
1584
buzbee76592632012-06-29 15:18:35 -07001585 case Instruction::DOUBLE_TO_FLOAT:
1586 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001587 break;
1588
1589 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001590 case Instruction::NEG_INT:
1591 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001592 break;
1593
1594 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001595 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001596 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001597 break;
1598
buzbee76592632012-06-29 15:18:35 -07001599 case Instruction::NOT_LONG:
1600 case Instruction::NOT_INT:
1601 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001602 break;
1603
buzbee2cfc6392012-05-07 14:51:40 -07001604 case Instruction::FLOAT_TO_INT:
buzbee2cfc6392012-05-07 14:51:40 -07001605 case Instruction::DOUBLE_TO_INT:
buzbee76592632012-06-29 15:18:35 -07001606 convertFPToInt(cUnit, cUnit->irb->getInt32Ty(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001607 break;
1608
buzbee76592632012-06-29 15:18:35 -07001609 case Instruction::FLOAT_TO_LONG:
1610 case Instruction::DOUBLE_TO_LONG:
1611 convertFPToInt(cUnit, cUnit->irb->getInt64Ty(), rlDest, rlSrc[0]);
1612 break;
1613
1614 case Instruction::CMPL_FLOAT:
1615 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1616 rlDest, rlSrc[0], rlSrc[1]);
1617 break;
1618 case Instruction::CMPG_FLOAT:
1619 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1620 rlDest, rlSrc[0], rlSrc[1]);
1621 break;
1622 case Instruction::CMPL_DOUBLE:
1623 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1624 rlDest, rlSrc[0], rlSrc[1]);
1625 break;
1626 case Instruction::CMPG_DOUBLE:
1627 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1628 rlDest, rlSrc[0], rlSrc[1]);
1629 break;
1630 case Instruction::CMP_LONG:
1631 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1632 rlDest, rlSrc[0], rlSrc[1]);
1633 break;
1634
buzbee76592632012-06-29 15:18:35 -07001635 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001636 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001637 break;
1638
1639 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001640 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001641 break;
buzbee2cfc6392012-05-07 14:51:40 -07001642
1643 default:
buzbee32412962012-06-26 16:27:56 -07001644 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001645 res = true;
1646 }
buzbeeb03f4872012-06-11 15:22:11 -07001647 if (objectDefinition) {
1648 setShadowFrameEntry(cUnit, (llvm::Value*)
1649 cUnit->llvmValues.elemList[rlDest.origSReg]);
1650 }
buzbee2cfc6392012-05-07 14:51:40 -07001651 return res;
1652}
1653
1654/* Extended MIR instructions like PHI */
1655void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1656 llvm::BasicBlock* llvmBB)
1657{
1658
1659 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1660 case kMirOpPhi: {
buzbee2cfc6392012-05-07 14:51:40 -07001661 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001662 /*
1663 * The Art compiler's Phi nodes only handle 32-bit operands,
1664 * representing wide values using a matched set of Phi nodes
1665 * for the lower and upper halves. In the llvm world, we only
1666 * want a single Phi for wides. Here we will simply discard
1667 * the Phi node representing the high word.
1668 */
1669 if (rlDest.highWord) {
1670 return; // No Phi node - handled via low word
1671 }
1672 int* incoming = (int*)mir->dalvikInsn.vB;
buzbee2cfc6392012-05-07 14:51:40 -07001673 llvm::Type* phiType =
1674 llvmTypeFromLocRec(cUnit, rlDest);
1675 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1676 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1677 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001678 // Don't check width here.
1679 loc = oatGetRawSrc(cUnit, mir, i);
1680 DCHECK_EQ(rlDest.wide, loc.wide);
1681 DCHECK_EQ(rlDest.wide & rlDest.highWord, loc.wide & loc.highWord);
1682 DCHECK_EQ(rlDest.fp, loc.fp);
1683 DCHECK_EQ(rlDest.core, loc.core);
1684 DCHECK_EQ(rlDest.ref, loc.ref);
buzbee2cfc6392012-05-07 14:51:40 -07001685 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
1686 getLLVMBlock(cUnit, incoming[i]));
1687 }
1688 defineValue(cUnit, phi, rlDest.origSReg);
1689 break;
1690 }
1691 case kMirOpCopy: {
1692 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1693 break;
1694 }
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001695 case kMirOpNop:
1696 if ((mir == bb->lastMIRInsn) && (bb->taken == NULL) &&
1697 (bb->fallThrough == NULL)) {
1698 cUnit->irb->CreateUnreachable();
1699 }
1700 break;
1701
buzbee2cfc6392012-05-07 14:51:40 -07001702#if defined(TARGET_ARM)
1703 case kMirOpFusedCmplFloat:
1704 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1705 break;
1706 case kMirOpFusedCmpgFloat:
1707 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1708 break;
1709 case kMirOpFusedCmplDouble:
1710 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1711 break;
1712 case kMirOpFusedCmpgDouble:
1713 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1714 break;
1715 case kMirOpFusedCmpLong:
1716 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1717 break;
1718#endif
1719 default:
1720 break;
1721 }
1722}
1723
1724void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1725{
1726 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001727 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001728 arrayRef.push_back(cUnit->irb->getInt32(offset));
1729 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1730 cUnit->irb->SetDexOffset(node);
1731}
1732
1733// Attach method info as metadata to special intrinsic
1734void setMethodInfo(CompilationUnit* cUnit)
1735{
1736 // We don't want dex offset on this
1737 cUnit->irb->SetDexOffset(NULL);
1738 greenland::IntrinsicHelper::IntrinsicId id;
1739 id = greenland::IntrinsicHelper::MethodInfo;
1740 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1741 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1742 llvm::SmallVector<llvm::Value*, 2> regInfo;
1743 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1744 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1745 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1746 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1747 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1748 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1749 inst->setMetadata("RegInfo", regInfoNode);
1750 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1751 llvm::SmallVector<llvm::Value*, 50> pmap;
1752 for (int i = 0; i < promoSize; i++) {
1753 PromotionMap* p = &cUnit->promotionMap[i];
1754 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1755 ((p->fpReg & 0xff) << 16) |
1756 ((p->coreReg & 0xff) << 8) |
1757 ((p->fpLocation & 0xf) << 4) |
1758 (p->coreLocation & 0xf);
1759 pmap.push_back(cUnit->irb->getInt32(mapData));
1760 }
1761 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1762 inst->setMetadata("PromotionMap", mapNode);
1763 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1764}
1765
1766/* Handle the content in each basic block */
1767bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1768{
1769 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
1770 cUnit->irb->SetInsertPoint(llvmBB);
1771 setDexOffset(cUnit, bb->startOffset);
1772
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001773 if (cUnit->printMe) {
1774 LOG(INFO) << "................................";
1775 LOG(INFO) << "Block id " << bb->id;
1776 if (llvmBB != NULL) {
1777 LOG(INFO) << "label " << llvmBB->getName().str().c_str();
1778 } else {
1779 LOG(INFO) << "llvmBB is NULL";
1780 }
1781 }
1782
buzbee2cfc6392012-05-07 14:51:40 -07001783 if (bb->blockType == kEntryBlock) {
1784 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001785 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1786 cUnit->numDalvikRegisters, true,
1787 kAllocMisc);
1788 for (int i = 0; i < cUnit->numSSARegs; i++) {
1789 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1790 }
1791 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1792 if (canBeRef[i]) {
1793 cUnit->numShadowFrameEntries++;
1794 }
1795 }
1796 if (cUnit->numShadowFrameEntries > 0) {
1797 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1798 cUnit->numShadowFrameEntries, true,
1799 kAllocMisc);
1800 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1801 if (canBeRef[i]) {
1802 cUnit->shadowMap[j++] = i;
1803 }
1804 }
1805 greenland::IntrinsicHelper::IntrinsicId id =
1806 greenland::IntrinsicHelper::AllocaShadowFrame;
1807 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1808 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1809 cUnit->irb->CreateCall(func, entries);
1810 }
buzbee2cfc6392012-05-07 14:51:40 -07001811 } else if (bb->blockType == kExitBlock) {
1812 /*
1813 * Because of the differences between how MIR/LIR and llvm handle exit
1814 * blocks, we won't explicitly covert them. On the llvm-to-lir
1815 * path, it will need to be regenereated.
1816 */
1817 return false;
buzbee6969d502012-06-15 16:40:31 -07001818 } else if (bb->blockType == kExceptionHandling) {
1819 /*
1820 * Because we're deferring null checking, delete the associated empty
1821 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001822 */
1823 llvmBB->eraseFromParent();
1824 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001825 }
1826
1827 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1828
1829 setDexOffset(cUnit, mir->offset);
1830
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001831 int opcode = mir->dalvikInsn.opcode;
1832 Instruction::Format dalvikFormat =
1833 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001834
1835 /* If we're compiling for the debugger, generate an update callout */
1836 if (cUnit->genDebugger) {
1837 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1838 //genDebuggerUpdate(cUnit, mir->offset);
1839 }
1840
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001841 if (opcode == kMirOpCheck) {
1842 // Combine check and work halves of throwing instruction.
1843 MIR* workHalf = mir->meta.throwInsn;
1844 mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
1845 opcode = mir->dalvikInsn.opcode;
1846 SSARepresentation* ssaRep = workHalf->ssaRep;
1847 workHalf->ssaRep = mir->ssaRep;
1848 mir->ssaRep = ssaRep;
1849 workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1850 if (bb->successorBlockList.blockListType == kCatch) {
1851 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
1852 greenland::IntrinsicHelper::CatchTargets);
1853 llvm::Value* switchKey =
1854 cUnit->irb->CreateCall(intr, cUnit->irb->getInt32(mir->offset));
1855 GrowableListIterator iter;
1856 oatGrowableListIteratorInit(&bb->successorBlockList.blocks, &iter);
1857 // New basic block to use for work half
1858 llvm::BasicBlock* workBB =
1859 llvm::BasicBlock::Create(*cUnit->context, "", cUnit->func);
1860 llvm::SwitchInst* sw =
1861 cUnit->irb->CreateSwitch(switchKey, workBB,
1862 bb->successorBlockList.blocks.numUsed);
1863 while (true) {
1864 SuccessorBlockInfo *successorBlockInfo =
1865 (SuccessorBlockInfo *) oatGrowableListIteratorNext(&iter);
1866 if (successorBlockInfo == NULL) break;
1867 llvm::BasicBlock *target =
1868 getLLVMBlock(cUnit, successorBlockInfo->block->id);
1869 int typeIndex = successorBlockInfo->key;
1870 sw->addCase(cUnit->irb->getInt32(typeIndex), target);
1871 }
1872 llvmBB = workBB;
1873 cUnit->irb->SetInsertPoint(llvmBB);
1874 }
1875 }
1876
1877 if (opcode >= kMirOpFirst) {
buzbee2cfc6392012-05-07 14:51:40 -07001878 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1879 continue;
1880 }
1881
1882 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1883 NULL /* labelList */);
1884 if (notHandled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001885 Instruction::Code dalvikOpcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001886 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001887 mir->offset, opcode,
buzbee2cfc6392012-05-07 14:51:40 -07001888 Instruction::Name(dalvikOpcode),
1889 dalvikFormat);
1890 }
1891 }
1892
buzbee4be777b2012-07-12 14:38:18 -07001893 if (bb->blockType == kEntryBlock) {
1894 cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
1895 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001896 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1897 }
1898
1899 return false;
1900}
1901
buzbee4f4dfc72012-07-02 14:54:44 -07001902char remapShorty(char shortyType) {
1903 /*
1904 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1905 * and longs/doubles are represented as a pair of registers. When sub-word
1906 * arguments (and method results) are passed, they are extended to Dalvik
1907 * virtual register containers. Because llvm is picky about type consistency,
1908 * we must either cast the "real" type to 32-bit container multiple Dalvik
1909 * register types, or always use the expanded values.
1910 * Here, we're doing the latter. We map the shorty signature to container
1911 * types (which is valid so long as we always do a real expansion of passed
1912 * arguments and field loads).
1913 */
1914 switch(shortyType) {
1915 case 'Z' : shortyType = 'I'; break;
1916 case 'B' : shortyType = 'I'; break;
1917 case 'S' : shortyType = 'I'; break;
1918 case 'C' : shortyType = 'I'; break;
1919 default: break;
1920 }
1921 return shortyType;
1922}
1923
buzbee2cfc6392012-05-07 14:51:40 -07001924llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1925
1926 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001927 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001928 greenland::kAccurate);
1929
1930 // Get argument type
1931 std::vector<llvm::Type*> args_type;
1932
1933 // method object
1934 args_type.push_back(cUnit->irb->GetJMethodTy());
1935
1936 // Do we have a "this"?
1937 if ((cUnit->access_flags & kAccStatic) == 0) {
1938 args_type.push_back(cUnit->irb->GetJObjectTy());
1939 }
1940
1941 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001942 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001943 greenland::kAccurate));
1944 }
1945
1946 return llvm::FunctionType::get(ret_type, args_type, false);
1947}
1948
1949bool createFunction(CompilationUnit* cUnit) {
1950 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1951 /* with_signature */ false));
1952 llvm::FunctionType* func_type = getFunctionType(cUnit);
1953
1954 if (func_type == NULL) {
1955 return false;
1956 }
1957
1958 cUnit->func = llvm::Function::Create(func_type,
1959 llvm::Function::ExternalLinkage,
1960 func_name, cUnit->module);
1961
1962 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1963 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1964
1965 arg_iter->setName("method");
1966 ++arg_iter;
1967
1968 int startSReg = cUnit->numRegs;
1969
1970 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1971 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1972 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1973 }
1974
1975 return true;
1976}
1977
1978bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1979{
1980 // Skip the exit block
1981 if (bb->blockType == kExitBlock) {
1982 cUnit->idToBlockMap.Put(bb->id, NULL);
1983 } else {
1984 int offset = bb->startOffset;
1985 bool entryBlock = (bb->blockType == kEntryBlock);
1986 llvm::BasicBlock* llvmBB =
1987 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
Elliott Hughes74847412012-06-20 18:10:21 -07001988 StringPrintf(kLabelFormat, offset, bb->id),
buzbee2cfc6392012-05-07 14:51:40 -07001989 cUnit->func);
1990 if (entryBlock) {
1991 cUnit->entryBB = llvmBB;
1992 cUnit->placeholderBB =
1993 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
1994 cUnit->func);
1995 }
1996 cUnit->idToBlockMap.Put(bb->id, llvmBB);
1997 }
1998 return false;
1999}
2000
2001
2002/*
2003 * Convert MIR to LLVM_IR
2004 * o For each ssa name, create LLVM named value. Type these
2005 * appropriately, and ignore high half of wide and double operands.
2006 * o For each MIR basic block, create an LLVM basic block.
2007 * o Iterate through the MIR a basic block at a time, setting arguments
2008 * to recovered ssa name.
2009 */
2010void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
2011{
2012 initIR(cUnit);
2013 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
2014
2015 // Create the function
2016 createFunction(cUnit);
2017
2018 // Create an LLVM basic block for each MIR block in dfs preorder
2019 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
2020 kPreOrderDFSTraversal, false /* isIterative */);
2021 /*
2022 * Create an llvm named value for each MIR SSA name. Note: we'll use
2023 * placeholders for all non-argument values (because we haven't seen
2024 * the definition yet).
2025 */
2026 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2027 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2028 arg_iter++; /* Skip path method */
2029 for (int i = 0; i < cUnit->numSSARegs; i++) {
2030 llvm::Value* val;
buzbee85eee022012-07-16 22:12:38 -07002031 RegLocation rlTemp = cUnit->regLocation[i];
2032 if ((SRegToVReg(cUnit, i) < 0) || rlTemp.highWord) {
buzbee2a83e8f2012-07-13 16:42:30 -07002033 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
2034 } else if ((i < cUnit->numRegs) ||
2035 (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee85eee022012-07-16 22:12:38 -07002036 llvm::Constant* immValue = cUnit->regLocation[i].wide ?
2037 cUnit->irb->GetJLong(0) : cUnit->irb->GetJInt(0);
buzbee2a83e8f2012-07-13 16:42:30 -07002038 val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
2039 val->setName(llvmSSAName(cUnit, i));
buzbee2cfc6392012-05-07 14:51:40 -07002040 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
buzbee2cfc6392012-05-07 14:51:40 -07002041 } else {
2042 // Recover previously-created argument values
2043 llvm::Value* argVal = arg_iter++;
2044 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
2045 }
2046 }
buzbee2cfc6392012-05-07 14:51:40 -07002047
2048 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
2049 kPreOrderDFSTraversal, false /* Iterative */);
2050
buzbee4be777b2012-07-12 14:38:18 -07002051 /*
2052 * In a few rare cases of verification failure, the verifier will
2053 * replace one or more Dalvik opcodes with the special
2054 * throw-verification-failure opcode. This can leave the SSA graph
2055 * in an invalid state, as definitions may be lost, while uses retained.
2056 * To work around this problem, we insert placeholder definitions for
2057 * all Dalvik SSA regs in the "placeholder" block. Here, after
2058 * bitcode conversion is complete, we examine those placeholder definitions
2059 * and delete any with no references (which normally is all of them).
2060 *
2061 * If any definitions remain, we link the placeholder block into the
2062 * CFG. Otherwise, it is deleted.
2063 */
2064 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
2065 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
2066 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2067 DCHECK(inst != NULL);
2068 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2069 DCHECK(val != NULL);
2070 if (val->getNumUses() == 0) {
2071 inst->eraseFromParent();
2072 }
2073 }
2074 setDexOffset(cUnit, 0);
2075 if (cUnit->placeholderBB->empty()) {
2076 cUnit->placeholderBB->eraseFromParent();
2077 } else {
2078 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2079 cUnit->irb->CreateBr(cUnit->entryTargetBB);
2080 cUnit->entryTargetBB = cUnit->placeholderBB;
2081 }
2082 cUnit->irb->SetInsertPoint(cUnit->entryBB);
2083 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07002084
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002085 if (cUnit->enableDebug & (1 << kDebugVerifyBitcode)) {
2086 if (llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction)) {
2087 LOG(INFO) << "Bitcode verification FAILED for "
2088 << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
2089 << " of size " << cUnit->insnsSize;
2090 cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
2091 }
2092 }
buzbee2cfc6392012-05-07 14:51:40 -07002093
buzbeead8f15e2012-06-18 14:49:45 -07002094 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
2095 // Write bitcode to file
2096 std::string errmsg;
2097 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
2098 oatReplaceSpecialChars(fname);
2099 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07002100 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002101
buzbeead8f15e2012-06-18 14:49:45 -07002102 llvm::OwningPtr<llvm::tool_output_file> out_file(
2103 new llvm::tool_output_file(fname.c_str(), errmsg,
2104 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002105
buzbeead8f15e2012-06-18 14:49:45 -07002106 if (!errmsg.empty()) {
2107 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2108 }
2109
2110 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
2111 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002112 }
buzbee2cfc6392012-05-07 14:51:40 -07002113}
2114
2115RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
2116 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002117 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002118 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2119 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07002120 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07002121 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002122 // FIXME: need to be more robust, handle FP and be in a position to
2123 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002124 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2125 memset(&res, 0, sizeof(res));
2126 res.location = kLocPhysReg;
2127 res.lowReg = oatAllocTemp(cUnit);
2128 res.home = true;
2129 res.sRegLow = INVALID_SREG;
2130 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002131 llvm::Type* ty = val->getType();
2132 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2133 (ty == cUnit->irb->getDoubleTy()));
2134 if (res.wide) {
2135 res.highReg = oatAllocTemp(cUnit);
2136 }
buzbee4f1181f2012-06-22 13:52:12 -07002137 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002138 } else {
2139 DCHECK_EQ(valName[0], 'v');
2140 int baseSReg = INVALID_SREG;
2141 sscanf(valName.c_str(), "v%d_", &baseSReg);
2142 res = cUnit->regLocation[baseSReg];
2143 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002144 }
2145 } else {
2146 res = it->second;
2147 }
2148 return res;
2149}
2150
2151Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
2152{
2153 Instruction::Code res = Instruction::NOP;
2154 if (isWide) {
2155 switch(op) {
2156 case kOpAdd: res = Instruction::ADD_LONG; break;
2157 case kOpSub: res = Instruction::SUB_LONG; break;
2158 case kOpMul: res = Instruction::MUL_LONG; break;
2159 case kOpDiv: res = Instruction::DIV_LONG; break;
2160 case kOpRem: res = Instruction::REM_LONG; break;
2161 case kOpAnd: res = Instruction::AND_LONG; break;
2162 case kOpOr: res = Instruction::OR_LONG; break;
2163 case kOpXor: res = Instruction::XOR_LONG; break;
2164 case kOpLsl: res = Instruction::SHL_LONG; break;
2165 case kOpLsr: res = Instruction::USHR_LONG; break;
2166 case kOpAsr: res = Instruction::SHR_LONG; break;
2167 default: LOG(FATAL) << "Unexpected OpKind " << op;
2168 }
2169 } else if (isConst){
2170 switch(op) {
2171 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2172 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2173 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2174 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2175 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2176 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2177 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2178 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2179 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2180 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2181 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2182 default: LOG(FATAL) << "Unexpected OpKind " << op;
2183 }
2184 } else {
2185 switch(op) {
2186 case kOpAdd: res = Instruction::ADD_INT; break;
2187 case kOpSub: res = Instruction::SUB_INT; break;
2188 case kOpMul: res = Instruction::MUL_INT; break;
2189 case kOpDiv: res = Instruction::DIV_INT; break;
2190 case kOpRem: res = Instruction::REM_INT; break;
2191 case kOpAnd: res = Instruction::AND_INT; break;
2192 case kOpOr: res = Instruction::OR_INT; break;
2193 case kOpXor: res = Instruction::XOR_INT; break;
2194 case kOpLsl: res = Instruction::SHL_INT; break;
2195 case kOpLsr: res = Instruction::USHR_INT; break;
2196 case kOpAsr: res = Instruction::SHR_INT; break;
2197 default: LOG(FATAL) << "Unexpected OpKind " << op;
2198 }
2199 }
2200 return res;
2201}
2202
buzbee4f1181f2012-06-22 13:52:12 -07002203Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2204{
2205 Instruction::Code res = Instruction::NOP;
2206 if (isWide) {
2207 switch(op) {
2208 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2209 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2210 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2211 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2212 case kOpRem: res = Instruction::REM_DOUBLE; break;
2213 default: LOG(FATAL) << "Unexpected OpKind " << op;
2214 }
2215 } else {
2216 switch(op) {
2217 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2218 case kOpSub: res = Instruction::SUB_FLOAT; break;
2219 case kOpMul: res = Instruction::MUL_FLOAT; break;
2220 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2221 case kOpRem: res = Instruction::REM_FLOAT; break;
2222 default: LOG(FATAL) << "Unexpected OpKind " << op;
2223 }
2224 }
2225 return res;
2226}
2227
2228void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2229{
2230 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002231 /*
2232 * Normally, we won't ever generate an FP operation with an immediate
2233 * operand (not supported in Dex instruction set). However, the IR builder
2234 * may insert them - in particular for createNegFP. Recognize this case
2235 * and deal with it.
2236 */
2237 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2238 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2239 DCHECK(op2C == NULL);
2240 if ((op1C != NULL) && (op == kOpSub)) {
2241 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2242 if (rlDest.wide) {
2243 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2244 } else {
2245 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2246 }
buzbee4f1181f2012-06-22 13:52:12 -07002247 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002248 DCHECK(op1C == NULL);
2249 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2250 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2251 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2252 if (rlDest.wide) {
2253 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2254 } else {
2255 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2256 }
buzbee4f1181f2012-06-22 13:52:12 -07002257 }
2258}
2259
buzbee101305f2012-06-28 18:00:56 -07002260void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2261 Instruction::Code opcode)
2262{
2263 RegLocation rlDest = getLoc(cUnit, inst);
2264 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2265 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2266}
2267
buzbee76592632012-06-29 15:18:35 -07002268void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2269{
2270 RegLocation rlDest = getLoc(cUnit, inst);
2271 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2272 Instruction::Code opcode;
2273 if (rlDest.wide) {
2274 if (rlSrc.wide) {
2275 opcode = Instruction::LONG_TO_DOUBLE;
2276 } else {
2277 opcode = Instruction::INT_TO_DOUBLE;
2278 }
2279 } else {
2280 if (rlSrc.wide) {
2281 opcode = Instruction::LONG_TO_FLOAT;
2282 } else {
2283 opcode = Instruction::INT_TO_FLOAT;
2284 }
2285 }
2286 genConversion(cUnit, opcode, rlDest, rlSrc);
2287}
2288
2289void cvtFPToInt(CompilationUnit* cUnit, llvm::Instruction* inst)
2290{
2291 RegLocation rlDest = getLoc(cUnit, inst);
2292 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2293 Instruction::Code opcode;
2294 if (rlDest.wide) {
2295 if (rlSrc.wide) {
2296 opcode = Instruction::DOUBLE_TO_LONG;
2297 } else {
2298 opcode = Instruction::FLOAT_TO_LONG;
2299 }
2300 } else {
2301 if (rlSrc.wide) {
2302 opcode = Instruction::DOUBLE_TO_INT;
2303 } else {
2304 opcode = Instruction::FLOAT_TO_INT;
2305 }
2306 }
2307 genConversion(cUnit, opcode, rlDest, rlSrc);
2308}
2309
2310void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2311{
2312 RegLocation rlDest = getLoc(cUnit, inst);
2313 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2314 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2315}
2316
2317void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2318{
2319 RegLocation rlDest = getLoc(cUnit, inst);
2320 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2321 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2322 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2323 storeValue(cUnit, rlDest, rlSrc);
2324}
2325
2326void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2327{
2328 RegLocation rlDest = getLoc(cUnit, inst);
2329 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2330 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2331}
2332
2333
buzbee101305f2012-06-28 18:00:56 -07002334void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2335{
2336 // TODO: evaluate src/tgt types and add general support for more than int to long
2337 RegLocation rlDest = getLoc(cUnit, inst);
2338 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2339 DCHECK(rlDest.wide);
2340 DCHECK(!rlSrc.wide);
2341 DCHECK(!rlDest.fp);
2342 DCHECK(!rlSrc.fp);
2343 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2344 if (rlSrc.location == kLocPhysReg) {
2345 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2346 } else {
2347 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2348 }
2349 if (isSigned) {
2350 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2351 } else {
2352 loadConstant(cUnit, rlResult.highReg, 0);
2353 }
2354 storeValueWide(cUnit, rlDest, rlResult);
2355}
2356
buzbee2cfc6392012-05-07 14:51:40 -07002357void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2358{
2359 RegLocation rlDest = getLoc(cUnit, inst);
2360 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002361 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002362 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2363 if ((op == kOpSub) && (lhsImm != NULL)) {
2364 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002365 if (rlSrc1.wide) {
2366 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2367 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2368 } else {
2369 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2370 lhsImm->getSExtValue());
2371 }
buzbee4f1181f2012-06-22 13:52:12 -07002372 return;
2373 }
2374 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002375 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2376 llvm::Value* rhs = inst->getOperand(1);
buzbee9a2487f2012-07-26 14:01:13 -07002377 llvm::ConstantInt* constRhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2378 if (!rlDest.wide && (constRhs != NULL)) {
buzbee2cfc6392012-05-07 14:51:40 -07002379 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
buzbee9a2487f2012-07-26 14:01:13 -07002380 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, constRhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002381 } else {
2382 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
buzbee9a2487f2012-07-26 14:01:13 -07002383 RegLocation rlSrc2;
2384 if (constRhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002385 // ir_builder converts NOT_LONG to xor src, -1. Restore
2386 DCHECK_EQ(dalvikOp, Instruction::XOR_LONG);
2387 DCHECK_EQ(-1L, constRhs->getSExtValue());
2388 dalvikOp = Instruction::NOT_LONG;
buzbee9a2487f2012-07-26 14:01:13 -07002389 rlSrc2 = rlSrc1;
2390 } else {
2391 rlSrc2 = getLoc(cUnit, rhs);
2392 }
buzbee2cfc6392012-05-07 14:51:40 -07002393 if (rlDest.wide) {
2394 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2395 } else {
2396 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2397 }
2398 }
2399}
2400
buzbee2a83e8f2012-07-13 16:42:30 -07002401void cvtShiftOp(CompilationUnit* cUnit, Instruction::Code opcode,
2402 llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002403{
buzbee2a83e8f2012-07-13 16:42:30 -07002404 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2405 RegLocation rlDest = getLoc(cUnit, callInst);
2406 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2407 llvm::Value* rhs = callInst->getArgOperand(1);
2408 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2409 DCHECK(!rlDest.wide);
2410 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002411 } else {
buzbee2a83e8f2012-07-13 16:42:30 -07002412 RegLocation rlShift = getLoc(cUnit, rhs);
2413 if (callInst->getType() == cUnit->irb->getInt64Ty()) {
2414 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2415 } else {
2416 genArithOpInt(cUnit, opcode, rlDest, rlSrc, rlShift);
2417 }
buzbee101305f2012-06-28 18:00:56 -07002418 }
2419}
2420
buzbee2cfc6392012-05-07 14:51:40 -07002421void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2422{
2423 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2424 DCHECK(brInst != NULL);
2425 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2426 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2427 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2428}
2429
2430void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2431{
2432 // Nop - these have already been processed
2433}
2434
2435void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2436{
2437 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2438 llvm::Value* retVal = retInst->getReturnValue();
2439 if (retVal != NULL) {
2440 RegLocation rlSrc = getLoc(cUnit, retVal);
2441 if (rlSrc.wide) {
2442 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2443 } else {
2444 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2445 }
2446 }
2447 genExitSequence(cUnit);
2448}
2449
2450ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2451{
2452 ConditionCode res = kCondAl;
2453 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002454 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002455 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2456 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2457 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002458 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002459 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002460 default: LOG(FATAL) << "Unexpected llvm condition";
2461 }
2462 return res;
2463}
2464
2465void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2466{
2467 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2468 UNIMPLEMENTED(FATAL);
2469}
2470
2471void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2472 llvm::BranchInst* brInst)
2473{
2474 // Get targets
2475 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2476 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2477 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2478 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2479 // Get comparison operands
2480 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2481 ConditionCode cond = getCond(iCmpInst->getPredicate());
2482 llvm::Value* lhs = iCmpInst->getOperand(0);
2483 // Not expecting a constant as 1st operand
2484 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2485 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2486 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2487 llvm::Value* rhs = inst->getOperand(1);
2488#if defined(TARGET_MIPS)
2489 // Compare and branch in one shot
2490 (void)taken;
2491 (void)cond;
2492 (void)rhs;
2493 UNIMPLEMENTED(FATAL);
2494#else
2495 //Compare, then branch
2496 // TODO: handle fused CMP_LONG/IF_xxZ case
2497 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2498 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002499 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
2500 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002501 } else {
2502 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2503 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2504 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2505 }
2506 opCondBranch(cUnit, cond, taken);
2507#endif
2508 // Fallthrough
2509 opUnconditionalBranch(cUnit, fallThrough);
2510}
2511
2512void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2513 llvm::Function* callee)
2514{
2515 UNIMPLEMENTED(FATAL);
2516}
2517
buzbee2cfc6392012-05-07 14:51:40 -07002518void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2519{
buzbee4f1181f2012-06-22 13:52:12 -07002520 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002521 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2522 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002523 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2524 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002525 if (rlSrc.wide) {
2526 storeValueWide(cUnit, rlDest, rlSrc);
2527 } else {
2528 storeValue(cUnit, rlDest, rlSrc);
2529 }
2530}
2531
2532// Note: Immediate arg is a ConstantInt regardless of result type
2533void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2534{
buzbee4f1181f2012-06-22 13:52:12 -07002535 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002536 llvm::ConstantInt* src =
2537 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2538 uint64_t immval = src->getZExtValue();
2539 RegLocation rlDest = getLoc(cUnit, callInst);
2540 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2541 if (rlDest.wide) {
2542 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2543 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2544 storeValueWide(cUnit, rlDest, rlResult);
2545 } else {
2546 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2547 storeValue(cUnit, rlDest, rlResult);
2548 }
2549}
2550
buzbee101305f2012-06-28 18:00:56 -07002551void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2552 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002553{
buzbee4f1181f2012-06-22 13:52:12 -07002554 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002555 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002556 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002557 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002558 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002559 if (isString) {
2560 genConstString(cUnit, index, rlDest);
2561 } else {
2562 genConstClass(cUnit, index, rlDest);
2563 }
2564}
2565
2566void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2567{
2568 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2569 llvm::ConstantInt* offsetVal =
2570 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2571 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2572 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002573}
2574
buzbee4f1181f2012-06-22 13:52:12 -07002575void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2576{
buzbee32412962012-06-26 16:27:56 -07002577 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002578 llvm::ConstantInt* typeIdxVal =
2579 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2580 uint32_t typeIdx = typeIdxVal->getZExtValue();
2581 RegLocation rlDest = getLoc(cUnit, callInst);
2582 genNewInstance(cUnit, typeIdx, rlDest);
2583}
2584
buzbee8fa0fda2012-06-27 15:44:52 -07002585void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2586{
2587 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2588 llvm::ConstantInt* typeIdxVal =
2589 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2590 uint32_t typeIdx = typeIdxVal->getZExtValue();
2591 llvm::Value* len = callInst->getArgOperand(1);
2592 RegLocation rlLen = getLoc(cUnit, len);
2593 RegLocation rlDest = getLoc(cUnit, callInst);
2594 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2595}
2596
2597void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2598{
2599 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2600 llvm::ConstantInt* typeIdxVal =
2601 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2602 uint32_t typeIdx = typeIdxVal->getZExtValue();
2603 llvm::Value* src = callInst->getArgOperand(1);
2604 RegLocation rlSrc = getLoc(cUnit, src);
2605 RegLocation rlDest = getLoc(cUnit, callInst);
2606 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2607}
2608
buzbee32412962012-06-26 16:27:56 -07002609void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2610{
2611 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2612 llvm::Value* src = callInst->getArgOperand(0);
2613 RegLocation rlSrc = getLoc(cUnit, src);
2614 genThrow(cUnit, rlSrc);
2615}
2616
buzbee8fa0fda2012-06-27 15:44:52 -07002617void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2618 llvm::CallInst* callInst)
2619{
2620 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2621 llvm::ConstantInt* optFlags =
2622 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2623 llvm::Value* src = callInst->getArgOperand(1);
2624 RegLocation rlSrc = getLoc(cUnit, src);
2625 if (isEnter) {
2626 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2627 } else {
2628 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2629 }
2630}
2631
buzbee76592632012-06-29 15:18:35 -07002632void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002633{
2634 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2635 llvm::ConstantInt* optFlags =
2636 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2637 llvm::Value* src = callInst->getArgOperand(1);
2638 RegLocation rlSrc = getLoc(cUnit, src);
2639 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2640 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2641 RegLocation rlDest = getLoc(cUnit, callInst);
2642 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2643 int lenOffset = Array::LengthOffset().Int32Value();
2644 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2645 storeValue(cUnit, rlDest, rlResult);
2646}
2647
buzbee32412962012-06-26 16:27:56 -07002648void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2649{
2650 DCHECK_EQ(callInst->getNumArgOperands(), 0U);
2651 int exOffset = Thread::ExceptionOffset().Int32Value();
2652 RegLocation rlDest = getLoc(cUnit, callInst);
2653 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2654#if defined(TARGET_X86)
2655 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
2656 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
2657#else
2658 int resetReg = oatAllocTemp(cUnit);
2659 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
2660 loadConstant(cUnit, resetReg, 0);
2661 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
2662 oatFreeTemp(cUnit, resetReg);
2663#endif
2664 storeValue(cUnit, rlDest, rlResult);
2665}
2666
buzbee4f1181f2012-06-22 13:52:12 -07002667void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2668 bool isObject)
2669{
buzbee32412962012-06-26 16:27:56 -07002670 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002671 llvm::ConstantInt* typeIdxVal =
2672 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2673 uint32_t typeIdx = typeIdxVal->getZExtValue();
2674 RegLocation rlDest = getLoc(cUnit, callInst);
2675 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2676}
2677
buzbee8fa0fda2012-06-27 15:44:52 -07002678void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2679 bool isObject)
2680{
2681 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2682 llvm::ConstantInt* typeIdxVal =
2683 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2684 uint32_t typeIdx = typeIdxVal->getZExtValue();
2685 llvm::Value* src = callInst->getArgOperand(1);
2686 RegLocation rlSrc = getLoc(cUnit, src);
2687 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2688}
2689
2690void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2691 int scale)
2692{
2693 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2694 llvm::ConstantInt* optFlags =
2695 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2696 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2697 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2698 RegLocation rlDest = getLoc(cUnit, callInst);
2699 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2700 rlDest, scale);
2701}
2702
2703void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002704 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002705{
2706 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2707 llvm::ConstantInt* optFlags =
2708 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2709 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2710 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2711 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002712 if (isObject) {
2713 genArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
2714 rlSrc, scale);
2715 } else {
2716 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2717 rlSrc, scale);
2718 }
2719}
2720
2721void cvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
2722{
2723 cvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
2724}
2725
2726void cvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
2727 OpSize size, int scale)
2728{
2729 cvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002730}
2731
buzbee101305f2012-06-28 18:00:56 -07002732void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2733 bool isWide, bool isObj)
2734{
2735 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2736 llvm::ConstantInt* optFlags =
2737 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2738 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2739 llvm::ConstantInt* fieldIdx =
2740 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2741 RegLocation rlDest = getLoc(cUnit, callInst);
2742 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2743 size, rlDest, rlObj, isWide, isObj);
2744}
2745
2746void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2747 bool isWide, bool isObj)
2748{
2749 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2750 llvm::ConstantInt* optFlags =
2751 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2752 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2753 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2754 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002755 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002756 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2757 size, rlSrc, rlObj, isWide, isObj);
2758}
2759
2760void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2761{
2762 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2763 llvm::ConstantInt* typeIdx =
2764 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2765 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2766 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2767}
2768
buzbee76592632012-06-29 15:18:35 -07002769void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2770 Instruction::Code opcode)
2771{
2772 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2773 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2774 RegLocation rlDest = getLoc(cUnit, callInst);
2775 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2776}
2777
2778void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2779{
2780 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2781 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2782 RegLocation rlDest = getLoc(cUnit, callInst);
2783 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2784}
2785
buzbeef58c12c2012-07-03 15:06:29 -07002786void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2787{
2788 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2789 DCHECK(swInst != NULL);
2790 llvm::Value* testVal = swInst->getCondition();
2791 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2792 DCHECK(tableOffsetNode != NULL);
2793 llvm::ConstantInt* tableOffsetValue =
2794 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2795 int32_t tableOffset = tableOffsetValue->getSExtValue();
2796 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeea1da8a52012-07-09 14:00:21 -07002797 const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2798 u2 tableMagic = *table;
2799 if (tableMagic == 0x100) {
2800 genPackedSwitch(cUnit, tableOffset, rlSrc);
2801 } else {
2802 DCHECK_EQ(tableMagic, 0x200);
2803 genSparseSwitch(cUnit, tableOffset, rlSrc);
2804 }
buzbeef58c12c2012-07-03 15:06:29 -07002805}
2806
buzbee6969d502012-06-15 16:40:31 -07002807void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002808 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002809{
2810 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2811 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002812 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002813 info->result.location = kLocInvalid;
2814 } else {
2815 info->result = getLoc(cUnit, callInst);
2816 }
2817 llvm::ConstantInt* invokeTypeVal =
2818 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2819 llvm::ConstantInt* methodIndexVal =
2820 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2821 llvm::ConstantInt* optFlagsVal =
2822 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2823 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2824 info->index = methodIndexVal->getZExtValue();
2825 info->optFlags = optFlagsVal->getZExtValue();
2826 info->offset = cUnit->currentDalvikOffset;
2827
buzbee6969d502012-06-15 16:40:31 -07002828 // Count the argument words, and then build argument array.
2829 info->numArgWords = 0;
2830 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2831 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2832 info->numArgWords += tLoc.wide ? 2 : 1;
2833 }
2834 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2835 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2836 // Now, fill in the location records, synthesizing high loc of wide vals
2837 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002838 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002839 if (info->args[next].wide) {
2840 next++;
2841 // TODO: Might make sense to mark this as an invalid loc
2842 info->args[next].origSReg = info->args[next-1].origSReg+1;
2843 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2844 }
2845 next++;
2846 }
buzbee4f4dfc72012-07-02 14:54:44 -07002847 // TODO - rework such that we no longer need isRange
2848 info->isRange = (info->numArgWords > 5);
2849
buzbee76592632012-06-29 15:18:35 -07002850 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002851 genFilledNewArray(cUnit, info);
2852 } else {
2853 genInvoke(cUnit, info);
2854 }
buzbee6969d502012-06-15 16:40:31 -07002855}
2856
buzbeead8f15e2012-06-18 14:49:45 -07002857/* Look up the RegLocation associated with a Value. Must already be defined */
2858RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2859{
2860 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2861 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2862 return it->second;
2863}
2864
buzbee2cfc6392012-05-07 14:51:40 -07002865bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2866{
2867 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2868 // Define the starting label
2869 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2870 // Extract the starting offset from the block's name
2871 if (!isEntry) {
2872 const char* blockName = bb->getName().str().c_str();
2873 int dummy;
Elliott Hughes74847412012-06-20 18:10:21 -07002874 sscanf(blockName, kLabelFormat, &blockLabel->operands[0], &dummy);
buzbee2cfc6392012-05-07 14:51:40 -07002875 }
2876 // Set the label kind
2877 blockLabel->opcode = kPseudoNormalBlockLabel;
2878 // Insert the label
2879 oatAppendLIR(cUnit, blockLabel);
2880
2881 // Free temp registers and reset redundant store tracking */
2882 oatResetRegPool(cUnit);
2883 oatResetDefTracking(cUnit);
2884
2885 //TODO: restore oat incoming liveness optimization
2886 oatClobberAllRegs(cUnit);
2887
buzbee6969d502012-06-15 16:40:31 -07002888 LIR* headLIR = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07002889
2890 if (isEntry) {
2891 cUnit->currentDalvikOffset = 0;
buzbeead8f15e2012-06-18 14:49:45 -07002892 RegLocation* argLocs = (RegLocation*)
2893 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2894 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2895 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
buzbeeca7a5e42012-08-20 11:12:18 -07002896 // Skip past Method*
2897 it++;
buzbeead8f15e2012-06-18 14:49:45 -07002898 for (unsigned i = 0; it != it_end; ++it) {
2899 llvm::Value* val = it;
2900 argLocs[i++] = valToLoc(cUnit, val);
2901 llvm::Type* ty = val->getType();
2902 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
buzbeeca7a5e42012-08-20 11:12:18 -07002903 argLocs[i] = argLocs[i-1];
2904 argLocs[i].lowReg = argLocs[i].highReg;
2905 argLocs[i].origSReg++;
2906 argLocs[i].sRegLow = INVALID_SREG;
2907 argLocs[i].highWord = true;
2908 i++;
buzbeead8f15e2012-06-18 14:49:45 -07002909 }
2910 }
2911 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
buzbee2cfc6392012-05-07 14:51:40 -07002912 }
2913
2914 // Visit all of the instructions in the block
2915 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2916 llvm::Instruction* inst = it;
2917 llvm::BasicBlock::iterator nextIt = ++it;
2918 // Extract the Dalvik offset from the instruction
2919 uint32_t opcode = inst->getOpcode();
2920 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2921 if (dexOffsetNode != NULL) {
2922 llvm::ConstantInt* dexOffsetValue =
2923 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2924 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2925 }
2926
buzbee6969d502012-06-15 16:40:31 -07002927 oatResetRegPool(cUnit);
2928 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2929 oatClobberAllRegs(cUnit);
2930 }
2931
2932 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2933 oatResetDefTracking(cUnit);
2934 }
2935
2936#ifndef NDEBUG
2937 /* Reset temp tracking sanity check */
2938 cUnit->liveSReg = INVALID_SREG;
2939#endif
2940
2941 LIR* boundaryLIR;
2942 const char* instStr = "boundary";
2943 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
2944 (intptr_t) instStr);
2945 cUnit->boundaryMap.Overwrite(cUnit->currentDalvikOffset, boundaryLIR);
2946
2947 /* Remember the first LIR for thisl block*/
2948 if (headLIR == NULL) {
2949 headLIR = boundaryLIR;
2950 headLIR->defMask = ENCODE_ALL;
2951 }
2952
buzbee2cfc6392012-05-07 14:51:40 -07002953 switch(opcode) {
2954
2955 case llvm::Instruction::ICmp: {
2956 llvm::Instruction* nextInst = nextIt;
2957 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2958 if (brInst != NULL /* and... */) {
2959 cvtICmpBr(cUnit, inst, brInst);
2960 ++it;
2961 } else {
2962 cvtICmp(cUnit, inst);
2963 }
2964 }
2965 break;
2966
2967 case llvm::Instruction::Call: {
2968 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2969 llvm::Function* callee = callInst->getCalledFunction();
2970 greenland::IntrinsicHelper::IntrinsicId id =
2971 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2972 switch (id) {
buzbeeb03f4872012-06-11 15:22:11 -07002973 case greenland::IntrinsicHelper::AllocaShadowFrame:
2974 case greenland::IntrinsicHelper::SetShadowFrameEntry:
buzbee6969d502012-06-15 16:40:31 -07002975 case greenland::IntrinsicHelper::PopShadowFrame:
buzbeeb03f4872012-06-11 15:22:11 -07002976 // Ignore shadow frame stuff for quick compiler
2977 break;
buzbee2cfc6392012-05-07 14:51:40 -07002978 case greenland::IntrinsicHelper::CopyInt:
2979 case greenland::IntrinsicHelper::CopyObj:
2980 case greenland::IntrinsicHelper::CopyFloat:
2981 case greenland::IntrinsicHelper::CopyLong:
2982 case greenland::IntrinsicHelper::CopyDouble:
2983 cvtCopy(cUnit, callInst);
2984 break;
2985 case greenland::IntrinsicHelper::ConstInt:
2986 case greenland::IntrinsicHelper::ConstObj:
2987 case greenland::IntrinsicHelper::ConstLong:
2988 case greenland::IntrinsicHelper::ConstFloat:
2989 case greenland::IntrinsicHelper::ConstDouble:
2990 cvtConst(cUnit, callInst);
2991 break;
buzbee4f1181f2012-06-22 13:52:12 -07002992 case greenland::IntrinsicHelper::DivInt:
2993 case greenland::IntrinsicHelper::DivLong:
2994 cvtBinOp(cUnit, kOpDiv, inst);
2995 break;
2996 case greenland::IntrinsicHelper::RemInt:
2997 case greenland::IntrinsicHelper::RemLong:
2998 cvtBinOp(cUnit, kOpRem, inst);
2999 break;
buzbee2cfc6392012-05-07 14:51:40 -07003000 case greenland::IntrinsicHelper::MethodInfo:
buzbeead8f15e2012-06-18 14:49:45 -07003001 // Already dealt with - just ignore it here.
buzbee2cfc6392012-05-07 14:51:40 -07003002 break;
3003 case greenland::IntrinsicHelper::CheckSuspend:
3004 genSuspendTest(cUnit, 0 /* optFlags already applied */);
3005 break;
buzbee4f1181f2012-06-22 13:52:12 -07003006 case greenland::IntrinsicHelper::HLInvokeObj:
buzbee8fa0fda2012-06-27 15:44:52 -07003007 case greenland::IntrinsicHelper::HLInvokeFloat:
3008 case greenland::IntrinsicHelper::HLInvokeDouble:
3009 case greenland::IntrinsicHelper::HLInvokeLong:
3010 case greenland::IntrinsicHelper::HLInvokeInt:
buzbee101305f2012-06-28 18:00:56 -07003011 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
buzbee4f1181f2012-06-22 13:52:12 -07003012 break;
buzbee6969d502012-06-15 16:40:31 -07003013 case greenland::IntrinsicHelper::HLInvokeVoid:
buzbee101305f2012-06-28 18:00:56 -07003014 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
3015 break;
3016 case greenland::IntrinsicHelper::FilledNewArray:
3017 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
3018 break;
3019 case greenland::IntrinsicHelper::FillArrayData:
3020 cvtFillArrayData(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07003021 break;
3022 case greenland::IntrinsicHelper::ConstString:
buzbee101305f2012-06-28 18:00:56 -07003023 cvtConstObject(cUnit, callInst, true /* isString */);
3024 break;
3025 case greenland::IntrinsicHelper::ConstClass:
3026 cvtConstObject(cUnit, callInst, false /* isString */);
3027 break;
3028 case greenland::IntrinsicHelper::CheckCast:
3029 cvtCheckCast(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07003030 break;
buzbee4f1181f2012-06-22 13:52:12 -07003031 case greenland::IntrinsicHelper::NewInstance:
3032 cvtNewInstance(cUnit, callInst);
3033 break;
buzbee8fa0fda2012-06-27 15:44:52 -07003034 case greenland::IntrinsicHelper::HLSgetObject:
buzbee4f1181f2012-06-22 13:52:12 -07003035 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
3036 break;
buzbee8fa0fda2012-06-27 15:44:52 -07003037 case greenland::IntrinsicHelper::HLSget:
3038 case greenland::IntrinsicHelper::HLSgetFloat:
3039 case greenland::IntrinsicHelper::HLSgetBoolean:
3040 case greenland::IntrinsicHelper::HLSgetByte:
3041 case greenland::IntrinsicHelper::HLSgetChar:
3042 case greenland::IntrinsicHelper::HLSgetShort:
3043 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
3044 break;
3045 case greenland::IntrinsicHelper::HLSgetWide:
3046 case greenland::IntrinsicHelper::HLSgetDouble:
3047 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
3048 break;
buzbee76592632012-06-29 15:18:35 -07003049 case greenland::IntrinsicHelper::HLSput:
3050 case greenland::IntrinsicHelper::HLSputFloat:
3051 case greenland::IntrinsicHelper::HLSputBoolean:
3052 case greenland::IntrinsicHelper::HLSputByte:
3053 case greenland::IntrinsicHelper::HLSputChar:
3054 case greenland::IntrinsicHelper::HLSputShort:
3055 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
3056 break;
3057 case greenland::IntrinsicHelper::HLSputWide:
3058 case greenland::IntrinsicHelper::HLSputDouble:
3059 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
3060 break;
buzbeea1da8a52012-07-09 14:00:21 -07003061 case greenland::IntrinsicHelper::HLSputObject:
3062 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
3063 break;
buzbee32412962012-06-26 16:27:56 -07003064 case greenland::IntrinsicHelper::GetException:
3065 cvtMoveException(cUnit, callInst);
3066 break;
3067 case greenland::IntrinsicHelper::Throw:
3068 cvtThrow(cUnit, callInst);
3069 break;
buzbee8fa0fda2012-06-27 15:44:52 -07003070 case greenland::IntrinsicHelper::MonitorEnter:
3071 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
3072 break;
3073 case greenland::IntrinsicHelper::MonitorExit:
3074 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
3075 break;
3076 case greenland::IntrinsicHelper::ArrayLength:
buzbee76592632012-06-29 15:18:35 -07003077 cvtArrayLength(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07003078 break;
3079 case greenland::IntrinsicHelper::NewArray:
3080 cvtNewArray(cUnit, callInst);
3081 break;
3082 case greenland::IntrinsicHelper::InstanceOf:
3083 cvtInstanceOf(cUnit, callInst);
3084 break;
3085
3086 case greenland::IntrinsicHelper::HLArrayGet:
3087 case greenland::IntrinsicHelper::HLArrayGetObject:
3088 case greenland::IntrinsicHelper::HLArrayGetFloat:
3089 cvtAget(cUnit, callInst, kWord, 2);
3090 break;
3091 case greenland::IntrinsicHelper::HLArrayGetWide:
3092 case greenland::IntrinsicHelper::HLArrayGetDouble:
3093 cvtAget(cUnit, callInst, kLong, 3);
3094 break;
3095 case greenland::IntrinsicHelper::HLArrayGetBoolean:
3096 cvtAget(cUnit, callInst, kUnsignedByte, 0);
3097 break;
3098 case greenland::IntrinsicHelper::HLArrayGetByte:
3099 cvtAget(cUnit, callInst, kSignedByte, 0);
3100 break;
3101 case greenland::IntrinsicHelper::HLArrayGetChar:
3102 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
3103 break;
3104 case greenland::IntrinsicHelper::HLArrayGetShort:
3105 cvtAget(cUnit, callInst, kSignedHalf, 1);
3106 break;
3107
3108 case greenland::IntrinsicHelper::HLArrayPut:
buzbee8fa0fda2012-06-27 15:44:52 -07003109 case greenland::IntrinsicHelper::HLArrayPutFloat:
buzbeef1f86362012-07-10 15:18:31 -07003110 cvtAputPrimitive(cUnit, callInst, kWord, 2);
3111 break;
3112 case greenland::IntrinsicHelper::HLArrayPutObject:
3113 cvtAputObj(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07003114 break;
3115 case greenland::IntrinsicHelper::HLArrayPutWide:
3116 case greenland::IntrinsicHelper::HLArrayPutDouble:
buzbeef1f86362012-07-10 15:18:31 -07003117 cvtAputPrimitive(cUnit, callInst, kLong, 3);
buzbee8fa0fda2012-06-27 15:44:52 -07003118 break;
3119 case greenland::IntrinsicHelper::HLArrayPutBoolean:
buzbeef1f86362012-07-10 15:18:31 -07003120 cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
buzbee8fa0fda2012-06-27 15:44:52 -07003121 break;
3122 case greenland::IntrinsicHelper::HLArrayPutByte:
buzbeef1f86362012-07-10 15:18:31 -07003123 cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
buzbee8fa0fda2012-06-27 15:44:52 -07003124 break;
3125 case greenland::IntrinsicHelper::HLArrayPutChar:
buzbeef1f86362012-07-10 15:18:31 -07003126 cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
buzbee8fa0fda2012-06-27 15:44:52 -07003127 break;
3128 case greenland::IntrinsicHelper::HLArrayPutShort:
buzbeef1f86362012-07-10 15:18:31 -07003129 cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
buzbee8fa0fda2012-06-27 15:44:52 -07003130 break;
3131
buzbee101305f2012-06-28 18:00:56 -07003132 case greenland::IntrinsicHelper::HLIGet:
3133 case greenland::IntrinsicHelper::HLIGetFloat:
3134 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3135 break;
3136 case greenland::IntrinsicHelper::HLIGetObject:
3137 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3138 break;
3139 case greenland::IntrinsicHelper::HLIGetWide:
3140 case greenland::IntrinsicHelper::HLIGetDouble:
3141 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3142 break;
3143 case greenland::IntrinsicHelper::HLIGetBoolean:
3144 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
3145 false /* obj */);
3146 break;
3147 case greenland::IntrinsicHelper::HLIGetByte:
3148 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
3149 false /* obj */);
3150 break;
3151 case greenland::IntrinsicHelper::HLIGetChar:
3152 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3153 false /* obj */);
3154 break;
3155 case greenland::IntrinsicHelper::HLIGetShort:
3156 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
3157 false /* obj */);
3158 break;
3159
3160 case greenland::IntrinsicHelper::HLIPut:
3161 case greenland::IntrinsicHelper::HLIPutFloat:
3162 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3163 break;
3164 case greenland::IntrinsicHelper::HLIPutObject:
3165 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3166 break;
3167 case greenland::IntrinsicHelper::HLIPutWide:
3168 case greenland::IntrinsicHelper::HLIPutDouble:
3169 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3170 break;
3171 case greenland::IntrinsicHelper::HLIPutBoolean:
3172 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3173 false /* obj */);
3174 break;
3175 case greenland::IntrinsicHelper::HLIPutByte:
3176 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3177 false /* obj */);
3178 break;
3179 case greenland::IntrinsicHelper::HLIPutChar:
3180 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3181 false /* obj */);
3182 break;
3183 case greenland::IntrinsicHelper::HLIPutShort:
3184 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3185 false /* obj */);
3186 break;
3187
3188 case greenland::IntrinsicHelper::IntToChar:
3189 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3190 break;
3191 case greenland::IntrinsicHelper::IntToShort:
3192 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3193 break;
3194 case greenland::IntrinsicHelper::IntToByte:
3195 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3196 break;
3197
buzbee76592632012-06-29 15:18:35 -07003198 case greenland::IntrinsicHelper::CmplFloat:
3199 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3200 break;
3201 case greenland::IntrinsicHelper::CmpgFloat:
3202 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3203 break;
3204 case greenland::IntrinsicHelper::CmplDouble:
3205 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3206 break;
3207 case greenland::IntrinsicHelper::CmpgDouble:
3208 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3209 break;
3210
3211 case greenland::IntrinsicHelper::CmpLong:
3212 cvtLongCompare(cUnit, callInst);
3213 break;
3214
buzbee2a83e8f2012-07-13 16:42:30 -07003215 case greenland::IntrinsicHelper::SHLLong:
3216 cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
buzbee2cfc6392012-05-07 14:51:40 -07003217 break;
buzbee2a83e8f2012-07-13 16:42:30 -07003218 case greenland::IntrinsicHelper::SHRLong:
3219 cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
3220 break;
3221 case greenland::IntrinsicHelper::USHRLong:
3222 cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
3223 break;
3224 case greenland::IntrinsicHelper::SHLInt:
3225 cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
3226 break;
3227 case greenland::IntrinsicHelper::SHRInt:
3228 cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
3229 break;
3230 case greenland::IntrinsicHelper::USHRInt:
3231 cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
3232 break;
3233
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07003234 case greenland::IntrinsicHelper::CatchTargets: {
3235 llvm::SwitchInst* swInst =
3236 llvm::dyn_cast<llvm::SwitchInst>(nextIt);
3237 DCHECK(swInst != NULL);
3238 /*
3239 * Discard the edges and the following conditional branch.
3240 * Do a direct branch to the default target (which is the
3241 * "work" portion of the pair.
3242 * TODO: awful code layout - rework
3243 */
3244 llvm::BasicBlock* targetBB = swInst->getDefaultDest();
3245 DCHECK(targetBB != NULL);
3246 opUnconditionalBranch(cUnit,
3247 cUnit->blockToLabelMap.Get(targetBB));
3248 ++it;
3249 }
3250 break;
3251
buzbee2cfc6392012-05-07 14:51:40 -07003252 default:
3253 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
3254 << cUnit->intrinsic_helper->GetName(id);
3255 }
3256 }
3257 break;
3258
3259 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3260 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3261 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3262 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3263 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3264 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3265 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3266 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3267 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003268 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3269 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
buzbee4f1181f2012-06-22 13:52:12 -07003270 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3271 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3272 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3273 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3274 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
buzbee76592632012-06-29 15:18:35 -07003275 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
3276 case llvm::Instruction::FPToSI: cvtFPToInt(cUnit, inst); break;
3277 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3278 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3279 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003280
buzbee101305f2012-06-28 18:00:56 -07003281 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3282 break;
3283 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3284 break;
3285
buzbeef58c12c2012-07-03 15:06:29 -07003286 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3287
buzbee32412962012-06-26 16:27:56 -07003288 case llvm::Instruction::Unreachable:
3289 break; // FIXME: can we really ignore these?
3290
buzbee2a83e8f2012-07-13 16:42:30 -07003291 case llvm::Instruction::Shl:
3292 case llvm::Instruction::LShr:
3293 case llvm::Instruction::AShr:
buzbee2cfc6392012-05-07 14:51:40 -07003294 case llvm::Instruction::Invoke:
buzbee2cfc6392012-05-07 14:51:40 -07003295 case llvm::Instruction::FPToUI:
buzbee2cfc6392012-05-07 14:51:40 -07003296 case llvm::Instruction::UIToFP:
buzbee2cfc6392012-05-07 14:51:40 -07003297 case llvm::Instruction::PtrToInt:
3298 case llvm::Instruction::IntToPtr:
buzbee2cfc6392012-05-07 14:51:40 -07003299 case llvm::Instruction::FCmp:
buzbee2cfc6392012-05-07 14:51:40 -07003300 case llvm::Instruction::URem:
3301 case llvm::Instruction::UDiv:
3302 case llvm::Instruction::Resume:
buzbee2cfc6392012-05-07 14:51:40 -07003303 case llvm::Instruction::Alloca:
3304 case llvm::Instruction::GetElementPtr:
3305 case llvm::Instruction::Fence:
3306 case llvm::Instruction::AtomicCmpXchg:
3307 case llvm::Instruction::AtomicRMW:
3308 case llvm::Instruction::BitCast:
3309 case llvm::Instruction::VAArg:
3310 case llvm::Instruction::Select:
3311 case llvm::Instruction::UserOp1:
3312 case llvm::Instruction::UserOp2:
3313 case llvm::Instruction::ExtractElement:
3314 case llvm::Instruction::InsertElement:
3315 case llvm::Instruction::ShuffleVector:
3316 case llvm::Instruction::ExtractValue:
3317 case llvm::Instruction::InsertValue:
3318 case llvm::Instruction::LandingPad:
3319 case llvm::Instruction::IndirectBr:
3320 case llvm::Instruction::Load:
3321 case llvm::Instruction::Store:
3322 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3323
3324 default:
buzbee2a83e8f2012-07-13 16:42:30 -07003325 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3326 break;
buzbee2cfc6392012-05-07 14:51:40 -07003327 }
3328 }
buzbee6969d502012-06-15 16:40:31 -07003329
3330 if (headLIR != NULL) {
3331 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
3332 }
buzbee2cfc6392012-05-07 14:51:40 -07003333 return false;
3334}
3335
3336/*
3337 * Convert LLVM_IR to MIR:
3338 * o Iterate through the LLVM_IR and construct a graph using
3339 * standard MIR building blocks.
3340 * o Perform a basic-block optimization pass to remove unnecessary
3341 * store/load sequences.
3342 * o Convert the LLVM Value operands into RegLocations where applicable.
3343 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3344 * o Perform register promotion
3345 * o Iterate through the graph a basic block at a time, generating
3346 * LIR.
3347 * o Assemble LIR as usual.
3348 * o Profit.
3349 */
3350void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3351{
buzbeead8f15e2012-06-18 14:49:45 -07003352 llvm::Function* func = cUnit->func;
3353 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003354 // Allocate a list for LIR basic block labels
3355 cUnit->blockLabelList =
buzbeea1da8a52012-07-09 14:00:21 -07003356 (LIR*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3357 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003358 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003359 for (llvm::Function::iterator i = func->begin(),
3360 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003361 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3362 &labelList[nextLabel++]);
3363 }
buzbeead8f15e2012-06-18 14:49:45 -07003364
3365 /*
3366 * Keep honest - clear regLocations, Value => RegLocation,
3367 * promotion map and VmapTables.
3368 */
3369 cUnit->locMap.clear(); // Start fresh
3370 cUnit->regLocation = NULL;
3371 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3372 i++) {
3373 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3374 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3375 }
3376 cUnit->coreSpillMask = 0;
3377 cUnit->numCoreSpills = 0;
3378 cUnit->fpSpillMask = 0;
3379 cUnit->numFPSpills = 0;
3380 cUnit->coreVmapTable.clear();
3381 cUnit->fpVmapTable.clear();
buzbeead8f15e2012-06-18 14:49:45 -07003382
3383 /*
3384 * At this point, we've lost all knowledge of register promotion.
3385 * Rebuild that info from the MethodInfo intrinsic (if it
buzbeeca7a5e42012-08-20 11:12:18 -07003386 * exists - not required for correctness). Normally, this will
3387 * be the first instruction we encounter, so we won't have to iterate
3388 * through everything.
buzbeead8f15e2012-06-18 14:49:45 -07003389 */
buzbeeca7a5e42012-08-20 11:12:18 -07003390 for (llvm::inst_iterator i = llvm::inst_begin(func),
3391 e = llvm::inst_end(func); i != e; ++i) {
3392 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(&*i);
3393 if (callInst != NULL) {
3394 llvm::Function* callee = callInst->getCalledFunction();
3395 greenland::IntrinsicHelper::IntrinsicId id =
3396 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3397 if (id == greenland::IntrinsicHelper::MethodInfo) {
3398 if (cUnit->printMe) {
3399 LOG(INFO) << "Found MethodInfo";
3400 }
3401 llvm::MDNode* regInfoNode = callInst->getMetadata("RegInfo");
3402 if (regInfoNode != NULL) {
3403 llvm::ConstantInt* numInsValue =
3404 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(0));
3405 llvm::ConstantInt* numRegsValue =
3406 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(1));
3407 llvm::ConstantInt* numOutsValue =
3408 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(2));
3409 llvm::ConstantInt* numCompilerTempsValue =
3410 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(3));
3411 llvm::ConstantInt* numSSARegsValue =
3412 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(4));
3413 if (cUnit->printMe) {
3414 LOG(INFO) << "RegInfo - Ins:" << numInsValue->getZExtValue()
3415 << ", Regs:" << numRegsValue->getZExtValue()
3416 << ", Outs:" << numOutsValue->getZExtValue()
3417 << ", CTemps:" << numCompilerTempsValue->getZExtValue()
3418 << ", SSARegs:" << numSSARegsValue->getZExtValue();
3419 }
3420 }
3421 llvm::MDNode* pmapInfoNode = callInst->getMetadata("PromotionMap");
3422 if (pmapInfoNode != NULL) {
3423 int elems = pmapInfoNode->getNumOperands();
3424 if (cUnit->printMe) {
3425 LOG(INFO) << "PMap size: " << elems;
3426 }
3427 for (int i = 0; i < elems; i++) {
3428 llvm::ConstantInt* rawMapData =
3429 static_cast<llvm::ConstantInt*>(pmapInfoNode->getOperand(i));
3430 uint32_t mapData = rawMapData->getZExtValue();
3431 PromotionMap* p = &cUnit->promotionMap[i];
3432 p->firstInPair = (mapData >> 24) & 0xff;
3433 p->fpReg = (mapData >> 16) & 0xff;
3434 p->coreReg = (mapData >> 8) & 0xff;
3435 p->fpLocation = static_cast<RegLocationType>((mapData >> 4) & 0xf);
3436 if (p->fpLocation == kLocPhysReg) {
3437 oatRecordFpPromotion(cUnit, p->fpReg, i);
3438 }
3439 p->coreLocation = static_cast<RegLocationType>(mapData & 0xf);
3440 if (p->coreLocation == kLocPhysReg) {
3441 oatRecordCorePromotion(cUnit, p->coreReg, i);
3442 }
3443 }
3444 if (cUnit->printMe) {
3445 oatDumpPromotionMap(cUnit);
3446 }
3447 }
3448 break;
3449 }
3450 }
3451 }
3452 oatAdjustSpillMask(cUnit);
3453 cUnit->frameSize = oatComputeFrameSize(cUnit);
buzbeead8f15e2012-06-18 14:49:45 -07003454
3455 // Create RegLocations for arguments
3456 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3457 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3458 for (; it != it_end; ++it) {
3459 llvm::Value* val = it;
3460 createLocFromValue(cUnit, val);
3461 }
3462 // Create RegLocations for all non-argument defintions
3463 for (llvm::inst_iterator i = llvm::inst_begin(func),
3464 e = llvm::inst_end(func); i != e; ++i) {
3465 llvm::Value* val = &*i;
3466 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3467 createLocFromValue(cUnit, val);
3468 }
3469 }
3470
buzbee2cfc6392012-05-07 14:51:40 -07003471 // Walk the blocks, generating code.
3472 for (llvm::Function::iterator i = cUnit->func->begin(),
3473 e = cUnit->func->end(); i != e; ++i) {
3474 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3475 }
3476
3477 handleSuspendLaunchpads(cUnit);
3478
3479 handleThrowLaunchpads(cUnit);
3480
3481 handleIntrinsicLaunchpads(cUnit);
3482
3483 freeIR(cUnit);
3484}
3485
3486
3487} // namespace art
3488
3489#endif // ART_USE_QUICK_COMPILER