blob: 8d62750a49867340c7ce649282d6f547e9836643 [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}
buzbee2cfc6392012-05-07 14:51:40 -0700169void initIR(CompilationUnit* cUnit)
170{
buzbee692be802012-08-29 15:52:59 -0700171 QuickCompiler* quick =
172 reinterpret_cast<QuickCompiler*>(cUnit->compiler->GetCompilerContext());
173 cUnit->context = quick->GetLLVMContext();
174 cUnit->module = quick->GetLLVMModule();
175 cUnit->intrinsic_helper = quick->GetIntrinsicHelper();
176 cUnit->irb = quick->GetIRBuilder();
buzbee2cfc6392012-05-07 14:51:40 -0700177}
178
179const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
180 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
181}
182
buzbeef58c12c2012-07-03 15:06:29 -0700183llvm::BasicBlock* findCaseTarget(CompilationUnit* cUnit, uint32_t vaddr)
184{
185 BasicBlock* bb = oatFindBlock(cUnit, vaddr);
186 DCHECK(bb != NULL);
187 return getLLVMBlock(cUnit, bb->id);
188}
189
190void convertPackedSwitch(CompilationUnit* cUnit, BasicBlock* bb,
191 int32_t tableOffset, RegLocation rlSrc)
192{
193 const Instruction::PackedSwitchPayload* payload =
194 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
195 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
196
197 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
198
199 llvm::SwitchInst* sw =
200 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
201 payload->case_count);
202
203 for (uint16_t i = 0; i < payload->case_count; ++i) {
204 llvm::BasicBlock* llvmBB =
205 findCaseTarget(cUnit, cUnit->currentDalvikOffset + payload->targets[i]);
206 sw->addCase(cUnit->irb->getInt32(payload->first_key + i), llvmBB);
207 }
208 llvm::MDNode* switchNode =
209 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
210 sw->setMetadata("SwitchTable", switchNode);
211 bb->taken = NULL;
212 bb->fallThrough = NULL;
213}
214
buzbeea1da8a52012-07-09 14:00:21 -0700215void convertSparseSwitch(CompilationUnit* cUnit, BasicBlock* bb,
216 int32_t tableOffset, RegLocation rlSrc)
217{
218 const Instruction::SparseSwitchPayload* payload =
219 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
220 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
221
222 const int32_t* keys = payload->GetKeys();
223 const int32_t* targets = payload->GetTargets();
224
225 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
226
227 llvm::SwitchInst* sw =
228 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
229 payload->case_count);
230
231 for (size_t i = 0; i < payload->case_count; ++i) {
232 llvm::BasicBlock* llvmBB =
233 findCaseTarget(cUnit, cUnit->currentDalvikOffset + targets[i]);
234 sw->addCase(cUnit->irb->getInt32(keys[i]), llvmBB);
235 }
236 llvm::MDNode* switchNode =
237 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
238 sw->setMetadata("SwitchTable", switchNode);
239 bb->taken = NULL;
240 bb->fallThrough = NULL;
241}
242
buzbee8fa0fda2012-06-27 15:44:52 -0700243void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
244 greenland::IntrinsicHelper::IntrinsicId id,
245 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700246{
buzbee8fa0fda2012-06-27 15:44:52 -0700247 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700248 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700249 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
250 defineValue(cUnit, res, rlDest.origSReg);
251}
252
253void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
254 greenland::IntrinsicHelper::IntrinsicId id,
255 RegLocation rlSrc)
256{
257 llvm::SmallVector<llvm::Value*, 2> args;
258 args.push_back(cUnit->irb->getInt32(fieldIndex));
259 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
260 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
261 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700262}
263
buzbee101305f2012-06-28 18:00:56 -0700264void convertFillArrayData(CompilationUnit* cUnit, int32_t offset,
265 RegLocation rlArray)
266{
267 greenland::IntrinsicHelper::IntrinsicId id;
268 id = greenland::IntrinsicHelper::FillArrayData;
269 llvm::SmallVector<llvm::Value*, 2> args;
270 args.push_back(cUnit->irb->getInt32(offset));
271 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
272 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
273 cUnit->irb->CreateCall(intr, args);
274}
275
buzbee2cfc6392012-05-07 14:51:40 -0700276llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
277 RegLocation loc)
278{
279 greenland::IntrinsicHelper::IntrinsicId id;
280 if (loc.wide) {
281 if (loc.fp) {
282 id = greenland::IntrinsicHelper::ConstDouble;
283 } else {
284 id = greenland::IntrinsicHelper::ConstLong;
285 }
286 } else {
287 if (loc.fp) {
288 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700289 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700290 id = greenland::IntrinsicHelper::ConstObj;
291 } else {
292 id = greenland::IntrinsicHelper::ConstInt;
293 }
294 }
295 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
296 return cUnit->irb->CreateCall(intr, src);
297}
buzbeeb03f4872012-06-11 15:22:11 -0700298
299void emitPopShadowFrame(CompilationUnit* cUnit)
300{
301 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
302 greenland::IntrinsicHelper::PopShadowFrame);
303 cUnit->irb->CreateCall(intr);
304}
305
buzbee2cfc6392012-05-07 14:51:40 -0700306llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
307 RegLocation loc)
308{
309 greenland::IntrinsicHelper::IntrinsicId id;
310 if (loc.wide) {
311 if (loc.fp) {
312 id = greenland::IntrinsicHelper::CopyDouble;
313 } else {
314 id = greenland::IntrinsicHelper::CopyLong;
315 }
316 } else {
317 if (loc.fp) {
318 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700319 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700320 id = greenland::IntrinsicHelper::CopyObj;
321 } else {
322 id = greenland::IntrinsicHelper::CopyInt;
323 }
324 }
325 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
326 return cUnit->irb->CreateCall(intr, src);
327}
328
buzbee32412962012-06-26 16:27:56 -0700329void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
330{
331 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
332 greenland::IntrinsicHelper::GetException);
333 llvm::Value* res = cUnit->irb->CreateCall(func);
334 defineValue(cUnit, res, rlDest.origSReg);
335}
336
337void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
338{
339 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
340 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
341 greenland::IntrinsicHelper::Throw);
342 cUnit->irb->CreateCall(func, src);
buzbee32412962012-06-26 16:27:56 -0700343}
344
buzbee8fa0fda2012-06-27 15:44:52 -0700345void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
346 greenland::IntrinsicHelper::IntrinsicId id,
347 RegLocation rlSrc)
348{
349 llvm::SmallVector<llvm::Value*, 2> args;
350 args.push_back(cUnit->irb->getInt32(optFlags));
351 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
352 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
353 cUnit->irb->CreateCall(func, args);
354}
355
buzbee76592632012-06-29 15:18:35 -0700356void convertArrayLength(CompilationUnit* cUnit, int optFlags,
357 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700358{
359 llvm::SmallVector<llvm::Value*, 2> args;
360 args.push_back(cUnit->irb->getInt32(optFlags));
361 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
362 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
363 greenland::IntrinsicHelper::ArrayLength);
buzbee76592632012-06-29 15:18:35 -0700364 llvm::Value* res = cUnit->irb->CreateCall(func, args);
365 defineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700366}
367
buzbee2cfc6392012-05-07 14:51:40 -0700368void emitSuspendCheck(CompilationUnit* cUnit)
369{
370 greenland::IntrinsicHelper::IntrinsicId id =
371 greenland::IntrinsicHelper::CheckSuspend;
372 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
373 cUnit->irb->CreateCall(intr);
374}
375
376llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
377 llvm::Value* src1, llvm::Value* src2)
378{
379 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700380 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700381 switch(cc) {
382 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
383 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
384 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
385 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
386 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
387 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
388 default: LOG(FATAL) << "Unexpected cc value " << cc;
389 }
390 return res;
391}
392
393void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
394 ConditionCode cc, RegLocation rlSrc1,
395 RegLocation rlSrc2)
396{
397 if (bb->taken->startOffset <= mir->offset) {
398 emitSuspendCheck(cUnit);
399 }
400 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
401 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
402 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
403 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
404 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
405 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700406 // Don't redo the fallthrough branch in the BB driver
407 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700408}
409
410void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
411 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
412{
413 if (bb->taken->startOffset <= mir->offset) {
414 emitSuspendCheck(cUnit);
415 }
416 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
417 llvm::Value* src2;
418 if (rlSrc1.ref) {
419 src2 = cUnit->irb->GetJNull();
420 } else {
421 src2 = cUnit->irb->getInt32(0);
422 }
423 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
buzbee2cfc6392012-05-07 14:51:40 -0700424 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
425 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700426 // Don't redo the fallthrough branch in the BB driver
427 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700428}
429
430llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
431 llvm::Value* src1, llvm::Value* src2)
432{
433 greenland::IntrinsicHelper::IntrinsicId id;
434 if (isLong) {
435 if (isDiv) {
436 id = greenland::IntrinsicHelper::DivLong;
437 } else {
438 id = greenland::IntrinsicHelper::RemLong;
439 }
440 } else if (isDiv) {
441 id = greenland::IntrinsicHelper::DivInt;
442 } else {
443 id = greenland::IntrinsicHelper::RemInt;
444 }
445 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
446 llvm::SmallVector<llvm::Value*, 2>args;
447 args.push_back(src1);
448 args.push_back(src2);
449 return cUnit->irb->CreateCall(intr, args);
450}
451
452llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
453 llvm::Value* src1, llvm::Value* src2)
454{
455 llvm::Value* res = NULL;
456 switch(op) {
457 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
458 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700459 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700460 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
461 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
462 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
463 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
464 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
465 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700466 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
467 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
468 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700469 default:
470 LOG(FATAL) << "Invalid op " << op;
471 }
472 return res;
473}
474
475void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
476 RegLocation rlSrc1, RegLocation rlSrc2)
477{
478 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
479 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
480 llvm::Value* res = NULL;
481 switch(op) {
482 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
483 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
484 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
485 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
486 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
487 default:
488 LOG(FATAL) << "Invalid op " << op;
489 }
490 defineValue(cUnit, res, rlDest.origSReg);
491}
492
buzbee2a83e8f2012-07-13 16:42:30 -0700493void convertShift(CompilationUnit* cUnit,
494 greenland::IntrinsicHelper::IntrinsicId id,
495 RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2)
buzbee4f1181f2012-06-22 13:52:12 -0700496{
buzbee2a83e8f2012-07-13 16:42:30 -0700497 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
498 llvm::SmallVector<llvm::Value*, 2>args;
499 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
500 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
501 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
502 defineValue(cUnit, res, rlDest.origSReg);
503}
504
505void convertShiftLit(CompilationUnit* cUnit,
506 greenland::IntrinsicHelper::IntrinsicId id,
507 RegLocation rlDest, RegLocation rlSrc, int shiftAmount)
508{
509 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
510 llvm::SmallVector<llvm::Value*, 2>args;
511 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
512 args.push_back(cUnit->irb->getInt32(shiftAmount));
513 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700514 defineValue(cUnit, res, rlDest.origSReg);
515}
516
buzbee2cfc6392012-05-07 14:51:40 -0700517void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
518 RegLocation rlSrc1, RegLocation rlSrc2)
519{
520 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
521 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700522 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700523 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
524 defineValue(cUnit, res, rlDest.origSReg);
525}
526
buzbeeb03f4872012-06-11 15:22:11 -0700527void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
528{
529 int index = -1;
530 DCHECK(newVal != NULL);
531 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
532 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
533 if (cUnit->shadowMap[i] == vReg) {
534 index = i;
535 break;
536 }
537 }
Elliott Hughes74847412012-06-20 18:10:21 -0700538 DCHECK_NE(index, -1) << "Corrupt shadowMap";
buzbeeb03f4872012-06-11 15:22:11 -0700539 greenland::IntrinsicHelper::IntrinsicId id =
540 greenland::IntrinsicHelper::SetShadowFrameEntry;
541 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
542 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
543 llvm::Value* args[] = { newVal, tableSlot };
544 cUnit->irb->CreateCall(func, args);
545}
546
buzbee2cfc6392012-05-07 14:51:40 -0700547void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
548 RegLocation rlSrc1, int32_t imm)
549{
550 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
551 llvm::Value* src2 = cUnit->irb->getInt32(imm);
552 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
553 defineValue(cUnit, res, rlDest.origSReg);
554}
555
buzbee101305f2012-06-28 18:00:56 -0700556/*
557 * Process arguments for invoke. Note: this code is also used to
558 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
559 * The requirements are similar.
560 */
buzbee6969d502012-06-15 16:40:31 -0700561void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700562 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700563{
564 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
565 llvm::SmallVector<llvm::Value*, 10> args;
566 // Insert the invokeType
567 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
568 // Insert the method_idx
569 args.push_back(cUnit->irb->getInt32(info->index));
570 // Insert the optimization flags
571 args.push_back(cUnit->irb->getInt32(info->optFlags));
572 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700573 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700574 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
575 args.push_back(val);
576 i += info->args[i].wide ? 2 : 1;
577 }
578 /*
579 * Choose the invoke return type based on actual usage. Note: may
580 * be different than shorty. For example, if a function return value
581 * is not used, we'll treat this as a void invoke.
582 */
583 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700584 if (isFilledNewArray) {
585 id = greenland::IntrinsicHelper::FilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700586 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700587 id = greenland::IntrinsicHelper::HLInvokeVoid;
588 } else {
589 if (info->result.wide) {
590 if (info->result.fp) {
591 id = greenland::IntrinsicHelper::HLInvokeDouble;
592 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700593 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700594 }
595 } else if (info->result.ref) {
596 id = greenland::IntrinsicHelper::HLInvokeObj;
597 } else if (info->result.fp) {
598 id = greenland::IntrinsicHelper::HLInvokeFloat;
599 } else {
600 id = greenland::IntrinsicHelper::HLInvokeInt;
601 }
602 }
603 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
604 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
605 if (info->result.location != kLocInvalid) {
606 defineValue(cUnit, res, info->result.origSReg);
607 }
608}
609
buzbee101305f2012-06-28 18:00:56 -0700610void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
611 greenland::IntrinsicHelper::IntrinsicId id,
612 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700613{
buzbee6969d502012-06-15 16:40:31 -0700614 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700615 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700616 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
617 defineValue(cUnit, res, rlDest.origSReg);
618}
619
buzbee101305f2012-06-28 18:00:56 -0700620void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
621 RegLocation rlSrc)
622{
623 greenland::IntrinsicHelper::IntrinsicId id;
624 id = greenland::IntrinsicHelper::CheckCast;
625 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
626 llvm::SmallVector<llvm::Value*, 2> args;
627 args.push_back(cUnit->irb->getInt32(type_idx));
628 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
629 cUnit->irb->CreateCall(intr, args);
630}
631
buzbee8fa0fda2012-06-27 15:44:52 -0700632void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
633 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700634{
635 greenland::IntrinsicHelper::IntrinsicId id;
636 id = greenland::IntrinsicHelper::NewInstance;
637 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
638 llvm::Value* index = cUnit->irb->getInt32(type_idx);
639 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
640 defineValue(cUnit, res, rlDest.origSReg);
641}
642
buzbee8fa0fda2012-06-27 15:44:52 -0700643void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
644 RegLocation rlDest, RegLocation rlSrc)
645{
646 greenland::IntrinsicHelper::IntrinsicId id;
647 id = greenland::IntrinsicHelper::NewArray;
648 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
649 llvm::SmallVector<llvm::Value*, 2> args;
650 args.push_back(cUnit->irb->getInt32(type_idx));
651 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
652 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
653 defineValue(cUnit, res, rlDest.origSReg);
654}
655
656void convertAget(CompilationUnit* cUnit, int optFlags,
657 greenland::IntrinsicHelper::IntrinsicId id,
658 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
659{
660 llvm::SmallVector<llvm::Value*, 3> args;
661 args.push_back(cUnit->irb->getInt32(optFlags));
662 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
663 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
664 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
665 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
666 defineValue(cUnit, res, rlDest.origSReg);
667}
668
669void convertAput(CompilationUnit* cUnit, int optFlags,
670 greenland::IntrinsicHelper::IntrinsicId id,
671 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
672{
673 llvm::SmallVector<llvm::Value*, 4> args;
674 args.push_back(cUnit->irb->getInt32(optFlags));
675 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
676 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
677 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
678 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
679 cUnit->irb->CreateCall(intr, args);
680}
681
buzbee101305f2012-06-28 18:00:56 -0700682void convertIget(CompilationUnit* cUnit, int optFlags,
683 greenland::IntrinsicHelper::IntrinsicId id,
684 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
685{
686 llvm::SmallVector<llvm::Value*, 3> args;
687 args.push_back(cUnit->irb->getInt32(optFlags));
688 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
689 args.push_back(cUnit->irb->getInt32(fieldIndex));
690 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
691 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
692 defineValue(cUnit, res, rlDest.origSReg);
693}
694
695void convertIput(CompilationUnit* cUnit, int optFlags,
696 greenland::IntrinsicHelper::IntrinsicId id,
697 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
698{
699 llvm::SmallVector<llvm::Value*, 4> args;
700 args.push_back(cUnit->irb->getInt32(optFlags));
701 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
702 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
703 args.push_back(cUnit->irb->getInt32(fieldIndex));
704 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
705 cUnit->irb->CreateCall(intr, args);
706}
707
buzbee8fa0fda2012-06-27 15:44:52 -0700708void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
709 RegLocation rlDest, RegLocation rlSrc)
710{
711 greenland::IntrinsicHelper::IntrinsicId id;
712 id = greenland::IntrinsicHelper::InstanceOf;
713 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
714 llvm::SmallVector<llvm::Value*, 2> args;
715 args.push_back(cUnit->irb->getInt32(type_idx));
716 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
717 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
718 defineValue(cUnit, res, rlDest.origSReg);
719}
720
buzbee101305f2012-06-28 18:00:56 -0700721void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
722 RegLocation rlSrc)
723{
724 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
725 cUnit->irb->getInt64Ty());
726 defineValue(cUnit, res, rlDest.origSReg);
727}
728
buzbee76592632012-06-29 15:18:35 -0700729void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
730 RegLocation rlSrc)
731{
732 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
733 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
734 defineValue(cUnit, res, rlDest.origSReg);
735}
736
737void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
738 RegLocation rlSrc)
739{
740 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
741 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
742 defineValue(cUnit, res, rlDest.origSReg);
743}
744
745void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
746 RegLocation rlSrc)
747{
748 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
749 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
750 defineValue(cUnit, res, rlDest.origSReg);
751}
752
753void convertWideComparison(CompilationUnit* cUnit,
754 greenland::IntrinsicHelper::IntrinsicId id,
755 RegLocation rlDest, RegLocation rlSrc1,
756 RegLocation rlSrc2)
757{
758 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
759 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
760 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
761 llvm::SmallVector<llvm::Value*, 2> args;
762 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
763 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
764 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
765 defineValue(cUnit, res, rlDest.origSReg);
766}
767
buzbee101305f2012-06-28 18:00:56 -0700768void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
769 RegLocation rlSrc,
770 greenland::IntrinsicHelper::IntrinsicId id)
771{
772 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700773 llvm::Value* res =
774 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
775 defineValue(cUnit, res, rlDest.origSReg);
776}
777
778void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
779 RegLocation rlSrc)
780{
781 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
782 defineValue(cUnit, res, rlDest.origSReg);
783}
784
785void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
786 RegLocation rlSrc)
787{
788 llvm::Value* res =
789 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
790 defineValue(cUnit, res, rlDest.origSReg);
791}
792
793void convertFPToInt(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
794 RegLocation rlSrc)
795{
796 llvm::Value* res =
797 cUnit->irb->CreateFPToSI(getLLVMValue(cUnit, rlSrc.origSReg), ty);
798 defineValue(cUnit, res, rlDest.origSReg);
799}
800
801
802void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
803 RegLocation rlSrc)
804{
805 llvm::Value* res =
806 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
807 defineValue(cUnit, res, rlDest.origSReg);
808}
809
810void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
811 RegLocation rlSrc)
812{
813 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
814 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700815 defineValue(cUnit, res, rlDest.origSReg);
816}
817
buzbee2cfc6392012-05-07 14:51:40 -0700818/*
819 * Target-independent code generation. Use only high-level
820 * load/store utilities here, or target-dependent genXX() handlers
821 * when necessary.
822 */
823bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
824 llvm::BasicBlock* llvmBB, LIR* labelList)
825{
826 bool res = false; // Assume success
827 RegLocation rlSrc[3];
828 RegLocation rlDest = badLoc;
buzbee2cfc6392012-05-07 14:51:40 -0700829 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee6969d502012-06-15 16:40:31 -0700830 uint32_t vB = mir->dalvikInsn.vB;
831 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700832 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700833
buzbeeb03f4872012-06-11 15:22:11 -0700834 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700835
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700836 if (cUnit->printMe) {
837 if ((int)opcode < kMirOpFirst) {
838 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x"
839 << std::hex << (int)opcode;
840 } else {
841 LOG(INFO) << ".. opcode 0x" << std::hex << (int)opcode;
842 }
843 }
844
buzbee2cfc6392012-05-07 14:51:40 -0700845 /* Prep Src and Dest locations */
846 int nextSreg = 0;
847 int nextLoc = 0;
848 int attrs = oatDataFlowAttributes[opcode];
849 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
850 if (attrs & DF_UA) {
851 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700852 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700853 nextSreg+= 2;
854 } else {
855 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
856 nextSreg++;
857 }
858 }
859 if (attrs & DF_UB) {
860 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700861 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700862 nextSreg+= 2;
863 } else {
864 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
865 nextSreg++;
866 }
867 }
868 if (attrs & DF_UC) {
869 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700870 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700871 } else {
872 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
873 }
874 }
875 if (attrs & DF_DA) {
876 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700877 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700878 } else {
buzbee15bf9802012-06-12 17:49:27 -0700879 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700880 if (rlDest.ref) {
881 objectDefinition = true;
882 }
buzbee2cfc6392012-05-07 14:51:40 -0700883 }
884 }
885
886 switch (opcode) {
887 case Instruction::NOP:
888 break;
889
890 case Instruction::MOVE:
891 case Instruction::MOVE_OBJECT:
892 case Instruction::MOVE_16:
893 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700894 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700895 case Instruction::MOVE_FROM16:
896 case Instruction::MOVE_WIDE:
897 case Instruction::MOVE_WIDE_16:
898 case Instruction::MOVE_WIDE_FROM16: {
899 /*
900 * Moves/copies are meaningless in pure SSA register form,
901 * but we need to preserve them for the conversion back into
902 * MIR (at least until we stop using the Dalvik register maps).
903 * Insert a dummy intrinsic copy call, which will be recognized
904 * by the quick path and removed by the portable path.
905 */
906 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
907 llvm::Value* res = emitCopy(cUnit, src, rlDest);
908 defineValue(cUnit, res, rlDest.origSReg);
909 }
910 break;
911
912 case Instruction::CONST:
913 case Instruction::CONST_4:
914 case Instruction::CONST_16: {
buzbee6969d502012-06-15 16:40:31 -0700915 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700916 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
917 defineValue(cUnit, res, rlDest.origSReg);
918 }
919 break;
920
921 case Instruction::CONST_WIDE_16:
922 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700923 // Sign extend to 64 bits
924 int64_t imm = static_cast<int32_t>(vB);
925 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700926 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
927 defineValue(cUnit, res, rlDest.origSReg);
928 }
929 break;
930
931 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700932 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700933 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
934 defineValue(cUnit, res, rlDest.origSReg);
935 }
936 break;
937
938 case Instruction::CONST_WIDE: {
939 llvm::Constant* immValue =
940 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
941 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
942 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700943 }
944 break;
buzbee2cfc6392012-05-07 14:51:40 -0700945 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700946 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700947 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
948 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
949 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700950 }
951 break;
952
buzbee8fa0fda2012-06-27 15:44:52 -0700953 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700954 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700955 rlSrc[0]);
956 break;
957 case Instruction::SPUT:
958 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700959 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700960 rlSrc[0]);
961 } else {
buzbee76592632012-06-29 15:18:35 -0700962 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700963 }
964 break;
965 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700966 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700967 rlSrc[0]);
968 break;
969 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700970 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700971 break;
972 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -0700973 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700974 break;
975 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -0700976 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700977 break;
978 case Instruction::SPUT_WIDE:
979 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700980 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -0700981 rlSrc[0]);
982 } else {
buzbee76592632012-06-29 15:18:35 -0700983 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -0700984 rlSrc[0]);
985 }
986 break;
987
988 case Instruction::SGET_OBJECT:
989 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
990 break;
991 case Instruction::SGET:
992 if (rlDest.fp) {
993 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
994 } else {
995 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
996 }
997 break;
998 case Instruction::SGET_BOOLEAN:
999 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
1000 break;
1001 case Instruction::SGET_BYTE:
1002 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
1003 break;
1004 case Instruction::SGET_CHAR:
1005 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
1006 break;
1007 case Instruction::SGET_SHORT:
1008 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
1009 break;
1010 case Instruction::SGET_WIDE:
1011 if (rlDest.fp) {
1012 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
1013 rlDest);
1014 } else {
1015 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001016 }
1017 break;
buzbee2cfc6392012-05-07 14:51:40 -07001018
1019 case Instruction::RETURN_WIDE:
1020 case Instruction::RETURN:
1021 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -07001022 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001023 emitSuspendCheck(cUnit);
1024 }
buzbeeb03f4872012-06-11 15:22:11 -07001025 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001026 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
1027 bb->hasReturn = true;
1028 }
1029 break;
1030
1031 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -07001032 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001033 emitSuspendCheck(cUnit);
1034 }
buzbeeb03f4872012-06-11 15:22:11 -07001035 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001036 cUnit->irb->CreateRetVoid();
1037 bb->hasReturn = true;
1038 }
1039 break;
1040
1041 case Instruction::IF_EQ:
1042 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1043 break;
1044 case Instruction::IF_NE:
1045 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1046 break;
1047 case Instruction::IF_LT:
1048 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1049 break;
1050 case Instruction::IF_GE:
1051 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1052 break;
1053 case Instruction::IF_GT:
1054 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1055 break;
1056 case Instruction::IF_LE:
1057 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1058 break;
1059 case Instruction::IF_EQZ:
1060 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1061 break;
1062 case Instruction::IF_NEZ:
1063 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1064 break;
1065 case Instruction::IF_LTZ:
1066 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1067 break;
1068 case Instruction::IF_GEZ:
1069 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1070 break;
1071 case Instruction::IF_GTZ:
1072 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1073 break;
1074 case Instruction::IF_LEZ:
1075 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1076 break;
1077
1078 case Instruction::GOTO:
1079 case Instruction::GOTO_16:
1080 case Instruction::GOTO_32: {
1081 if (bb->taken->startOffset <= bb->startOffset) {
1082 emitSuspendCheck(cUnit);
1083 }
1084 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1085 }
1086 break;
1087
1088 case Instruction::ADD_LONG:
1089 case Instruction::ADD_LONG_2ADDR:
1090 case Instruction::ADD_INT:
1091 case Instruction::ADD_INT_2ADDR:
1092 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1093 break;
1094 case Instruction::SUB_LONG:
1095 case Instruction::SUB_LONG_2ADDR:
1096 case Instruction::SUB_INT:
1097 case Instruction::SUB_INT_2ADDR:
1098 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1099 break;
1100 case Instruction::MUL_LONG:
1101 case Instruction::MUL_LONG_2ADDR:
1102 case Instruction::MUL_INT:
1103 case Instruction::MUL_INT_2ADDR:
1104 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1105 break;
1106 case Instruction::DIV_LONG:
1107 case Instruction::DIV_LONG_2ADDR:
1108 case Instruction::DIV_INT:
1109 case Instruction::DIV_INT_2ADDR:
1110 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1111 break;
1112 case Instruction::REM_LONG:
1113 case Instruction::REM_LONG_2ADDR:
1114 case Instruction::REM_INT:
1115 case Instruction::REM_INT_2ADDR:
1116 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1117 break;
1118 case Instruction::AND_LONG:
1119 case Instruction::AND_LONG_2ADDR:
1120 case Instruction::AND_INT:
1121 case Instruction::AND_INT_2ADDR:
1122 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1123 break;
1124 case Instruction::OR_LONG:
1125 case Instruction::OR_LONG_2ADDR:
1126 case Instruction::OR_INT:
1127 case Instruction::OR_INT_2ADDR:
1128 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1129 break;
1130 case Instruction::XOR_LONG:
1131 case Instruction::XOR_LONG_2ADDR:
1132 case Instruction::XOR_INT:
1133 case Instruction::XOR_INT_2ADDR:
1134 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1135 break;
1136 case Instruction::SHL_LONG:
1137 case Instruction::SHL_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001138 convertShift(cUnit, greenland::IntrinsicHelper::SHLLong,
1139 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001140 break;
buzbee2cfc6392012-05-07 14:51:40 -07001141 case Instruction::SHL_INT:
1142 case Instruction::SHL_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001143 convertShift(cUnit, greenland::IntrinsicHelper::SHLInt,
1144 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001145 break;
1146 case Instruction::SHR_LONG:
1147 case Instruction::SHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001148 convertShift(cUnit, greenland::IntrinsicHelper::SHRLong,
1149 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001150 break;
buzbee2cfc6392012-05-07 14:51:40 -07001151 case Instruction::SHR_INT:
1152 case Instruction::SHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001153 convertShift(cUnit, greenland::IntrinsicHelper::SHRInt,
1154 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001155 break;
1156 case Instruction::USHR_LONG:
1157 case Instruction::USHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001158 convertShift(cUnit, greenland::IntrinsicHelper::USHRLong,
1159 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001160 break;
buzbee2cfc6392012-05-07 14:51:40 -07001161 case Instruction::USHR_INT:
1162 case Instruction::USHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001163 convertShift(cUnit, greenland::IntrinsicHelper::USHRInt,
1164 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001165 break;
1166
1167 case Instruction::ADD_INT_LIT16:
1168 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001169 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001170 break;
1171 case Instruction::RSUB_INT:
1172 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001173 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001174 break;
1175 case Instruction::MUL_INT_LIT16:
1176 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001177 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001178 break;
1179 case Instruction::DIV_INT_LIT16:
1180 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001181 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001182 break;
1183 case Instruction::REM_INT_LIT16:
1184 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001185 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001186 break;
1187 case Instruction::AND_INT_LIT16:
1188 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001189 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001190 break;
1191 case Instruction::OR_INT_LIT16:
1192 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001193 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001194 break;
1195 case Instruction::XOR_INT_LIT16:
1196 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001197 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001198 break;
1199 case Instruction::SHL_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001200 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHLInt,
1201 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001202 break;
1203 case Instruction::SHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001204 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHRInt,
1205 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001206 break;
1207 case Instruction::USHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001208 convertShiftLit(cUnit, greenland::IntrinsicHelper::USHRInt,
1209 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001210 break;
1211
1212 case Instruction::ADD_FLOAT:
1213 case Instruction::ADD_FLOAT_2ADDR:
1214 case Instruction::ADD_DOUBLE:
1215 case Instruction::ADD_DOUBLE_2ADDR:
1216 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1217 break;
1218
1219 case Instruction::SUB_FLOAT:
1220 case Instruction::SUB_FLOAT_2ADDR:
1221 case Instruction::SUB_DOUBLE:
1222 case Instruction::SUB_DOUBLE_2ADDR:
1223 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1224 break;
1225
1226 case Instruction::MUL_FLOAT:
1227 case Instruction::MUL_FLOAT_2ADDR:
1228 case Instruction::MUL_DOUBLE:
1229 case Instruction::MUL_DOUBLE_2ADDR:
1230 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1231 break;
1232
1233 case Instruction::DIV_FLOAT:
1234 case Instruction::DIV_FLOAT_2ADDR:
1235 case Instruction::DIV_DOUBLE:
1236 case Instruction::DIV_DOUBLE_2ADDR:
1237 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1238 break;
1239
1240 case Instruction::REM_FLOAT:
1241 case Instruction::REM_FLOAT_2ADDR:
1242 case Instruction::REM_DOUBLE:
1243 case Instruction::REM_DOUBLE_2ADDR:
1244 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1245 break;
1246
buzbee6969d502012-06-15 16:40:31 -07001247 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001248 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1249 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001250 break;
1251 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001252 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1253 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001254 break;
1255
1256 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001257 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1258 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001259 break;
1260 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001261 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1262 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001263 break;
1264
1265 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001266 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1267 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001268 break;
1269 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001270 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1271 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001272 break;
1273
1274 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001275 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1276 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001277 break;
1278 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001279 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1280 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001281 break;
1282
1283 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001284 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1285 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001286 break;
1287 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001288 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1289 false /* NewFilledArray */);
1290 break;
1291 case Instruction::FILLED_NEW_ARRAY:
1292 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1293 true /* NewFilledArray */);
1294 break;
1295 case Instruction::FILLED_NEW_ARRAY_RANGE:
1296 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1297 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001298 break;
1299
1300 case Instruction::CONST_STRING:
1301 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001302 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1303 rlDest);
1304 break;
1305
1306 case Instruction::CONST_CLASS:
1307 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1308 rlDest);
1309 break;
1310
1311 case Instruction::CHECK_CAST:
1312 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001313 break;
1314
buzbee4f1181f2012-06-22 13:52:12 -07001315 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001316 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001317 break;
1318
buzbee32412962012-06-26 16:27:56 -07001319 case Instruction::MOVE_EXCEPTION:
1320 convertMoveException(cUnit, rlDest);
1321 break;
1322
1323 case Instruction::THROW:
1324 convertThrow(cUnit, rlSrc[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001325 /*
1326 * If this throw is standalone, terminate.
1327 * If it might rethrow, force termination
1328 * of the following block.
1329 */
1330 if (bb->fallThrough == NULL) {
1331 cUnit->irb->CreateUnreachable();
1332 } else {
1333 bb->fallThrough->fallThrough = NULL;
1334 bb->fallThrough->taken = NULL;
1335 }
buzbee32412962012-06-26 16:27:56 -07001336 break;
1337
buzbee2cfc6392012-05-07 14:51:40 -07001338 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001339 case Instruction::MOVE_RESULT:
1340 case Instruction::MOVE_RESULT_OBJECT:
buzbee9a2487f2012-07-26 14:01:13 -07001341 /*
jeffhao9a4f0032012-08-30 16:17:40 -07001342 * All move_results should have been folded into the preceeding invoke.
buzbee9a2487f2012-07-26 14:01:13 -07001343 */
jeffhao9a4f0032012-08-30 16:17:40 -07001344 LOG(FATAL) << "Unexpected move_result";
buzbee2cfc6392012-05-07 14:51:40 -07001345 break;
1346
1347 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001348 convertMonitorEnterExit(cUnit, optFlags,
1349 greenland::IntrinsicHelper::MonitorEnter,
1350 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001351 break;
1352
1353 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001354 convertMonitorEnterExit(cUnit, optFlags,
1355 greenland::IntrinsicHelper::MonitorExit,
1356 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001357 break;
1358
1359 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001360 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001361 break;
1362
1363 case Instruction::NEW_ARRAY:
1364 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1365 break;
1366
1367 case Instruction::INSTANCE_OF:
1368 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1369 break;
1370
1371 case Instruction::AGET:
1372 if (rlDest.fp) {
1373 convertAget(cUnit, optFlags,
1374 greenland::IntrinsicHelper::HLArrayGetFloat,
1375 rlDest, rlSrc[0], rlSrc[1]);
1376 } else {
1377 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1378 rlDest, rlSrc[0], rlSrc[1]);
1379 }
1380 break;
1381 case Instruction::AGET_OBJECT:
1382 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1383 rlDest, rlSrc[0], rlSrc[1]);
1384 break;
1385 case Instruction::AGET_BOOLEAN:
1386 convertAget(cUnit, optFlags,
1387 greenland::IntrinsicHelper::HLArrayGetBoolean,
1388 rlDest, rlSrc[0], rlSrc[1]);
1389 break;
1390 case Instruction::AGET_BYTE:
1391 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1392 rlDest, rlSrc[0], rlSrc[1]);
1393 break;
1394 case Instruction::AGET_CHAR:
1395 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1396 rlDest, rlSrc[0], rlSrc[1]);
1397 break;
1398 case Instruction::AGET_SHORT:
1399 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1400 rlDest, rlSrc[0], rlSrc[1]);
1401 break;
1402 case Instruction::AGET_WIDE:
1403 if (rlDest.fp) {
1404 convertAget(cUnit, optFlags,
1405 greenland::IntrinsicHelper::HLArrayGetDouble,
1406 rlDest, rlSrc[0], rlSrc[1]);
1407 } else {
1408 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1409 rlDest, rlSrc[0], rlSrc[1]);
1410 }
1411 break;
1412
1413 case Instruction::APUT:
1414 if (rlSrc[0].fp) {
1415 convertAput(cUnit, optFlags,
1416 greenland::IntrinsicHelper::HLArrayPutFloat,
1417 rlSrc[0], rlSrc[1], rlSrc[2]);
1418 } else {
1419 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1420 rlSrc[0], rlSrc[1], rlSrc[2]);
1421 }
1422 break;
1423 case Instruction::APUT_OBJECT:
1424 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1425 rlSrc[0], rlSrc[1], rlSrc[2]);
1426 break;
1427 case Instruction::APUT_BOOLEAN:
1428 convertAput(cUnit, optFlags,
1429 greenland::IntrinsicHelper::HLArrayPutBoolean,
1430 rlSrc[0], rlSrc[1], rlSrc[2]);
1431 break;
1432 case Instruction::APUT_BYTE:
1433 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1434 rlSrc[0], rlSrc[1], rlSrc[2]);
1435 break;
1436 case Instruction::APUT_CHAR:
1437 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1438 rlSrc[0], rlSrc[1], rlSrc[2]);
1439 break;
1440 case Instruction::APUT_SHORT:
1441 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1442 rlSrc[0], rlSrc[1], rlSrc[2]);
1443 break;
1444 case Instruction::APUT_WIDE:
1445 if (rlSrc[0].fp) {
1446 convertAput(cUnit, optFlags,
1447 greenland::IntrinsicHelper::HLArrayPutDouble,
1448 rlSrc[0], rlSrc[1], rlSrc[2]);
1449 } else {
1450 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1451 rlSrc[0], rlSrc[1], rlSrc[2]);
1452 }
1453 break;
1454
buzbee101305f2012-06-28 18:00:56 -07001455 case Instruction::IGET:
1456 if (rlDest.fp) {
1457 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001458 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001459 } else {
1460 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001461 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001462 }
buzbee2cfc6392012-05-07 14:51:40 -07001463 break;
buzbee101305f2012-06-28 18:00:56 -07001464 case Instruction::IGET_OBJECT:
1465 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001466 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001467 break;
1468 case Instruction::IGET_BOOLEAN:
1469 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001470 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001471 break;
1472 case Instruction::IGET_BYTE:
1473 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001474 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001475 break;
1476 case Instruction::IGET_CHAR:
1477 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001478 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001479 break;
1480 case Instruction::IGET_SHORT:
1481 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001482 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001483 break;
1484 case Instruction::IGET_WIDE:
1485 if (rlDest.fp) {
1486 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001487 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001488 } else {
1489 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001490 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001491 }
1492 break;
1493 case Instruction::IPUT:
buzbee85eee022012-07-16 22:12:38 -07001494 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001495 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1496 rlSrc[0], rlSrc[1], vC);
1497 } else {
1498 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1499 rlSrc[0], rlSrc[1], vC);
1500 }
1501 break;
1502 case Instruction::IPUT_OBJECT:
1503 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1504 rlSrc[0], rlSrc[1], vC);
1505 break;
1506 case Instruction::IPUT_BOOLEAN:
1507 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1508 rlSrc[0], rlSrc[1], vC);
1509 break;
1510 case Instruction::IPUT_BYTE:
1511 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1512 rlSrc[0], rlSrc[1], vC);
1513 break;
1514 case Instruction::IPUT_CHAR:
1515 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1516 rlSrc[0], rlSrc[1], vC);
1517 break;
1518 case Instruction::IPUT_SHORT:
1519 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1520 rlSrc[0], rlSrc[1], vC);
1521 break;
1522 case Instruction::IPUT_WIDE:
buzbee85eee022012-07-16 22:12:38 -07001523 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001524 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1525 rlSrc[0], rlSrc[1], vC);
1526 } else {
1527 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1528 rlSrc[0], rlSrc[1], vC);
1529 }
buzbee2cfc6392012-05-07 14:51:40 -07001530 break;
1531
1532 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001533 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001534 break;
1535
buzbee76592632012-06-29 15:18:35 -07001536 case Instruction::LONG_TO_INT:
1537 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1538 break;
1539
buzbee101305f2012-06-28 18:00:56 -07001540 case Instruction::INT_TO_LONG:
1541 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001542 break;
1543
buzbee101305f2012-06-28 18:00:56 -07001544 case Instruction::INT_TO_CHAR:
1545 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1546 greenland::IntrinsicHelper::IntToChar);
1547 break;
1548 case Instruction::INT_TO_BYTE:
1549 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1550 greenland::IntrinsicHelper::IntToByte);
1551 break;
1552 case Instruction::INT_TO_SHORT:
1553 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1554 greenland::IntrinsicHelper::IntToShort);
1555 break;
1556
buzbee76592632012-06-29 15:18:35 -07001557 case Instruction::INT_TO_FLOAT:
1558 case Instruction::LONG_TO_FLOAT:
1559 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001560 break;
1561
buzbee76592632012-06-29 15:18:35 -07001562 case Instruction::INT_TO_DOUBLE:
1563 case Instruction::LONG_TO_DOUBLE:
1564 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001565 break;
1566
buzbee76592632012-06-29 15:18:35 -07001567 case Instruction::FLOAT_TO_DOUBLE:
1568 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001569 break;
1570
buzbee76592632012-06-29 15:18:35 -07001571 case Instruction::DOUBLE_TO_FLOAT:
1572 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001573 break;
1574
1575 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001576 case Instruction::NEG_INT:
1577 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001578 break;
1579
1580 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001581 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001582 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001583 break;
1584
buzbee76592632012-06-29 15:18:35 -07001585 case Instruction::NOT_LONG:
1586 case Instruction::NOT_INT:
1587 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001588 break;
1589
buzbee2cfc6392012-05-07 14:51:40 -07001590 case Instruction::FLOAT_TO_INT:
buzbee2cfc6392012-05-07 14:51:40 -07001591 case Instruction::DOUBLE_TO_INT:
buzbee76592632012-06-29 15:18:35 -07001592 convertFPToInt(cUnit, cUnit->irb->getInt32Ty(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001593 break;
1594
buzbee76592632012-06-29 15:18:35 -07001595 case Instruction::FLOAT_TO_LONG:
1596 case Instruction::DOUBLE_TO_LONG:
1597 convertFPToInt(cUnit, cUnit->irb->getInt64Ty(), rlDest, rlSrc[0]);
1598 break;
1599
1600 case Instruction::CMPL_FLOAT:
1601 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1602 rlDest, rlSrc[0], rlSrc[1]);
1603 break;
1604 case Instruction::CMPG_FLOAT:
1605 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1606 rlDest, rlSrc[0], rlSrc[1]);
1607 break;
1608 case Instruction::CMPL_DOUBLE:
1609 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1610 rlDest, rlSrc[0], rlSrc[1]);
1611 break;
1612 case Instruction::CMPG_DOUBLE:
1613 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1614 rlDest, rlSrc[0], rlSrc[1]);
1615 break;
1616 case Instruction::CMP_LONG:
1617 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1618 rlDest, rlSrc[0], rlSrc[1]);
1619 break;
1620
buzbee76592632012-06-29 15:18:35 -07001621 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001622 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001623 break;
1624
1625 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001626 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001627 break;
buzbee2cfc6392012-05-07 14:51:40 -07001628
1629 default:
buzbee32412962012-06-26 16:27:56 -07001630 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001631 res = true;
1632 }
buzbeeb03f4872012-06-11 15:22:11 -07001633 if (objectDefinition) {
1634 setShadowFrameEntry(cUnit, (llvm::Value*)
1635 cUnit->llvmValues.elemList[rlDest.origSReg]);
1636 }
buzbee2cfc6392012-05-07 14:51:40 -07001637 return res;
1638}
1639
1640/* Extended MIR instructions like PHI */
1641void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1642 llvm::BasicBlock* llvmBB)
1643{
1644
1645 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1646 case kMirOpPhi: {
buzbee2cfc6392012-05-07 14:51:40 -07001647 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001648 /*
1649 * The Art compiler's Phi nodes only handle 32-bit operands,
1650 * representing wide values using a matched set of Phi nodes
1651 * for the lower and upper halves. In the llvm world, we only
1652 * want a single Phi for wides. Here we will simply discard
1653 * the Phi node representing the high word.
1654 */
1655 if (rlDest.highWord) {
1656 return; // No Phi node - handled via low word
1657 }
1658 int* incoming = (int*)mir->dalvikInsn.vB;
buzbee2cfc6392012-05-07 14:51:40 -07001659 llvm::Type* phiType =
1660 llvmTypeFromLocRec(cUnit, rlDest);
1661 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1662 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1663 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001664 // Don't check width here.
1665 loc = oatGetRawSrc(cUnit, mir, i);
1666 DCHECK_EQ(rlDest.wide, loc.wide);
1667 DCHECK_EQ(rlDest.wide & rlDest.highWord, loc.wide & loc.highWord);
1668 DCHECK_EQ(rlDest.fp, loc.fp);
1669 DCHECK_EQ(rlDest.core, loc.core);
1670 DCHECK_EQ(rlDest.ref, loc.ref);
buzbeed1643e42012-09-05 14:06:51 -07001671 SafeMap<unsigned int, unsigned int>::iterator it;
1672 it = cUnit->blockIdMap.find(incoming[i]);
1673 DCHECK(it != cUnit->blockIdMap.end());
buzbee2cfc6392012-05-07 14:51:40 -07001674 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
buzbeed1643e42012-09-05 14:06:51 -07001675 getLLVMBlock(cUnit, it->second));
buzbee2cfc6392012-05-07 14:51:40 -07001676 }
1677 defineValue(cUnit, phi, rlDest.origSReg);
1678 break;
1679 }
1680 case kMirOpCopy: {
1681 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1682 break;
1683 }
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001684 case kMirOpNop:
1685 if ((mir == bb->lastMIRInsn) && (bb->taken == NULL) &&
1686 (bb->fallThrough == NULL)) {
1687 cUnit->irb->CreateUnreachable();
1688 }
1689 break;
1690
buzbee2cfc6392012-05-07 14:51:40 -07001691#if defined(TARGET_ARM)
1692 case kMirOpFusedCmplFloat:
1693 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1694 break;
1695 case kMirOpFusedCmpgFloat:
1696 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1697 break;
1698 case kMirOpFusedCmplDouble:
1699 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1700 break;
1701 case kMirOpFusedCmpgDouble:
1702 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1703 break;
1704 case kMirOpFusedCmpLong:
1705 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1706 break;
1707#endif
1708 default:
1709 break;
1710 }
1711}
1712
1713void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1714{
1715 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001716 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001717 arrayRef.push_back(cUnit->irb->getInt32(offset));
1718 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1719 cUnit->irb->SetDexOffset(node);
1720}
1721
1722// Attach method info as metadata to special intrinsic
1723void setMethodInfo(CompilationUnit* cUnit)
1724{
1725 // We don't want dex offset on this
1726 cUnit->irb->SetDexOffset(NULL);
1727 greenland::IntrinsicHelper::IntrinsicId id;
1728 id = greenland::IntrinsicHelper::MethodInfo;
1729 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1730 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1731 llvm::SmallVector<llvm::Value*, 2> regInfo;
1732 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1733 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1734 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1735 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1736 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1737 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1738 inst->setMetadata("RegInfo", regInfoNode);
1739 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1740 llvm::SmallVector<llvm::Value*, 50> pmap;
1741 for (int i = 0; i < promoSize; i++) {
1742 PromotionMap* p = &cUnit->promotionMap[i];
1743 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1744 ((p->fpReg & 0xff) << 16) |
1745 ((p->coreReg & 0xff) << 8) |
1746 ((p->fpLocation & 0xf) << 4) |
1747 (p->coreLocation & 0xf);
1748 pmap.push_back(cUnit->irb->getInt32(mapData));
1749 }
1750 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1751 inst->setMetadata("PromotionMap", mapNode);
1752 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1753}
1754
1755/* Handle the content in each basic block */
1756bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1757{
buzbeed1643e42012-09-05 14:06:51 -07001758 if (bb->blockType == kDead) return false;
buzbee2cfc6392012-05-07 14:51:40 -07001759 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
1760 cUnit->irb->SetInsertPoint(llvmBB);
1761 setDexOffset(cUnit, bb->startOffset);
1762
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001763 if (cUnit->printMe) {
1764 LOG(INFO) << "................................";
1765 LOG(INFO) << "Block id " << bb->id;
1766 if (llvmBB != NULL) {
1767 LOG(INFO) << "label " << llvmBB->getName().str().c_str();
1768 } else {
1769 LOG(INFO) << "llvmBB is NULL";
1770 }
1771 }
1772
buzbee2cfc6392012-05-07 14:51:40 -07001773 if (bb->blockType == kEntryBlock) {
1774 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001775 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1776 cUnit->numDalvikRegisters, true,
1777 kAllocMisc);
1778 for (int i = 0; i < cUnit->numSSARegs; i++) {
1779 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1780 }
1781 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1782 if (canBeRef[i]) {
1783 cUnit->numShadowFrameEntries++;
1784 }
1785 }
1786 if (cUnit->numShadowFrameEntries > 0) {
1787 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1788 cUnit->numShadowFrameEntries, true,
1789 kAllocMisc);
1790 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1791 if (canBeRef[i]) {
1792 cUnit->shadowMap[j++] = i;
1793 }
1794 }
1795 greenland::IntrinsicHelper::IntrinsicId id =
1796 greenland::IntrinsicHelper::AllocaShadowFrame;
1797 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1798 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1799 cUnit->irb->CreateCall(func, entries);
1800 }
buzbee2cfc6392012-05-07 14:51:40 -07001801 } else if (bb->blockType == kExitBlock) {
1802 /*
1803 * Because of the differences between how MIR/LIR and llvm handle exit
1804 * blocks, we won't explicitly covert them. On the llvm-to-lir
1805 * path, it will need to be regenereated.
1806 */
1807 return false;
buzbee6969d502012-06-15 16:40:31 -07001808 } else if (bb->blockType == kExceptionHandling) {
1809 /*
1810 * Because we're deferring null checking, delete the associated empty
1811 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001812 */
1813 llvmBB->eraseFromParent();
1814 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001815 }
1816
1817 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1818
1819 setDexOffset(cUnit, mir->offset);
1820
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001821 int opcode = mir->dalvikInsn.opcode;
1822 Instruction::Format dalvikFormat =
1823 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001824
1825 /* If we're compiling for the debugger, generate an update callout */
1826 if (cUnit->genDebugger) {
1827 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1828 //genDebuggerUpdate(cUnit, mir->offset);
1829 }
1830
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001831 if (opcode == kMirOpCheck) {
1832 // Combine check and work halves of throwing instruction.
1833 MIR* workHalf = mir->meta.throwInsn;
1834 mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
1835 opcode = mir->dalvikInsn.opcode;
1836 SSARepresentation* ssaRep = workHalf->ssaRep;
1837 workHalf->ssaRep = mir->ssaRep;
1838 mir->ssaRep = ssaRep;
1839 workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1840 if (bb->successorBlockList.blockListType == kCatch) {
1841 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
1842 greenland::IntrinsicHelper::CatchTargets);
1843 llvm::Value* switchKey =
1844 cUnit->irb->CreateCall(intr, cUnit->irb->getInt32(mir->offset));
1845 GrowableListIterator iter;
1846 oatGrowableListIteratorInit(&bb->successorBlockList.blocks, &iter);
1847 // New basic block to use for work half
1848 llvm::BasicBlock* workBB =
1849 llvm::BasicBlock::Create(*cUnit->context, "", cUnit->func);
1850 llvm::SwitchInst* sw =
1851 cUnit->irb->CreateSwitch(switchKey, workBB,
1852 bb->successorBlockList.blocks.numUsed);
1853 while (true) {
1854 SuccessorBlockInfo *successorBlockInfo =
1855 (SuccessorBlockInfo *) oatGrowableListIteratorNext(&iter);
1856 if (successorBlockInfo == NULL) break;
1857 llvm::BasicBlock *target =
1858 getLLVMBlock(cUnit, successorBlockInfo->block->id);
1859 int typeIndex = successorBlockInfo->key;
1860 sw->addCase(cUnit->irb->getInt32(typeIndex), target);
1861 }
1862 llvmBB = workBB;
1863 cUnit->irb->SetInsertPoint(llvmBB);
1864 }
1865 }
1866
1867 if (opcode >= kMirOpFirst) {
buzbee2cfc6392012-05-07 14:51:40 -07001868 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1869 continue;
1870 }
1871
1872 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1873 NULL /* labelList */);
1874 if (notHandled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001875 Instruction::Code dalvikOpcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001876 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001877 mir->offset, opcode,
buzbee2cfc6392012-05-07 14:51:40 -07001878 Instruction::Name(dalvikOpcode),
1879 dalvikFormat);
1880 }
1881 }
1882
buzbee4be777b2012-07-12 14:38:18 -07001883 if (bb->blockType == kEntryBlock) {
1884 cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
1885 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001886 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1887 }
1888
1889 return false;
1890}
1891
buzbee4f4dfc72012-07-02 14:54:44 -07001892char remapShorty(char shortyType) {
1893 /*
1894 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1895 * and longs/doubles are represented as a pair of registers. When sub-word
1896 * arguments (and method results) are passed, they are extended to Dalvik
1897 * virtual register containers. Because llvm is picky about type consistency,
1898 * we must either cast the "real" type to 32-bit container multiple Dalvik
1899 * register types, or always use the expanded values.
1900 * Here, we're doing the latter. We map the shorty signature to container
1901 * types (which is valid so long as we always do a real expansion of passed
1902 * arguments and field loads).
1903 */
1904 switch(shortyType) {
1905 case 'Z' : shortyType = 'I'; break;
1906 case 'B' : shortyType = 'I'; break;
1907 case 'S' : shortyType = 'I'; break;
1908 case 'C' : shortyType = 'I'; break;
1909 default: break;
1910 }
1911 return shortyType;
1912}
1913
buzbee2cfc6392012-05-07 14:51:40 -07001914llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1915
1916 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001917 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001918 greenland::kAccurate);
1919
1920 // Get argument type
1921 std::vector<llvm::Type*> args_type;
1922
1923 // method object
1924 args_type.push_back(cUnit->irb->GetJMethodTy());
1925
1926 // Do we have a "this"?
1927 if ((cUnit->access_flags & kAccStatic) == 0) {
1928 args_type.push_back(cUnit->irb->GetJObjectTy());
1929 }
1930
1931 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001932 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001933 greenland::kAccurate));
1934 }
1935
1936 return llvm::FunctionType::get(ret_type, args_type, false);
1937}
1938
1939bool createFunction(CompilationUnit* cUnit) {
1940 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1941 /* with_signature */ false));
1942 llvm::FunctionType* func_type = getFunctionType(cUnit);
1943
1944 if (func_type == NULL) {
1945 return false;
1946 }
1947
1948 cUnit->func = llvm::Function::Create(func_type,
1949 llvm::Function::ExternalLinkage,
1950 func_name, cUnit->module);
1951
1952 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1953 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1954
1955 arg_iter->setName("method");
1956 ++arg_iter;
1957
1958 int startSReg = cUnit->numRegs;
1959
1960 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1961 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1962 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1963 }
1964
1965 return true;
1966}
1967
1968bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1969{
1970 // Skip the exit block
buzbeed1643e42012-09-05 14:06:51 -07001971 if ((bb->blockType == kDead) ||(bb->blockType == kExitBlock)) {
buzbee2cfc6392012-05-07 14:51:40 -07001972 cUnit->idToBlockMap.Put(bb->id, NULL);
1973 } else {
1974 int offset = bb->startOffset;
1975 bool entryBlock = (bb->blockType == kEntryBlock);
1976 llvm::BasicBlock* llvmBB =
1977 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
Elliott Hughes74847412012-06-20 18:10:21 -07001978 StringPrintf(kLabelFormat, offset, bb->id),
buzbee2cfc6392012-05-07 14:51:40 -07001979 cUnit->func);
1980 if (entryBlock) {
1981 cUnit->entryBB = llvmBB;
1982 cUnit->placeholderBB =
1983 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
1984 cUnit->func);
1985 }
1986 cUnit->idToBlockMap.Put(bb->id, llvmBB);
1987 }
1988 return false;
1989}
1990
1991
1992/*
1993 * Convert MIR to LLVM_IR
1994 * o For each ssa name, create LLVM named value. Type these
1995 * appropriately, and ignore high half of wide and double operands.
1996 * o For each MIR basic block, create an LLVM basic block.
1997 * o Iterate through the MIR a basic block at a time, setting arguments
1998 * to recovered ssa name.
1999 */
2000void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
2001{
2002 initIR(cUnit);
2003 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
2004
2005 // Create the function
2006 createFunction(cUnit);
2007
2008 // Create an LLVM basic block for each MIR block in dfs preorder
2009 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
2010 kPreOrderDFSTraversal, false /* isIterative */);
2011 /*
2012 * Create an llvm named value for each MIR SSA name. Note: we'll use
2013 * placeholders for all non-argument values (because we haven't seen
2014 * the definition yet).
2015 */
2016 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2017 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2018 arg_iter++; /* Skip path method */
2019 for (int i = 0; i < cUnit->numSSARegs; i++) {
2020 llvm::Value* val;
buzbee85eee022012-07-16 22:12:38 -07002021 RegLocation rlTemp = cUnit->regLocation[i];
2022 if ((SRegToVReg(cUnit, i) < 0) || rlTemp.highWord) {
buzbee2a83e8f2012-07-13 16:42:30 -07002023 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
2024 } else if ((i < cUnit->numRegs) ||
2025 (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee85eee022012-07-16 22:12:38 -07002026 llvm::Constant* immValue = cUnit->regLocation[i].wide ?
2027 cUnit->irb->GetJLong(0) : cUnit->irb->GetJInt(0);
buzbee2a83e8f2012-07-13 16:42:30 -07002028 val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
2029 val->setName(llvmSSAName(cUnit, i));
buzbee2cfc6392012-05-07 14:51:40 -07002030 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
buzbee2cfc6392012-05-07 14:51:40 -07002031 } else {
2032 // Recover previously-created argument values
2033 llvm::Value* argVal = arg_iter++;
2034 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
2035 }
2036 }
buzbee2cfc6392012-05-07 14:51:40 -07002037
2038 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
2039 kPreOrderDFSTraversal, false /* Iterative */);
2040
buzbee4be777b2012-07-12 14:38:18 -07002041 /*
2042 * In a few rare cases of verification failure, the verifier will
2043 * replace one or more Dalvik opcodes with the special
2044 * throw-verification-failure opcode. This can leave the SSA graph
2045 * in an invalid state, as definitions may be lost, while uses retained.
2046 * To work around this problem, we insert placeholder definitions for
2047 * all Dalvik SSA regs in the "placeholder" block. Here, after
2048 * bitcode conversion is complete, we examine those placeholder definitions
2049 * and delete any with no references (which normally is all of them).
2050 *
2051 * If any definitions remain, we link the placeholder block into the
2052 * CFG. Otherwise, it is deleted.
2053 */
2054 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
2055 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
2056 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2057 DCHECK(inst != NULL);
2058 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2059 DCHECK(val != NULL);
2060 if (val->getNumUses() == 0) {
2061 inst->eraseFromParent();
2062 }
2063 }
2064 setDexOffset(cUnit, 0);
2065 if (cUnit->placeholderBB->empty()) {
2066 cUnit->placeholderBB->eraseFromParent();
2067 } else {
2068 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2069 cUnit->irb->CreateBr(cUnit->entryTargetBB);
2070 cUnit->entryTargetBB = cUnit->placeholderBB;
2071 }
2072 cUnit->irb->SetInsertPoint(cUnit->entryBB);
2073 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07002074
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002075 if (cUnit->enableDebug & (1 << kDebugVerifyBitcode)) {
2076 if (llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction)) {
2077 LOG(INFO) << "Bitcode verification FAILED for "
2078 << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
2079 << " of size " << cUnit->insnsSize;
2080 cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
2081 }
2082 }
buzbee2cfc6392012-05-07 14:51:40 -07002083
buzbeead8f15e2012-06-18 14:49:45 -07002084 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
2085 // Write bitcode to file
2086 std::string errmsg;
2087 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
2088 oatReplaceSpecialChars(fname);
2089 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07002090 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002091
buzbeead8f15e2012-06-18 14:49:45 -07002092 llvm::OwningPtr<llvm::tool_output_file> out_file(
2093 new llvm::tool_output_file(fname.c_str(), errmsg,
2094 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002095
buzbeead8f15e2012-06-18 14:49:45 -07002096 if (!errmsg.empty()) {
2097 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2098 }
2099
2100 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
2101 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002102 }
buzbee2cfc6392012-05-07 14:51:40 -07002103}
2104
2105RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
2106 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002107 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002108 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2109 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07002110 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07002111 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002112 // FIXME: need to be more robust, handle FP and be in a position to
2113 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002114 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2115 memset(&res, 0, sizeof(res));
2116 res.location = kLocPhysReg;
2117 res.lowReg = oatAllocTemp(cUnit);
2118 res.home = true;
2119 res.sRegLow = INVALID_SREG;
2120 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002121 llvm::Type* ty = val->getType();
2122 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2123 (ty == cUnit->irb->getDoubleTy()));
2124 if (res.wide) {
2125 res.highReg = oatAllocTemp(cUnit);
2126 }
buzbee4f1181f2012-06-22 13:52:12 -07002127 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002128 } else {
2129 DCHECK_EQ(valName[0], 'v');
2130 int baseSReg = INVALID_SREG;
2131 sscanf(valName.c_str(), "v%d_", &baseSReg);
2132 res = cUnit->regLocation[baseSReg];
2133 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002134 }
2135 } else {
2136 res = it->second;
2137 }
2138 return res;
2139}
2140
2141Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
2142{
2143 Instruction::Code res = Instruction::NOP;
2144 if (isWide) {
2145 switch(op) {
2146 case kOpAdd: res = Instruction::ADD_LONG; break;
2147 case kOpSub: res = Instruction::SUB_LONG; break;
2148 case kOpMul: res = Instruction::MUL_LONG; break;
2149 case kOpDiv: res = Instruction::DIV_LONG; break;
2150 case kOpRem: res = Instruction::REM_LONG; break;
2151 case kOpAnd: res = Instruction::AND_LONG; break;
2152 case kOpOr: res = Instruction::OR_LONG; break;
2153 case kOpXor: res = Instruction::XOR_LONG; break;
2154 case kOpLsl: res = Instruction::SHL_LONG; break;
2155 case kOpLsr: res = Instruction::USHR_LONG; break;
2156 case kOpAsr: res = Instruction::SHR_LONG; break;
2157 default: LOG(FATAL) << "Unexpected OpKind " << op;
2158 }
2159 } else if (isConst){
2160 switch(op) {
2161 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2162 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2163 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2164 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2165 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2166 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2167 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2168 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2169 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2170 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2171 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2172 default: LOG(FATAL) << "Unexpected OpKind " << op;
2173 }
2174 } else {
2175 switch(op) {
2176 case kOpAdd: res = Instruction::ADD_INT; break;
2177 case kOpSub: res = Instruction::SUB_INT; break;
2178 case kOpMul: res = Instruction::MUL_INT; break;
2179 case kOpDiv: res = Instruction::DIV_INT; break;
2180 case kOpRem: res = Instruction::REM_INT; break;
2181 case kOpAnd: res = Instruction::AND_INT; break;
2182 case kOpOr: res = Instruction::OR_INT; break;
2183 case kOpXor: res = Instruction::XOR_INT; break;
2184 case kOpLsl: res = Instruction::SHL_INT; break;
2185 case kOpLsr: res = Instruction::USHR_INT; break;
2186 case kOpAsr: res = Instruction::SHR_INT; break;
2187 default: LOG(FATAL) << "Unexpected OpKind " << op;
2188 }
2189 }
2190 return res;
2191}
2192
buzbee4f1181f2012-06-22 13:52:12 -07002193Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2194{
2195 Instruction::Code res = Instruction::NOP;
2196 if (isWide) {
2197 switch(op) {
2198 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2199 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2200 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2201 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2202 case kOpRem: res = Instruction::REM_DOUBLE; break;
2203 default: LOG(FATAL) << "Unexpected OpKind " << op;
2204 }
2205 } else {
2206 switch(op) {
2207 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2208 case kOpSub: res = Instruction::SUB_FLOAT; break;
2209 case kOpMul: res = Instruction::MUL_FLOAT; break;
2210 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2211 case kOpRem: res = Instruction::REM_FLOAT; break;
2212 default: LOG(FATAL) << "Unexpected OpKind " << op;
2213 }
2214 }
2215 return res;
2216}
2217
2218void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2219{
2220 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002221 /*
2222 * Normally, we won't ever generate an FP operation with an immediate
2223 * operand (not supported in Dex instruction set). However, the IR builder
2224 * may insert them - in particular for createNegFP. Recognize this case
2225 * and deal with it.
2226 */
2227 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2228 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2229 DCHECK(op2C == NULL);
2230 if ((op1C != NULL) && (op == kOpSub)) {
2231 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2232 if (rlDest.wide) {
2233 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2234 } else {
2235 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2236 }
buzbee4f1181f2012-06-22 13:52:12 -07002237 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002238 DCHECK(op1C == NULL);
2239 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2240 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2241 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2242 if (rlDest.wide) {
2243 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2244 } else {
2245 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2246 }
buzbee4f1181f2012-06-22 13:52:12 -07002247 }
2248}
2249
buzbee101305f2012-06-28 18:00:56 -07002250void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2251 Instruction::Code opcode)
2252{
2253 RegLocation rlDest = getLoc(cUnit, inst);
2254 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2255 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2256}
2257
buzbee76592632012-06-29 15:18:35 -07002258void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2259{
2260 RegLocation rlDest = getLoc(cUnit, inst);
2261 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2262 Instruction::Code opcode;
2263 if (rlDest.wide) {
2264 if (rlSrc.wide) {
2265 opcode = Instruction::LONG_TO_DOUBLE;
2266 } else {
2267 opcode = Instruction::INT_TO_DOUBLE;
2268 }
2269 } else {
2270 if (rlSrc.wide) {
2271 opcode = Instruction::LONG_TO_FLOAT;
2272 } else {
2273 opcode = Instruction::INT_TO_FLOAT;
2274 }
2275 }
2276 genConversion(cUnit, opcode, rlDest, rlSrc);
2277}
2278
2279void cvtFPToInt(CompilationUnit* cUnit, llvm::Instruction* inst)
2280{
2281 RegLocation rlDest = getLoc(cUnit, inst);
2282 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2283 Instruction::Code opcode;
2284 if (rlDest.wide) {
2285 if (rlSrc.wide) {
2286 opcode = Instruction::DOUBLE_TO_LONG;
2287 } else {
2288 opcode = Instruction::FLOAT_TO_LONG;
2289 }
2290 } else {
2291 if (rlSrc.wide) {
2292 opcode = Instruction::DOUBLE_TO_INT;
2293 } else {
2294 opcode = Instruction::FLOAT_TO_INT;
2295 }
2296 }
2297 genConversion(cUnit, opcode, rlDest, rlSrc);
2298}
2299
2300void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2301{
2302 RegLocation rlDest = getLoc(cUnit, inst);
2303 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2304 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2305}
2306
2307void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2308{
2309 RegLocation rlDest = getLoc(cUnit, inst);
2310 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2311 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2312 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2313 storeValue(cUnit, rlDest, rlSrc);
2314}
2315
2316void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2317{
2318 RegLocation rlDest = getLoc(cUnit, inst);
2319 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2320 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2321}
2322
2323
buzbee101305f2012-06-28 18:00:56 -07002324void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2325{
2326 // TODO: evaluate src/tgt types and add general support for more than int to long
2327 RegLocation rlDest = getLoc(cUnit, inst);
2328 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2329 DCHECK(rlDest.wide);
2330 DCHECK(!rlSrc.wide);
2331 DCHECK(!rlDest.fp);
2332 DCHECK(!rlSrc.fp);
2333 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2334 if (rlSrc.location == kLocPhysReg) {
2335 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2336 } else {
2337 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2338 }
2339 if (isSigned) {
2340 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2341 } else {
2342 loadConstant(cUnit, rlResult.highReg, 0);
2343 }
2344 storeValueWide(cUnit, rlDest, rlResult);
2345}
2346
buzbee2cfc6392012-05-07 14:51:40 -07002347void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2348{
2349 RegLocation rlDest = getLoc(cUnit, inst);
2350 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002351 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002352 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2353 if ((op == kOpSub) && (lhsImm != NULL)) {
2354 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002355 if (rlSrc1.wide) {
2356 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2357 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2358 } else {
2359 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2360 lhsImm->getSExtValue());
2361 }
buzbee4f1181f2012-06-22 13:52:12 -07002362 return;
2363 }
2364 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002365 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2366 llvm::Value* rhs = inst->getOperand(1);
buzbee9a2487f2012-07-26 14:01:13 -07002367 llvm::ConstantInt* constRhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2368 if (!rlDest.wide && (constRhs != NULL)) {
buzbee2cfc6392012-05-07 14:51:40 -07002369 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
buzbee9a2487f2012-07-26 14:01:13 -07002370 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, constRhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002371 } else {
2372 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
buzbee9a2487f2012-07-26 14:01:13 -07002373 RegLocation rlSrc2;
2374 if (constRhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002375 // ir_builder converts NOT_LONG to xor src, -1. Restore
2376 DCHECK_EQ(dalvikOp, Instruction::XOR_LONG);
2377 DCHECK_EQ(-1L, constRhs->getSExtValue());
2378 dalvikOp = Instruction::NOT_LONG;
buzbee9a2487f2012-07-26 14:01:13 -07002379 rlSrc2 = rlSrc1;
2380 } else {
2381 rlSrc2 = getLoc(cUnit, rhs);
2382 }
buzbee2cfc6392012-05-07 14:51:40 -07002383 if (rlDest.wide) {
2384 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2385 } else {
2386 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2387 }
2388 }
2389}
2390
buzbee2a83e8f2012-07-13 16:42:30 -07002391void cvtShiftOp(CompilationUnit* cUnit, Instruction::Code opcode,
2392 llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002393{
buzbee2a83e8f2012-07-13 16:42:30 -07002394 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2395 RegLocation rlDest = getLoc(cUnit, callInst);
2396 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2397 llvm::Value* rhs = callInst->getArgOperand(1);
2398 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2399 DCHECK(!rlDest.wide);
2400 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002401 } else {
buzbee2a83e8f2012-07-13 16:42:30 -07002402 RegLocation rlShift = getLoc(cUnit, rhs);
2403 if (callInst->getType() == cUnit->irb->getInt64Ty()) {
2404 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2405 } else {
2406 genArithOpInt(cUnit, opcode, rlDest, rlSrc, rlShift);
2407 }
buzbee101305f2012-06-28 18:00:56 -07002408 }
2409}
2410
buzbee2cfc6392012-05-07 14:51:40 -07002411void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2412{
2413 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2414 DCHECK(brInst != NULL);
2415 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2416 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2417 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2418}
2419
2420void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2421{
2422 // Nop - these have already been processed
2423}
2424
2425void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2426{
2427 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2428 llvm::Value* retVal = retInst->getReturnValue();
2429 if (retVal != NULL) {
2430 RegLocation rlSrc = getLoc(cUnit, retVal);
2431 if (rlSrc.wide) {
2432 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2433 } else {
2434 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2435 }
2436 }
2437 genExitSequence(cUnit);
2438}
2439
2440ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2441{
2442 ConditionCode res = kCondAl;
2443 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002444 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002445 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2446 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2447 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002448 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002449 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002450 default: LOG(FATAL) << "Unexpected llvm condition";
2451 }
2452 return res;
2453}
2454
2455void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2456{
2457 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2458 UNIMPLEMENTED(FATAL);
2459}
2460
2461void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2462 llvm::BranchInst* brInst)
2463{
2464 // Get targets
2465 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2466 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2467 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2468 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2469 // Get comparison operands
2470 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2471 ConditionCode cond = getCond(iCmpInst->getPredicate());
2472 llvm::Value* lhs = iCmpInst->getOperand(0);
2473 // Not expecting a constant as 1st operand
2474 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2475 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2476 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2477 llvm::Value* rhs = inst->getOperand(1);
2478#if defined(TARGET_MIPS)
2479 // Compare and branch in one shot
2480 (void)taken;
2481 (void)cond;
2482 (void)rhs;
2483 UNIMPLEMENTED(FATAL);
2484#else
2485 //Compare, then branch
2486 // TODO: handle fused CMP_LONG/IF_xxZ case
2487 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2488 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002489 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
2490 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002491 } else {
2492 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2493 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2494 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2495 }
2496 opCondBranch(cUnit, cond, taken);
2497#endif
2498 // Fallthrough
2499 opUnconditionalBranch(cUnit, fallThrough);
2500}
2501
2502void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2503 llvm::Function* callee)
2504{
2505 UNIMPLEMENTED(FATAL);
2506}
2507
buzbee2cfc6392012-05-07 14:51:40 -07002508void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2509{
buzbee4f1181f2012-06-22 13:52:12 -07002510 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002511 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2512 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002513 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2514 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002515 if (rlSrc.wide) {
2516 storeValueWide(cUnit, rlDest, rlSrc);
2517 } else {
2518 storeValue(cUnit, rlDest, rlSrc);
2519 }
2520}
2521
2522// Note: Immediate arg is a ConstantInt regardless of result type
2523void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2524{
buzbee4f1181f2012-06-22 13:52:12 -07002525 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002526 llvm::ConstantInt* src =
2527 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2528 uint64_t immval = src->getZExtValue();
2529 RegLocation rlDest = getLoc(cUnit, callInst);
2530 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2531 if (rlDest.wide) {
2532 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2533 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2534 storeValueWide(cUnit, rlDest, rlResult);
2535 } else {
2536 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2537 storeValue(cUnit, rlDest, rlResult);
2538 }
2539}
2540
buzbee101305f2012-06-28 18:00:56 -07002541void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2542 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002543{
buzbee4f1181f2012-06-22 13:52:12 -07002544 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002545 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002546 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002547 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002548 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002549 if (isString) {
2550 genConstString(cUnit, index, rlDest);
2551 } else {
2552 genConstClass(cUnit, index, rlDest);
2553 }
2554}
2555
2556void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2557{
2558 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2559 llvm::ConstantInt* offsetVal =
2560 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2561 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2562 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002563}
2564
buzbee4f1181f2012-06-22 13:52:12 -07002565void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2566{
buzbee32412962012-06-26 16:27:56 -07002567 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002568 llvm::ConstantInt* typeIdxVal =
2569 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2570 uint32_t typeIdx = typeIdxVal->getZExtValue();
2571 RegLocation rlDest = getLoc(cUnit, callInst);
2572 genNewInstance(cUnit, typeIdx, rlDest);
2573}
2574
buzbee8fa0fda2012-06-27 15:44:52 -07002575void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2576{
2577 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2578 llvm::ConstantInt* typeIdxVal =
2579 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2580 uint32_t typeIdx = typeIdxVal->getZExtValue();
2581 llvm::Value* len = callInst->getArgOperand(1);
2582 RegLocation rlLen = getLoc(cUnit, len);
2583 RegLocation rlDest = getLoc(cUnit, callInst);
2584 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2585}
2586
2587void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2588{
2589 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2590 llvm::ConstantInt* typeIdxVal =
2591 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2592 uint32_t typeIdx = typeIdxVal->getZExtValue();
2593 llvm::Value* src = callInst->getArgOperand(1);
2594 RegLocation rlSrc = getLoc(cUnit, src);
2595 RegLocation rlDest = getLoc(cUnit, callInst);
2596 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2597}
2598
buzbee32412962012-06-26 16:27:56 -07002599void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2600{
2601 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2602 llvm::Value* src = callInst->getArgOperand(0);
2603 RegLocation rlSrc = getLoc(cUnit, src);
2604 genThrow(cUnit, rlSrc);
2605}
2606
buzbee8fa0fda2012-06-27 15:44:52 -07002607void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2608 llvm::CallInst* callInst)
2609{
2610 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2611 llvm::ConstantInt* optFlags =
2612 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2613 llvm::Value* src = callInst->getArgOperand(1);
2614 RegLocation rlSrc = getLoc(cUnit, src);
2615 if (isEnter) {
2616 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2617 } else {
2618 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2619 }
2620}
2621
buzbee76592632012-06-29 15:18:35 -07002622void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002623{
2624 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2625 llvm::ConstantInt* optFlags =
2626 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2627 llvm::Value* src = callInst->getArgOperand(1);
2628 RegLocation rlSrc = getLoc(cUnit, src);
2629 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2630 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2631 RegLocation rlDest = getLoc(cUnit, callInst);
2632 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2633 int lenOffset = Array::LengthOffset().Int32Value();
2634 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2635 storeValue(cUnit, rlDest, rlResult);
2636}
2637
buzbee32412962012-06-26 16:27:56 -07002638void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2639{
2640 DCHECK_EQ(callInst->getNumArgOperands(), 0U);
2641 int exOffset = Thread::ExceptionOffset().Int32Value();
2642 RegLocation rlDest = getLoc(cUnit, callInst);
2643 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2644#if defined(TARGET_X86)
2645 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
2646 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
2647#else
2648 int resetReg = oatAllocTemp(cUnit);
2649 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
2650 loadConstant(cUnit, resetReg, 0);
2651 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
2652 oatFreeTemp(cUnit, resetReg);
2653#endif
2654 storeValue(cUnit, rlDest, rlResult);
2655}
2656
buzbee4f1181f2012-06-22 13:52:12 -07002657void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2658 bool isObject)
2659{
buzbee32412962012-06-26 16:27:56 -07002660 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002661 llvm::ConstantInt* typeIdxVal =
2662 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2663 uint32_t typeIdx = typeIdxVal->getZExtValue();
2664 RegLocation rlDest = getLoc(cUnit, callInst);
2665 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2666}
2667
buzbee8fa0fda2012-06-27 15:44:52 -07002668void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2669 bool isObject)
2670{
2671 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2672 llvm::ConstantInt* typeIdxVal =
2673 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2674 uint32_t typeIdx = typeIdxVal->getZExtValue();
2675 llvm::Value* src = callInst->getArgOperand(1);
2676 RegLocation rlSrc = getLoc(cUnit, src);
2677 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2678}
2679
2680void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2681 int scale)
2682{
2683 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2684 llvm::ConstantInt* optFlags =
2685 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2686 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2687 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2688 RegLocation rlDest = getLoc(cUnit, callInst);
2689 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2690 rlDest, scale);
2691}
2692
2693void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002694 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002695{
2696 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2697 llvm::ConstantInt* optFlags =
2698 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2699 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2700 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2701 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002702 if (isObject) {
2703 genArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
2704 rlSrc, scale);
2705 } else {
2706 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2707 rlSrc, scale);
2708 }
2709}
2710
2711void cvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
2712{
2713 cvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
2714}
2715
2716void cvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
2717 OpSize size, int scale)
2718{
2719 cvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002720}
2721
buzbee101305f2012-06-28 18:00:56 -07002722void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2723 bool isWide, bool isObj)
2724{
2725 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2726 llvm::ConstantInt* optFlags =
2727 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2728 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2729 llvm::ConstantInt* fieldIdx =
2730 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2731 RegLocation rlDest = getLoc(cUnit, callInst);
2732 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2733 size, rlDest, rlObj, isWide, isObj);
2734}
2735
2736void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2737 bool isWide, bool isObj)
2738{
2739 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2740 llvm::ConstantInt* optFlags =
2741 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2742 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2743 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2744 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002745 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002746 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2747 size, rlSrc, rlObj, isWide, isObj);
2748}
2749
2750void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2751{
2752 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2753 llvm::ConstantInt* typeIdx =
2754 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2755 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2756 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2757}
2758
buzbee76592632012-06-29 15:18:35 -07002759void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2760 Instruction::Code opcode)
2761{
2762 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2763 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2764 RegLocation rlDest = getLoc(cUnit, callInst);
2765 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2766}
2767
2768void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2769{
2770 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2771 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2772 RegLocation rlDest = getLoc(cUnit, callInst);
2773 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2774}
2775
buzbeef58c12c2012-07-03 15:06:29 -07002776void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2777{
2778 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2779 DCHECK(swInst != NULL);
2780 llvm::Value* testVal = swInst->getCondition();
2781 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2782 DCHECK(tableOffsetNode != NULL);
2783 llvm::ConstantInt* tableOffsetValue =
2784 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2785 int32_t tableOffset = tableOffsetValue->getSExtValue();
2786 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeea1da8a52012-07-09 14:00:21 -07002787 const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2788 u2 tableMagic = *table;
2789 if (tableMagic == 0x100) {
2790 genPackedSwitch(cUnit, tableOffset, rlSrc);
2791 } else {
2792 DCHECK_EQ(tableMagic, 0x200);
2793 genSparseSwitch(cUnit, tableOffset, rlSrc);
2794 }
buzbeef58c12c2012-07-03 15:06:29 -07002795}
2796
buzbee6969d502012-06-15 16:40:31 -07002797void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002798 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002799{
2800 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2801 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002802 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002803 info->result.location = kLocInvalid;
2804 } else {
2805 info->result = getLoc(cUnit, callInst);
2806 }
2807 llvm::ConstantInt* invokeTypeVal =
2808 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2809 llvm::ConstantInt* methodIndexVal =
2810 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2811 llvm::ConstantInt* optFlagsVal =
2812 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2813 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2814 info->index = methodIndexVal->getZExtValue();
2815 info->optFlags = optFlagsVal->getZExtValue();
2816 info->offset = cUnit->currentDalvikOffset;
2817
buzbee6969d502012-06-15 16:40:31 -07002818 // Count the argument words, and then build argument array.
2819 info->numArgWords = 0;
2820 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2821 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2822 info->numArgWords += tLoc.wide ? 2 : 1;
2823 }
2824 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2825 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2826 // Now, fill in the location records, synthesizing high loc of wide vals
2827 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002828 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002829 if (info->args[next].wide) {
2830 next++;
2831 // TODO: Might make sense to mark this as an invalid loc
2832 info->args[next].origSReg = info->args[next-1].origSReg+1;
2833 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2834 }
2835 next++;
2836 }
buzbee4f4dfc72012-07-02 14:54:44 -07002837 // TODO - rework such that we no longer need isRange
2838 info->isRange = (info->numArgWords > 5);
2839
buzbee76592632012-06-29 15:18:35 -07002840 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002841 genFilledNewArray(cUnit, info);
2842 } else {
2843 genInvoke(cUnit, info);
2844 }
buzbee6969d502012-06-15 16:40:31 -07002845}
2846
buzbeead8f15e2012-06-18 14:49:45 -07002847/* Look up the RegLocation associated with a Value. Must already be defined */
2848RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2849{
2850 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2851 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2852 return it->second;
2853}
2854
buzbee2cfc6392012-05-07 14:51:40 -07002855bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2856{
2857 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2858 // Define the starting label
2859 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2860 // Extract the starting offset from the block's name
2861 if (!isEntry) {
2862 const char* blockName = bb->getName().str().c_str();
2863 int dummy;
Elliott Hughes74847412012-06-20 18:10:21 -07002864 sscanf(blockName, kLabelFormat, &blockLabel->operands[0], &dummy);
buzbee2cfc6392012-05-07 14:51:40 -07002865 }
2866 // Set the label kind
2867 blockLabel->opcode = kPseudoNormalBlockLabel;
2868 // Insert the label
2869 oatAppendLIR(cUnit, blockLabel);
2870
2871 // Free temp registers and reset redundant store tracking */
2872 oatResetRegPool(cUnit);
2873 oatResetDefTracking(cUnit);
2874
2875 //TODO: restore oat incoming liveness optimization
2876 oatClobberAllRegs(cUnit);
2877
buzbee6969d502012-06-15 16:40:31 -07002878 LIR* headLIR = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07002879
2880 if (isEntry) {
2881 cUnit->currentDalvikOffset = 0;
buzbeead8f15e2012-06-18 14:49:45 -07002882 RegLocation* argLocs = (RegLocation*)
2883 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2884 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2885 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
buzbeeca7a5e42012-08-20 11:12:18 -07002886 // Skip past Method*
2887 it++;
buzbeead8f15e2012-06-18 14:49:45 -07002888 for (unsigned i = 0; it != it_end; ++it) {
2889 llvm::Value* val = it;
2890 argLocs[i++] = valToLoc(cUnit, val);
2891 llvm::Type* ty = val->getType();
2892 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
buzbeeca7a5e42012-08-20 11:12:18 -07002893 argLocs[i] = argLocs[i-1];
2894 argLocs[i].lowReg = argLocs[i].highReg;
2895 argLocs[i].origSReg++;
2896 argLocs[i].sRegLow = INVALID_SREG;
2897 argLocs[i].highWord = true;
2898 i++;
buzbeead8f15e2012-06-18 14:49:45 -07002899 }
2900 }
2901 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
buzbee2cfc6392012-05-07 14:51:40 -07002902 }
2903
2904 // Visit all of the instructions in the block
2905 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2906 llvm::Instruction* inst = it;
2907 llvm::BasicBlock::iterator nextIt = ++it;
2908 // Extract the Dalvik offset from the instruction
2909 uint32_t opcode = inst->getOpcode();
2910 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2911 if (dexOffsetNode != NULL) {
2912 llvm::ConstantInt* dexOffsetValue =
2913 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2914 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2915 }
2916
buzbee6969d502012-06-15 16:40:31 -07002917 oatResetRegPool(cUnit);
2918 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2919 oatClobberAllRegs(cUnit);
2920 }
2921
2922 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2923 oatResetDefTracking(cUnit);
2924 }
2925
2926#ifndef NDEBUG
2927 /* Reset temp tracking sanity check */
2928 cUnit->liveSReg = INVALID_SREG;
2929#endif
2930
buzbeed1643e42012-09-05 14:06:51 -07002931 // TODO: use llvm opcode name here instead of "boundary" if verbose
2932 LIR* boundaryLIR = markBoundary(cUnit, cUnit->currentDalvikOffset, "boundary");
buzbee6969d502012-06-15 16:40:31 -07002933
2934 /* Remember the first LIR for thisl block*/
2935 if (headLIR == NULL) {
2936 headLIR = boundaryLIR;
2937 headLIR->defMask = ENCODE_ALL;
2938 }
2939
buzbee2cfc6392012-05-07 14:51:40 -07002940 switch(opcode) {
2941
2942 case llvm::Instruction::ICmp: {
2943 llvm::Instruction* nextInst = nextIt;
2944 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2945 if (brInst != NULL /* and... */) {
2946 cvtICmpBr(cUnit, inst, brInst);
2947 ++it;
2948 } else {
2949 cvtICmp(cUnit, inst);
2950 }
2951 }
2952 break;
2953
2954 case llvm::Instruction::Call: {
2955 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2956 llvm::Function* callee = callInst->getCalledFunction();
2957 greenland::IntrinsicHelper::IntrinsicId id =
2958 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2959 switch (id) {
buzbeeb03f4872012-06-11 15:22:11 -07002960 case greenland::IntrinsicHelper::AllocaShadowFrame:
2961 case greenland::IntrinsicHelper::SetShadowFrameEntry:
buzbee6969d502012-06-15 16:40:31 -07002962 case greenland::IntrinsicHelper::PopShadowFrame:
buzbeeb03f4872012-06-11 15:22:11 -07002963 // Ignore shadow frame stuff for quick compiler
2964 break;
buzbee2cfc6392012-05-07 14:51:40 -07002965 case greenland::IntrinsicHelper::CopyInt:
2966 case greenland::IntrinsicHelper::CopyObj:
2967 case greenland::IntrinsicHelper::CopyFloat:
2968 case greenland::IntrinsicHelper::CopyLong:
2969 case greenland::IntrinsicHelper::CopyDouble:
2970 cvtCopy(cUnit, callInst);
2971 break;
2972 case greenland::IntrinsicHelper::ConstInt:
2973 case greenland::IntrinsicHelper::ConstObj:
2974 case greenland::IntrinsicHelper::ConstLong:
2975 case greenland::IntrinsicHelper::ConstFloat:
2976 case greenland::IntrinsicHelper::ConstDouble:
2977 cvtConst(cUnit, callInst);
2978 break;
buzbee4f1181f2012-06-22 13:52:12 -07002979 case greenland::IntrinsicHelper::DivInt:
2980 case greenland::IntrinsicHelper::DivLong:
2981 cvtBinOp(cUnit, kOpDiv, inst);
2982 break;
2983 case greenland::IntrinsicHelper::RemInt:
2984 case greenland::IntrinsicHelper::RemLong:
2985 cvtBinOp(cUnit, kOpRem, inst);
2986 break;
buzbee2cfc6392012-05-07 14:51:40 -07002987 case greenland::IntrinsicHelper::MethodInfo:
buzbeead8f15e2012-06-18 14:49:45 -07002988 // Already dealt with - just ignore it here.
buzbee2cfc6392012-05-07 14:51:40 -07002989 break;
2990 case greenland::IntrinsicHelper::CheckSuspend:
2991 genSuspendTest(cUnit, 0 /* optFlags already applied */);
2992 break;
buzbee4f1181f2012-06-22 13:52:12 -07002993 case greenland::IntrinsicHelper::HLInvokeObj:
buzbee8fa0fda2012-06-27 15:44:52 -07002994 case greenland::IntrinsicHelper::HLInvokeFloat:
2995 case greenland::IntrinsicHelper::HLInvokeDouble:
2996 case greenland::IntrinsicHelper::HLInvokeLong:
2997 case greenland::IntrinsicHelper::HLInvokeInt:
buzbee101305f2012-06-28 18:00:56 -07002998 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
buzbee4f1181f2012-06-22 13:52:12 -07002999 break;
buzbee6969d502012-06-15 16:40:31 -07003000 case greenland::IntrinsicHelper::HLInvokeVoid:
buzbee101305f2012-06-28 18:00:56 -07003001 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
3002 break;
3003 case greenland::IntrinsicHelper::FilledNewArray:
3004 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
3005 break;
3006 case greenland::IntrinsicHelper::FillArrayData:
3007 cvtFillArrayData(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07003008 break;
3009 case greenland::IntrinsicHelper::ConstString:
buzbee101305f2012-06-28 18:00:56 -07003010 cvtConstObject(cUnit, callInst, true /* isString */);
3011 break;
3012 case greenland::IntrinsicHelper::ConstClass:
3013 cvtConstObject(cUnit, callInst, false /* isString */);
3014 break;
3015 case greenland::IntrinsicHelper::CheckCast:
3016 cvtCheckCast(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07003017 break;
buzbee4f1181f2012-06-22 13:52:12 -07003018 case greenland::IntrinsicHelper::NewInstance:
3019 cvtNewInstance(cUnit, callInst);
3020 break;
buzbee8fa0fda2012-06-27 15:44:52 -07003021 case greenland::IntrinsicHelper::HLSgetObject:
buzbee4f1181f2012-06-22 13:52:12 -07003022 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
3023 break;
buzbee8fa0fda2012-06-27 15:44:52 -07003024 case greenland::IntrinsicHelper::HLSget:
3025 case greenland::IntrinsicHelper::HLSgetFloat:
3026 case greenland::IntrinsicHelper::HLSgetBoolean:
3027 case greenland::IntrinsicHelper::HLSgetByte:
3028 case greenland::IntrinsicHelper::HLSgetChar:
3029 case greenland::IntrinsicHelper::HLSgetShort:
3030 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
3031 break;
3032 case greenland::IntrinsicHelper::HLSgetWide:
3033 case greenland::IntrinsicHelper::HLSgetDouble:
3034 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
3035 break;
buzbee76592632012-06-29 15:18:35 -07003036 case greenland::IntrinsicHelper::HLSput:
3037 case greenland::IntrinsicHelper::HLSputFloat:
3038 case greenland::IntrinsicHelper::HLSputBoolean:
3039 case greenland::IntrinsicHelper::HLSputByte:
3040 case greenland::IntrinsicHelper::HLSputChar:
3041 case greenland::IntrinsicHelper::HLSputShort:
3042 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
3043 break;
3044 case greenland::IntrinsicHelper::HLSputWide:
3045 case greenland::IntrinsicHelper::HLSputDouble:
3046 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
3047 break;
buzbeea1da8a52012-07-09 14:00:21 -07003048 case greenland::IntrinsicHelper::HLSputObject:
3049 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
3050 break;
buzbee32412962012-06-26 16:27:56 -07003051 case greenland::IntrinsicHelper::GetException:
3052 cvtMoveException(cUnit, callInst);
3053 break;
3054 case greenland::IntrinsicHelper::Throw:
3055 cvtThrow(cUnit, callInst);
3056 break;
buzbee8fa0fda2012-06-27 15:44:52 -07003057 case greenland::IntrinsicHelper::MonitorEnter:
3058 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
3059 break;
3060 case greenland::IntrinsicHelper::MonitorExit:
3061 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
3062 break;
3063 case greenland::IntrinsicHelper::ArrayLength:
buzbee76592632012-06-29 15:18:35 -07003064 cvtArrayLength(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07003065 break;
3066 case greenland::IntrinsicHelper::NewArray:
3067 cvtNewArray(cUnit, callInst);
3068 break;
3069 case greenland::IntrinsicHelper::InstanceOf:
3070 cvtInstanceOf(cUnit, callInst);
3071 break;
3072
3073 case greenland::IntrinsicHelper::HLArrayGet:
3074 case greenland::IntrinsicHelper::HLArrayGetObject:
3075 case greenland::IntrinsicHelper::HLArrayGetFloat:
3076 cvtAget(cUnit, callInst, kWord, 2);
3077 break;
3078 case greenland::IntrinsicHelper::HLArrayGetWide:
3079 case greenland::IntrinsicHelper::HLArrayGetDouble:
3080 cvtAget(cUnit, callInst, kLong, 3);
3081 break;
3082 case greenland::IntrinsicHelper::HLArrayGetBoolean:
3083 cvtAget(cUnit, callInst, kUnsignedByte, 0);
3084 break;
3085 case greenland::IntrinsicHelper::HLArrayGetByte:
3086 cvtAget(cUnit, callInst, kSignedByte, 0);
3087 break;
3088 case greenland::IntrinsicHelper::HLArrayGetChar:
3089 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
3090 break;
3091 case greenland::IntrinsicHelper::HLArrayGetShort:
3092 cvtAget(cUnit, callInst, kSignedHalf, 1);
3093 break;
3094
3095 case greenland::IntrinsicHelper::HLArrayPut:
buzbee8fa0fda2012-06-27 15:44:52 -07003096 case greenland::IntrinsicHelper::HLArrayPutFloat:
buzbeef1f86362012-07-10 15:18:31 -07003097 cvtAputPrimitive(cUnit, callInst, kWord, 2);
3098 break;
3099 case greenland::IntrinsicHelper::HLArrayPutObject:
3100 cvtAputObj(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07003101 break;
3102 case greenland::IntrinsicHelper::HLArrayPutWide:
3103 case greenland::IntrinsicHelper::HLArrayPutDouble:
buzbeef1f86362012-07-10 15:18:31 -07003104 cvtAputPrimitive(cUnit, callInst, kLong, 3);
buzbee8fa0fda2012-06-27 15:44:52 -07003105 break;
3106 case greenland::IntrinsicHelper::HLArrayPutBoolean:
buzbeef1f86362012-07-10 15:18:31 -07003107 cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
buzbee8fa0fda2012-06-27 15:44:52 -07003108 break;
3109 case greenland::IntrinsicHelper::HLArrayPutByte:
buzbeef1f86362012-07-10 15:18:31 -07003110 cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
buzbee8fa0fda2012-06-27 15:44:52 -07003111 break;
3112 case greenland::IntrinsicHelper::HLArrayPutChar:
buzbeef1f86362012-07-10 15:18:31 -07003113 cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
buzbee8fa0fda2012-06-27 15:44:52 -07003114 break;
3115 case greenland::IntrinsicHelper::HLArrayPutShort:
buzbeef1f86362012-07-10 15:18:31 -07003116 cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
buzbee8fa0fda2012-06-27 15:44:52 -07003117 break;
3118
buzbee101305f2012-06-28 18:00:56 -07003119 case greenland::IntrinsicHelper::HLIGet:
3120 case greenland::IntrinsicHelper::HLIGetFloat:
3121 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3122 break;
3123 case greenland::IntrinsicHelper::HLIGetObject:
3124 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3125 break;
3126 case greenland::IntrinsicHelper::HLIGetWide:
3127 case greenland::IntrinsicHelper::HLIGetDouble:
3128 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3129 break;
3130 case greenland::IntrinsicHelper::HLIGetBoolean:
3131 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
3132 false /* obj */);
3133 break;
3134 case greenland::IntrinsicHelper::HLIGetByte:
3135 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
3136 false /* obj */);
3137 break;
3138 case greenland::IntrinsicHelper::HLIGetChar:
3139 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3140 false /* obj */);
3141 break;
3142 case greenland::IntrinsicHelper::HLIGetShort:
3143 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
3144 false /* obj */);
3145 break;
3146
3147 case greenland::IntrinsicHelper::HLIPut:
3148 case greenland::IntrinsicHelper::HLIPutFloat:
3149 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3150 break;
3151 case greenland::IntrinsicHelper::HLIPutObject:
3152 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3153 break;
3154 case greenland::IntrinsicHelper::HLIPutWide:
3155 case greenland::IntrinsicHelper::HLIPutDouble:
3156 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3157 break;
3158 case greenland::IntrinsicHelper::HLIPutBoolean:
3159 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3160 false /* obj */);
3161 break;
3162 case greenland::IntrinsicHelper::HLIPutByte:
3163 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3164 false /* obj */);
3165 break;
3166 case greenland::IntrinsicHelper::HLIPutChar:
3167 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3168 false /* obj */);
3169 break;
3170 case greenland::IntrinsicHelper::HLIPutShort:
3171 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3172 false /* obj */);
3173 break;
3174
3175 case greenland::IntrinsicHelper::IntToChar:
3176 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3177 break;
3178 case greenland::IntrinsicHelper::IntToShort:
3179 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3180 break;
3181 case greenland::IntrinsicHelper::IntToByte:
3182 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3183 break;
3184
buzbee76592632012-06-29 15:18:35 -07003185 case greenland::IntrinsicHelper::CmplFloat:
3186 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3187 break;
3188 case greenland::IntrinsicHelper::CmpgFloat:
3189 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3190 break;
3191 case greenland::IntrinsicHelper::CmplDouble:
3192 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3193 break;
3194 case greenland::IntrinsicHelper::CmpgDouble:
3195 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3196 break;
3197
3198 case greenland::IntrinsicHelper::CmpLong:
3199 cvtLongCompare(cUnit, callInst);
3200 break;
3201
buzbee2a83e8f2012-07-13 16:42:30 -07003202 case greenland::IntrinsicHelper::SHLLong:
3203 cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
buzbee2cfc6392012-05-07 14:51:40 -07003204 break;
buzbee2a83e8f2012-07-13 16:42:30 -07003205 case greenland::IntrinsicHelper::SHRLong:
3206 cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
3207 break;
3208 case greenland::IntrinsicHelper::USHRLong:
3209 cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
3210 break;
3211 case greenland::IntrinsicHelper::SHLInt:
3212 cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
3213 break;
3214 case greenland::IntrinsicHelper::SHRInt:
3215 cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
3216 break;
3217 case greenland::IntrinsicHelper::USHRInt:
3218 cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
3219 break;
3220
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07003221 case greenland::IntrinsicHelper::CatchTargets: {
3222 llvm::SwitchInst* swInst =
3223 llvm::dyn_cast<llvm::SwitchInst>(nextIt);
3224 DCHECK(swInst != NULL);
3225 /*
3226 * Discard the edges and the following conditional branch.
3227 * Do a direct branch to the default target (which is the
3228 * "work" portion of the pair.
3229 * TODO: awful code layout - rework
3230 */
3231 llvm::BasicBlock* targetBB = swInst->getDefaultDest();
3232 DCHECK(targetBB != NULL);
3233 opUnconditionalBranch(cUnit,
3234 cUnit->blockToLabelMap.Get(targetBB));
3235 ++it;
3236 }
3237 break;
3238
buzbee2cfc6392012-05-07 14:51:40 -07003239 default:
3240 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
3241 << cUnit->intrinsic_helper->GetName(id);
3242 }
3243 }
3244 break;
3245
3246 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3247 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3248 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3249 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3250 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3251 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3252 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3253 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3254 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003255 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3256 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
buzbee4f1181f2012-06-22 13:52:12 -07003257 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3258 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3259 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3260 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3261 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
buzbee76592632012-06-29 15:18:35 -07003262 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
3263 case llvm::Instruction::FPToSI: cvtFPToInt(cUnit, inst); break;
3264 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3265 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3266 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003267
buzbee101305f2012-06-28 18:00:56 -07003268 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3269 break;
3270 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3271 break;
3272
buzbeef58c12c2012-07-03 15:06:29 -07003273 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3274
buzbee32412962012-06-26 16:27:56 -07003275 case llvm::Instruction::Unreachable:
3276 break; // FIXME: can we really ignore these?
3277
buzbee2a83e8f2012-07-13 16:42:30 -07003278 case llvm::Instruction::Shl:
3279 case llvm::Instruction::LShr:
3280 case llvm::Instruction::AShr:
buzbee2cfc6392012-05-07 14:51:40 -07003281 case llvm::Instruction::Invoke:
buzbee2cfc6392012-05-07 14:51:40 -07003282 case llvm::Instruction::FPToUI:
buzbee2cfc6392012-05-07 14:51:40 -07003283 case llvm::Instruction::UIToFP:
buzbee2cfc6392012-05-07 14:51:40 -07003284 case llvm::Instruction::PtrToInt:
3285 case llvm::Instruction::IntToPtr:
buzbee2cfc6392012-05-07 14:51:40 -07003286 case llvm::Instruction::FCmp:
buzbee2cfc6392012-05-07 14:51:40 -07003287 case llvm::Instruction::URem:
3288 case llvm::Instruction::UDiv:
3289 case llvm::Instruction::Resume:
buzbee2cfc6392012-05-07 14:51:40 -07003290 case llvm::Instruction::Alloca:
3291 case llvm::Instruction::GetElementPtr:
3292 case llvm::Instruction::Fence:
3293 case llvm::Instruction::AtomicCmpXchg:
3294 case llvm::Instruction::AtomicRMW:
3295 case llvm::Instruction::BitCast:
3296 case llvm::Instruction::VAArg:
3297 case llvm::Instruction::Select:
3298 case llvm::Instruction::UserOp1:
3299 case llvm::Instruction::UserOp2:
3300 case llvm::Instruction::ExtractElement:
3301 case llvm::Instruction::InsertElement:
3302 case llvm::Instruction::ShuffleVector:
3303 case llvm::Instruction::ExtractValue:
3304 case llvm::Instruction::InsertValue:
3305 case llvm::Instruction::LandingPad:
3306 case llvm::Instruction::IndirectBr:
3307 case llvm::Instruction::Load:
3308 case llvm::Instruction::Store:
3309 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3310
3311 default:
buzbee2a83e8f2012-07-13 16:42:30 -07003312 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3313 break;
buzbee2cfc6392012-05-07 14:51:40 -07003314 }
3315 }
buzbee6969d502012-06-15 16:40:31 -07003316
3317 if (headLIR != NULL) {
3318 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
3319 }
buzbee2cfc6392012-05-07 14:51:40 -07003320 return false;
3321}
3322
3323/*
3324 * Convert LLVM_IR to MIR:
3325 * o Iterate through the LLVM_IR and construct a graph using
3326 * standard MIR building blocks.
3327 * o Perform a basic-block optimization pass to remove unnecessary
3328 * store/load sequences.
3329 * o Convert the LLVM Value operands into RegLocations where applicable.
3330 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3331 * o Perform register promotion
3332 * o Iterate through the graph a basic block at a time, generating
3333 * LIR.
3334 * o Assemble LIR as usual.
3335 * o Profit.
3336 */
3337void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3338{
buzbeead8f15e2012-06-18 14:49:45 -07003339 llvm::Function* func = cUnit->func;
3340 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003341 // Allocate a list for LIR basic block labels
3342 cUnit->blockLabelList =
buzbeea1da8a52012-07-09 14:00:21 -07003343 (LIR*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3344 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003345 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003346 for (llvm::Function::iterator i = func->begin(),
3347 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003348 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3349 &labelList[nextLabel++]);
3350 }
buzbeead8f15e2012-06-18 14:49:45 -07003351
3352 /*
3353 * Keep honest - clear regLocations, Value => RegLocation,
3354 * promotion map and VmapTables.
3355 */
3356 cUnit->locMap.clear(); // Start fresh
3357 cUnit->regLocation = NULL;
3358 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3359 i++) {
3360 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3361 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3362 }
3363 cUnit->coreSpillMask = 0;
3364 cUnit->numCoreSpills = 0;
3365 cUnit->fpSpillMask = 0;
3366 cUnit->numFPSpills = 0;
3367 cUnit->coreVmapTable.clear();
3368 cUnit->fpVmapTable.clear();
buzbeead8f15e2012-06-18 14:49:45 -07003369
3370 /*
3371 * At this point, we've lost all knowledge of register promotion.
3372 * Rebuild that info from the MethodInfo intrinsic (if it
buzbeeca7a5e42012-08-20 11:12:18 -07003373 * exists - not required for correctness). Normally, this will
3374 * be the first instruction we encounter, so we won't have to iterate
3375 * through everything.
buzbeead8f15e2012-06-18 14:49:45 -07003376 */
buzbeeca7a5e42012-08-20 11:12:18 -07003377 for (llvm::inst_iterator i = llvm::inst_begin(func),
3378 e = llvm::inst_end(func); i != e; ++i) {
3379 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(&*i);
3380 if (callInst != NULL) {
3381 llvm::Function* callee = callInst->getCalledFunction();
3382 greenland::IntrinsicHelper::IntrinsicId id =
3383 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3384 if (id == greenland::IntrinsicHelper::MethodInfo) {
3385 if (cUnit->printMe) {
3386 LOG(INFO) << "Found MethodInfo";
3387 }
3388 llvm::MDNode* regInfoNode = callInst->getMetadata("RegInfo");
3389 if (regInfoNode != NULL) {
3390 llvm::ConstantInt* numInsValue =
3391 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(0));
3392 llvm::ConstantInt* numRegsValue =
3393 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(1));
3394 llvm::ConstantInt* numOutsValue =
3395 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(2));
3396 llvm::ConstantInt* numCompilerTempsValue =
3397 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(3));
3398 llvm::ConstantInt* numSSARegsValue =
3399 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(4));
3400 if (cUnit->printMe) {
3401 LOG(INFO) << "RegInfo - Ins:" << numInsValue->getZExtValue()
3402 << ", Regs:" << numRegsValue->getZExtValue()
3403 << ", Outs:" << numOutsValue->getZExtValue()
3404 << ", CTemps:" << numCompilerTempsValue->getZExtValue()
3405 << ", SSARegs:" << numSSARegsValue->getZExtValue();
3406 }
3407 }
3408 llvm::MDNode* pmapInfoNode = callInst->getMetadata("PromotionMap");
3409 if (pmapInfoNode != NULL) {
3410 int elems = pmapInfoNode->getNumOperands();
3411 if (cUnit->printMe) {
3412 LOG(INFO) << "PMap size: " << elems;
3413 }
3414 for (int i = 0; i < elems; i++) {
3415 llvm::ConstantInt* rawMapData =
3416 static_cast<llvm::ConstantInt*>(pmapInfoNode->getOperand(i));
3417 uint32_t mapData = rawMapData->getZExtValue();
3418 PromotionMap* p = &cUnit->promotionMap[i];
3419 p->firstInPair = (mapData >> 24) & 0xff;
3420 p->fpReg = (mapData >> 16) & 0xff;
3421 p->coreReg = (mapData >> 8) & 0xff;
3422 p->fpLocation = static_cast<RegLocationType>((mapData >> 4) & 0xf);
3423 if (p->fpLocation == kLocPhysReg) {
3424 oatRecordFpPromotion(cUnit, p->fpReg, i);
3425 }
3426 p->coreLocation = static_cast<RegLocationType>(mapData & 0xf);
3427 if (p->coreLocation == kLocPhysReg) {
3428 oatRecordCorePromotion(cUnit, p->coreReg, i);
3429 }
3430 }
3431 if (cUnit->printMe) {
3432 oatDumpPromotionMap(cUnit);
3433 }
3434 }
3435 break;
3436 }
3437 }
3438 }
3439 oatAdjustSpillMask(cUnit);
3440 cUnit->frameSize = oatComputeFrameSize(cUnit);
buzbeead8f15e2012-06-18 14:49:45 -07003441
3442 // Create RegLocations for arguments
3443 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3444 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3445 for (; it != it_end; ++it) {
3446 llvm::Value* val = it;
3447 createLocFromValue(cUnit, val);
3448 }
3449 // Create RegLocations for all non-argument defintions
3450 for (llvm::inst_iterator i = llvm::inst_begin(func),
3451 e = llvm::inst_end(func); i != e; ++i) {
3452 llvm::Value* val = &*i;
3453 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3454 createLocFromValue(cUnit, val);
3455 }
3456 }
3457
buzbee2cfc6392012-05-07 14:51:40 -07003458 // Walk the blocks, generating code.
3459 for (llvm::Function::iterator i = cUnit->func->begin(),
3460 e = cUnit->func->end(); i != e; ++i) {
3461 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3462 }
3463
3464 handleSuspendLaunchpads(cUnit);
3465
3466 handleThrowLaunchpads(cUnit);
3467
3468 handleIntrinsicLaunchpads(cUnit);
3469
buzbee692be802012-08-29 15:52:59 -07003470 cUnit->func->eraseFromParent();
3471 cUnit->func = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07003472}
3473
3474
3475} // namespace art
3476
3477#endif // ART_USE_QUICK_COMPILER