blob: c4e1b9ddf306c0c872ec740cef27ad08a93aca30 [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
buzbee8320f382012-09-11 16:29:42 -070032static const char* kLabelFormat = "%c0x%x_%d";
33static const char kNormalBlock = 'L';
34static const char kCatchBlock = 'C';
buzbee2cfc6392012-05-07 14:51:40 -070035
36namespace art {
37extern const RegLocation badLoc;
buzbeeb03f4872012-06-11 15:22:11 -070038RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val);
buzbee2cfc6392012-05-07 14:51:40 -070039
40llvm::BasicBlock* getLLVMBlock(CompilationUnit* cUnit, int id)
41{
42 return cUnit->idToBlockMap.Get(id);
43}
44
45llvm::Value* getLLVMValue(CompilationUnit* cUnit, int sReg)
46{
47 return (llvm::Value*)oatGrowableListGetElement(&cUnit->llvmValues, sReg);
48}
49
50// Replace the placeholder value with the real definition
51void defineValue(CompilationUnit* cUnit, llvm::Value* val, int sReg)
52{
53 llvm::Value* placeholder = getLLVMValue(cUnit, sReg);
buzbee9a2487f2012-07-26 14:01:13 -070054 if (placeholder == NULL) {
55 // This can happen on instruction rewrite on verification failure
Bill Buzbeec9f40dd2012-08-15 11:35:25 -070056 LOG(WARNING) << "Null placeholder";
buzbee9a2487f2012-07-26 14:01:13 -070057 return;
58 }
buzbee2cfc6392012-05-07 14:51:40 -070059 placeholder->replaceAllUsesWith(val);
60 val->takeName(placeholder);
61 cUnit->llvmValues.elemList[sReg] = (intptr_t)val;
buzbee4be777b2012-07-12 14:38:18 -070062 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(placeholder);
63 DCHECK(inst != NULL);
64 inst->eraseFromParent();
buzbee2cfc6392012-05-07 14:51:40 -070065}
66
67llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
68{
69 llvm::Type* res = NULL;
70 if (loc.wide) {
71 if (loc.fp)
buzbee4f1181f2012-06-22 13:52:12 -070072 res = cUnit->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070073 else
buzbee4f1181f2012-06-22 13:52:12 -070074 res = cUnit->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070075 } else {
76 if (loc.fp) {
buzbee4f1181f2012-06-22 13:52:12 -070077 res = cUnit->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -070078 } else {
79 if (loc.ref)
80 res = cUnit->irb->GetJObjectTy();
81 else
buzbee4f1181f2012-06-22 13:52:12 -070082 res = cUnit->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -070083 }
84 }
85 return res;
86}
87
buzbeead8f15e2012-06-18 14:49:45 -070088/* Create an in-memory RegLocation from an llvm Value. */
89void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val)
90{
91 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
92 std::string s(val->getName().str());
93 const char* valName = s.c_str();
buzbeead8f15e2012-06-18 14:49:45 -070094 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
95 DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName;
96 int baseSReg = INVALID_SREG;
97 int subscript = -1;
98 sscanf(valName, "v%d_%d", &baseSReg, &subscript);
99 if ((baseSReg == INVALID_SREG) && (!strcmp(valName, "method"))) {
100 baseSReg = SSA_METHOD_BASEREG;
101 subscript = 0;
102 }
buzbeead8f15e2012-06-18 14:49:45 -0700103 DCHECK_NE(baseSReg, INVALID_SREG);
104 DCHECK_NE(subscript, -1);
105 // TODO: redo during C++'ification
106 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
107 INVALID_REG, INVALID_SREG, INVALID_SREG};
108 llvm::Type* ty = val->getType();
109 loc.wide = ((ty == cUnit->irb->getInt64Ty()) ||
110 (ty == cUnit->irb->getDoubleTy()));
111 loc.defined = true;
buzbeeca7a5e42012-08-20 11:12:18 -0700112 loc.home = false; // May change during promotion
buzbeead8f15e2012-06-18 14:49:45 -0700113 loc.sRegLow = baseSReg;
114 loc.origSReg = cUnit->locMap.size();
buzbeeca7a5e42012-08-20 11:12:18 -0700115 PromotionMap pMap = cUnit->promotionMap[baseSReg];
116 if (ty == cUnit->irb->getFloatTy()) {
117 loc.fp = true;
118 if (pMap.fpLocation == kLocPhysReg) {
119 loc.lowReg = pMap.fpReg;
120 loc.location = kLocPhysReg;
121 loc.home = true;
122 }
123 } else if (ty == cUnit->irb->getDoubleTy()) {
124 loc.fp = true;
125 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
126 if ((pMap.fpLocation == kLocPhysReg) &&
127 (pMapHigh.fpLocation == kLocPhysReg) &&
128 ((pMap.fpReg & 0x1) == 0) &&
129 (pMap.fpReg + 1 == pMapHigh.fpReg)) {
130 loc.lowReg = pMap.fpReg;
131 loc.highReg = pMapHigh.fpReg;
132 loc.location = kLocPhysReg;
133 loc.home = true;
134 }
135 } else if (ty == cUnit->irb->GetJObjectTy()) {
136 loc.ref = true;
137 if (pMap.coreLocation == kLocPhysReg) {
138 loc.lowReg = pMap.coreReg;
139 loc.location = kLocPhysReg;
140 loc.home = true;
141 }
142 } else if (ty == cUnit->irb->getInt64Ty()) {
143 loc.core = true;
144 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
145 if ((pMap.coreLocation == kLocPhysReg) &&
146 (pMapHigh.coreLocation == kLocPhysReg)) {
147 loc.lowReg = pMap.coreReg;
148 loc.highReg = pMapHigh.coreReg;
149 loc.location = kLocPhysReg;
150 loc.home = true;
151 }
152 } else {
153 loc.core = true;
154 if (pMap.coreLocation == kLocPhysReg) {
155 loc.lowReg = pMap.coreReg;
156 loc.location = kLocPhysReg;
157 loc.home = true;
158 }
159 }
160
161 if (cUnit->printMe && loc.home) {
162 if (loc.wide) {
163 LOG(INFO) << "Promoted wide " << s << " to regs " << loc.lowReg
164 << "/" << loc.highReg;
165 } else {
166 LOG(INFO) << "Promoted " << s << " to reg " << loc.lowReg;
167 }
168 }
buzbeead8f15e2012-06-18 14:49:45 -0700169 cUnit->locMap.Put(val, loc);
170}
buzbee2cfc6392012-05-07 14:51:40 -0700171void initIR(CompilationUnit* cUnit)
172{
buzbee692be802012-08-29 15:52:59 -0700173 QuickCompiler* quick =
174 reinterpret_cast<QuickCompiler*>(cUnit->compiler->GetCompilerContext());
175 cUnit->context = quick->GetLLVMContext();
176 cUnit->module = quick->GetLLVMModule();
177 cUnit->intrinsic_helper = quick->GetIntrinsicHelper();
178 cUnit->irb = quick->GetIRBuilder();
buzbee2cfc6392012-05-07 14:51:40 -0700179}
180
181const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
182 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
183}
184
buzbeef58c12c2012-07-03 15:06:29 -0700185llvm::BasicBlock* findCaseTarget(CompilationUnit* cUnit, uint32_t vaddr)
186{
187 BasicBlock* bb = oatFindBlock(cUnit, vaddr);
188 DCHECK(bb != NULL);
189 return getLLVMBlock(cUnit, bb->id);
190}
191
192void convertPackedSwitch(CompilationUnit* cUnit, BasicBlock* bb,
193 int32_t tableOffset, RegLocation rlSrc)
194{
195 const Instruction::PackedSwitchPayload* payload =
196 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
197 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
198
199 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
200
201 llvm::SwitchInst* sw =
202 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
203 payload->case_count);
204
205 for (uint16_t i = 0; i < payload->case_count; ++i) {
206 llvm::BasicBlock* llvmBB =
207 findCaseTarget(cUnit, cUnit->currentDalvikOffset + payload->targets[i]);
208 sw->addCase(cUnit->irb->getInt32(payload->first_key + i), llvmBB);
209 }
210 llvm::MDNode* switchNode =
211 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
212 sw->setMetadata("SwitchTable", switchNode);
213 bb->taken = NULL;
214 bb->fallThrough = NULL;
215}
216
buzbeea1da8a52012-07-09 14:00:21 -0700217void convertSparseSwitch(CompilationUnit* cUnit, BasicBlock* bb,
218 int32_t tableOffset, RegLocation rlSrc)
219{
220 const Instruction::SparseSwitchPayload* payload =
221 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
222 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
223
224 const int32_t* keys = payload->GetKeys();
225 const int32_t* targets = payload->GetTargets();
226
227 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
228
229 llvm::SwitchInst* sw =
230 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
231 payload->case_count);
232
233 for (size_t i = 0; i < payload->case_count; ++i) {
234 llvm::BasicBlock* llvmBB =
235 findCaseTarget(cUnit, cUnit->currentDalvikOffset + targets[i]);
236 sw->addCase(cUnit->irb->getInt32(keys[i]), llvmBB);
237 }
238 llvm::MDNode* switchNode =
239 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
240 sw->setMetadata("SwitchTable", switchNode);
241 bb->taken = NULL;
242 bb->fallThrough = NULL;
243}
244
buzbee8fa0fda2012-06-27 15:44:52 -0700245void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
246 greenland::IntrinsicHelper::IntrinsicId id,
247 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700248{
buzbee8fa0fda2012-06-27 15:44:52 -0700249 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700250 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700251 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
252 defineValue(cUnit, res, rlDest.origSReg);
253}
254
255void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
256 greenland::IntrinsicHelper::IntrinsicId id,
257 RegLocation rlSrc)
258{
259 llvm::SmallVector<llvm::Value*, 2> args;
260 args.push_back(cUnit->irb->getInt32(fieldIndex));
261 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
262 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
263 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700264}
265
buzbee101305f2012-06-28 18:00:56 -0700266void convertFillArrayData(CompilationUnit* cUnit, int32_t offset,
267 RegLocation rlArray)
268{
269 greenland::IntrinsicHelper::IntrinsicId id;
270 id = greenland::IntrinsicHelper::FillArrayData;
271 llvm::SmallVector<llvm::Value*, 2> args;
272 args.push_back(cUnit->irb->getInt32(offset));
273 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
274 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
275 cUnit->irb->CreateCall(intr, args);
276}
277
buzbee2cfc6392012-05-07 14:51:40 -0700278llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
279 RegLocation loc)
280{
281 greenland::IntrinsicHelper::IntrinsicId id;
282 if (loc.wide) {
283 if (loc.fp) {
284 id = greenland::IntrinsicHelper::ConstDouble;
285 } else {
286 id = greenland::IntrinsicHelper::ConstLong;
287 }
288 } else {
289 if (loc.fp) {
290 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700291 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700292 id = greenland::IntrinsicHelper::ConstObj;
293 } else {
294 id = greenland::IntrinsicHelper::ConstInt;
295 }
296 }
297 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
298 return cUnit->irb->CreateCall(intr, src);
299}
buzbeeb03f4872012-06-11 15:22:11 -0700300
301void emitPopShadowFrame(CompilationUnit* cUnit)
302{
303 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
304 greenland::IntrinsicHelper::PopShadowFrame);
305 cUnit->irb->CreateCall(intr);
306}
307
buzbee2cfc6392012-05-07 14:51:40 -0700308llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
309 RegLocation loc)
310{
311 greenland::IntrinsicHelper::IntrinsicId id;
312 if (loc.wide) {
313 if (loc.fp) {
314 id = greenland::IntrinsicHelper::CopyDouble;
315 } else {
316 id = greenland::IntrinsicHelper::CopyLong;
317 }
318 } else {
319 if (loc.fp) {
320 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700321 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700322 id = greenland::IntrinsicHelper::CopyObj;
323 } else {
324 id = greenland::IntrinsicHelper::CopyInt;
325 }
326 }
327 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
328 return cUnit->irb->CreateCall(intr, src);
329}
330
buzbee32412962012-06-26 16:27:56 -0700331void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
332{
333 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
334 greenland::IntrinsicHelper::GetException);
335 llvm::Value* res = cUnit->irb->CreateCall(func);
336 defineValue(cUnit, res, rlDest.origSReg);
337}
338
339void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
340{
341 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
342 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
343 greenland::IntrinsicHelper::Throw);
344 cUnit->irb->CreateCall(func, src);
buzbee32412962012-06-26 16:27:56 -0700345}
346
buzbee8fa0fda2012-06-27 15:44:52 -0700347void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
348 greenland::IntrinsicHelper::IntrinsicId id,
349 RegLocation rlSrc)
350{
351 llvm::SmallVector<llvm::Value*, 2> args;
352 args.push_back(cUnit->irb->getInt32(optFlags));
353 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
354 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
355 cUnit->irb->CreateCall(func, args);
356}
357
buzbee76592632012-06-29 15:18:35 -0700358void convertArrayLength(CompilationUnit* cUnit, int optFlags,
359 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700360{
361 llvm::SmallVector<llvm::Value*, 2> args;
362 args.push_back(cUnit->irb->getInt32(optFlags));
363 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
364 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
365 greenland::IntrinsicHelper::ArrayLength);
buzbee76592632012-06-29 15:18:35 -0700366 llvm::Value* res = cUnit->irb->CreateCall(func, args);
367 defineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700368}
369
buzbee2cfc6392012-05-07 14:51:40 -0700370void emitSuspendCheck(CompilationUnit* cUnit)
371{
372 greenland::IntrinsicHelper::IntrinsicId id =
373 greenland::IntrinsicHelper::CheckSuspend;
374 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
375 cUnit->irb->CreateCall(intr);
376}
377
378llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
379 llvm::Value* src1, llvm::Value* src2)
380{
381 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700382 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700383 switch(cc) {
384 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
385 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
386 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
387 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
388 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
389 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
390 default: LOG(FATAL) << "Unexpected cc value " << cc;
391 }
392 return res;
393}
394
395void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
396 ConditionCode cc, RegLocation rlSrc1,
397 RegLocation rlSrc2)
398{
399 if (bb->taken->startOffset <= mir->offset) {
400 emitSuspendCheck(cUnit);
401 }
402 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
403 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
404 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
405 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
406 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
407 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700408 // Don't redo the fallthrough branch in the BB driver
409 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700410}
411
412void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
413 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
414{
415 if (bb->taken->startOffset <= mir->offset) {
416 emitSuspendCheck(cUnit);
417 }
418 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
419 llvm::Value* src2;
420 if (rlSrc1.ref) {
421 src2 = cUnit->irb->GetJNull();
422 } else {
423 src2 = cUnit->irb->getInt32(0);
424 }
425 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
buzbee2cfc6392012-05-07 14:51:40 -0700426 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
427 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700428 // Don't redo the fallthrough branch in the BB driver
429 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700430}
431
432llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
433 llvm::Value* src1, llvm::Value* src2)
434{
435 greenland::IntrinsicHelper::IntrinsicId id;
436 if (isLong) {
437 if (isDiv) {
438 id = greenland::IntrinsicHelper::DivLong;
439 } else {
440 id = greenland::IntrinsicHelper::RemLong;
441 }
442 } else if (isDiv) {
443 id = greenland::IntrinsicHelper::DivInt;
444 } else {
445 id = greenland::IntrinsicHelper::RemInt;
446 }
447 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
448 llvm::SmallVector<llvm::Value*, 2>args;
449 args.push_back(src1);
450 args.push_back(src2);
451 return cUnit->irb->CreateCall(intr, args);
452}
453
454llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
455 llvm::Value* src1, llvm::Value* src2)
456{
457 llvm::Value* res = NULL;
458 switch(op) {
459 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
460 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700461 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700462 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
463 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
464 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
465 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
466 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
467 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700468 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
469 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
470 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700471 default:
472 LOG(FATAL) << "Invalid op " << op;
473 }
474 return res;
475}
476
477void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
478 RegLocation rlSrc1, RegLocation rlSrc2)
479{
480 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
481 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
482 llvm::Value* res = NULL;
483 switch(op) {
484 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
485 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
486 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
487 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
488 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
489 default:
490 LOG(FATAL) << "Invalid op " << op;
491 }
492 defineValue(cUnit, res, rlDest.origSReg);
493}
494
buzbee2a83e8f2012-07-13 16:42:30 -0700495void convertShift(CompilationUnit* cUnit,
496 greenland::IntrinsicHelper::IntrinsicId id,
497 RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2)
buzbee4f1181f2012-06-22 13:52:12 -0700498{
buzbee2a83e8f2012-07-13 16:42:30 -0700499 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
500 llvm::SmallVector<llvm::Value*, 2>args;
501 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
502 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
503 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
504 defineValue(cUnit, res, rlDest.origSReg);
505}
506
507void convertShiftLit(CompilationUnit* cUnit,
508 greenland::IntrinsicHelper::IntrinsicId id,
509 RegLocation rlDest, RegLocation rlSrc, int shiftAmount)
510{
511 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
512 llvm::SmallVector<llvm::Value*, 2>args;
513 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
514 args.push_back(cUnit->irb->getInt32(shiftAmount));
515 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700516 defineValue(cUnit, res, rlDest.origSReg);
517}
518
buzbee2cfc6392012-05-07 14:51:40 -0700519void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
520 RegLocation rlSrc1, RegLocation rlSrc2)
521{
522 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
523 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700524 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700525 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
526 defineValue(cUnit, res, rlDest.origSReg);
527}
528
buzbeeb03f4872012-06-11 15:22:11 -0700529void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
530{
531 int index = -1;
532 DCHECK(newVal != NULL);
533 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
534 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
535 if (cUnit->shadowMap[i] == vReg) {
536 index = i;
537 break;
538 }
539 }
Elliott Hughes74847412012-06-20 18:10:21 -0700540 DCHECK_NE(index, -1) << "Corrupt shadowMap";
buzbeeb03f4872012-06-11 15:22:11 -0700541 greenland::IntrinsicHelper::IntrinsicId id =
542 greenland::IntrinsicHelper::SetShadowFrameEntry;
543 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
544 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
545 llvm::Value* args[] = { newVal, tableSlot };
546 cUnit->irb->CreateCall(func, args);
547}
548
buzbee2cfc6392012-05-07 14:51:40 -0700549void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
550 RegLocation rlSrc1, int32_t imm)
551{
552 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
553 llvm::Value* src2 = cUnit->irb->getInt32(imm);
554 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
555 defineValue(cUnit, res, rlDest.origSReg);
556}
557
buzbee101305f2012-06-28 18:00:56 -0700558/*
559 * Process arguments for invoke. Note: this code is also used to
560 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
561 * The requirements are similar.
562 */
buzbee6969d502012-06-15 16:40:31 -0700563void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700564 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700565{
566 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
567 llvm::SmallVector<llvm::Value*, 10> args;
568 // Insert the invokeType
569 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
570 // Insert the method_idx
571 args.push_back(cUnit->irb->getInt32(info->index));
572 // Insert the optimization flags
573 args.push_back(cUnit->irb->getInt32(info->optFlags));
574 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700575 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700576 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
577 args.push_back(val);
578 i += info->args[i].wide ? 2 : 1;
579 }
580 /*
581 * Choose the invoke return type based on actual usage. Note: may
582 * be different than shorty. For example, if a function return value
583 * is not used, we'll treat this as a void invoke.
584 */
585 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700586 if (isFilledNewArray) {
587 id = greenland::IntrinsicHelper::FilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700588 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700589 id = greenland::IntrinsicHelper::HLInvokeVoid;
590 } else {
591 if (info->result.wide) {
592 if (info->result.fp) {
593 id = greenland::IntrinsicHelper::HLInvokeDouble;
594 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700595 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700596 }
597 } else if (info->result.ref) {
598 id = greenland::IntrinsicHelper::HLInvokeObj;
599 } else if (info->result.fp) {
600 id = greenland::IntrinsicHelper::HLInvokeFloat;
601 } else {
602 id = greenland::IntrinsicHelper::HLInvokeInt;
603 }
604 }
605 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
606 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
607 if (info->result.location != kLocInvalid) {
608 defineValue(cUnit, res, info->result.origSReg);
609 }
610}
611
buzbee101305f2012-06-28 18:00:56 -0700612void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
613 greenland::IntrinsicHelper::IntrinsicId id,
614 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700615{
buzbee6969d502012-06-15 16:40:31 -0700616 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700617 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700618 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
619 defineValue(cUnit, res, rlDest.origSReg);
620}
621
buzbee101305f2012-06-28 18:00:56 -0700622void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
623 RegLocation rlSrc)
624{
625 greenland::IntrinsicHelper::IntrinsicId id;
626 id = greenland::IntrinsicHelper::CheckCast;
627 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
628 llvm::SmallVector<llvm::Value*, 2> args;
629 args.push_back(cUnit->irb->getInt32(type_idx));
630 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
631 cUnit->irb->CreateCall(intr, args);
632}
633
buzbee8fa0fda2012-06-27 15:44:52 -0700634void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
635 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700636{
637 greenland::IntrinsicHelper::IntrinsicId id;
638 id = greenland::IntrinsicHelper::NewInstance;
639 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
640 llvm::Value* index = cUnit->irb->getInt32(type_idx);
641 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
642 defineValue(cUnit, res, rlDest.origSReg);
643}
644
buzbee8fa0fda2012-06-27 15:44:52 -0700645void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
646 RegLocation rlDest, RegLocation rlSrc)
647{
648 greenland::IntrinsicHelper::IntrinsicId id;
649 id = greenland::IntrinsicHelper::NewArray;
650 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
651 llvm::SmallVector<llvm::Value*, 2> args;
652 args.push_back(cUnit->irb->getInt32(type_idx));
653 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
654 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
655 defineValue(cUnit, res, rlDest.origSReg);
656}
657
658void convertAget(CompilationUnit* cUnit, int optFlags,
659 greenland::IntrinsicHelper::IntrinsicId id,
660 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
661{
662 llvm::SmallVector<llvm::Value*, 3> args;
663 args.push_back(cUnit->irb->getInt32(optFlags));
664 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
665 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
666 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
667 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
668 defineValue(cUnit, res, rlDest.origSReg);
669}
670
671void convertAput(CompilationUnit* cUnit, int optFlags,
672 greenland::IntrinsicHelper::IntrinsicId id,
673 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
674{
675 llvm::SmallVector<llvm::Value*, 4> args;
676 args.push_back(cUnit->irb->getInt32(optFlags));
677 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
678 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
679 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
680 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
681 cUnit->irb->CreateCall(intr, args);
682}
683
buzbee101305f2012-06-28 18:00:56 -0700684void convertIget(CompilationUnit* cUnit, int optFlags,
685 greenland::IntrinsicHelper::IntrinsicId id,
686 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
687{
688 llvm::SmallVector<llvm::Value*, 3> args;
689 args.push_back(cUnit->irb->getInt32(optFlags));
690 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
691 args.push_back(cUnit->irb->getInt32(fieldIndex));
692 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
693 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
694 defineValue(cUnit, res, rlDest.origSReg);
695}
696
697void convertIput(CompilationUnit* cUnit, int optFlags,
698 greenland::IntrinsicHelper::IntrinsicId id,
699 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
700{
701 llvm::SmallVector<llvm::Value*, 4> args;
702 args.push_back(cUnit->irb->getInt32(optFlags));
703 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
704 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
705 args.push_back(cUnit->irb->getInt32(fieldIndex));
706 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
707 cUnit->irb->CreateCall(intr, args);
708}
709
buzbee8fa0fda2012-06-27 15:44:52 -0700710void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
711 RegLocation rlDest, RegLocation rlSrc)
712{
713 greenland::IntrinsicHelper::IntrinsicId id;
714 id = greenland::IntrinsicHelper::InstanceOf;
715 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
716 llvm::SmallVector<llvm::Value*, 2> args;
717 args.push_back(cUnit->irb->getInt32(type_idx));
718 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
719 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
720 defineValue(cUnit, res, rlDest.origSReg);
721}
722
buzbee101305f2012-06-28 18:00:56 -0700723void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
724 RegLocation rlSrc)
725{
726 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
727 cUnit->irb->getInt64Ty());
728 defineValue(cUnit, res, rlDest.origSReg);
729}
730
buzbee76592632012-06-29 15:18:35 -0700731void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
732 RegLocation rlSrc)
733{
734 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
735 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
736 defineValue(cUnit, res, rlDest.origSReg);
737}
738
739void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
740 RegLocation rlSrc)
741{
742 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
743 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
744 defineValue(cUnit, res, rlDest.origSReg);
745}
746
747void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
748 RegLocation rlSrc)
749{
750 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
751 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
752 defineValue(cUnit, res, rlDest.origSReg);
753}
754
755void convertWideComparison(CompilationUnit* cUnit,
756 greenland::IntrinsicHelper::IntrinsicId id,
757 RegLocation rlDest, RegLocation rlSrc1,
758 RegLocation rlSrc2)
759{
760 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
761 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
762 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
763 llvm::SmallVector<llvm::Value*, 2> args;
764 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
765 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
766 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
767 defineValue(cUnit, res, rlDest.origSReg);
768}
769
buzbee101305f2012-06-28 18:00:56 -0700770void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
771 RegLocation rlSrc,
772 greenland::IntrinsicHelper::IntrinsicId id)
773{
774 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700775 llvm::Value* res =
776 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
777 defineValue(cUnit, res, rlDest.origSReg);
778}
779
780void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
781 RegLocation rlSrc)
782{
783 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
784 defineValue(cUnit, res, rlDest.origSReg);
785}
786
787void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
788 RegLocation rlSrc)
789{
790 llvm::Value* res =
791 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
792 defineValue(cUnit, res, rlDest.origSReg);
793}
794
795void convertFPToInt(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
796 RegLocation rlSrc)
797{
798 llvm::Value* res =
799 cUnit->irb->CreateFPToSI(getLLVMValue(cUnit, rlSrc.origSReg), ty);
800 defineValue(cUnit, res, rlDest.origSReg);
801}
802
803
804void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
805 RegLocation rlSrc)
806{
807 llvm::Value* res =
808 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
809 defineValue(cUnit, res, rlDest.origSReg);
810}
811
812void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
813 RegLocation rlSrc)
814{
815 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
816 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700817 defineValue(cUnit, res, rlDest.origSReg);
818}
819
buzbee2cfc6392012-05-07 14:51:40 -0700820/*
821 * Target-independent code generation. Use only high-level
822 * load/store utilities here, or target-dependent genXX() handlers
823 * when necessary.
824 */
825bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
826 llvm::BasicBlock* llvmBB, LIR* labelList)
827{
828 bool res = false; // Assume success
829 RegLocation rlSrc[3];
830 RegLocation rlDest = badLoc;
buzbee2cfc6392012-05-07 14:51:40 -0700831 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee6969d502012-06-15 16:40:31 -0700832 uint32_t vB = mir->dalvikInsn.vB;
833 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700834 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700835
buzbeeb03f4872012-06-11 15:22:11 -0700836 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700837
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700838 if (cUnit->printMe) {
839 if ((int)opcode < kMirOpFirst) {
840 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x"
841 << std::hex << (int)opcode;
842 } else {
843 LOG(INFO) << ".. opcode 0x" << std::hex << (int)opcode;
844 }
845 }
846
buzbee2cfc6392012-05-07 14:51:40 -0700847 /* Prep Src and Dest locations */
848 int nextSreg = 0;
849 int nextLoc = 0;
850 int attrs = oatDataFlowAttributes[opcode];
851 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
852 if (attrs & DF_UA) {
853 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700854 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700855 nextSreg+= 2;
856 } else {
857 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
858 nextSreg++;
859 }
860 }
861 if (attrs & DF_UB) {
862 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700863 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700864 nextSreg+= 2;
865 } else {
866 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
867 nextSreg++;
868 }
869 }
870 if (attrs & DF_UC) {
871 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700872 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700873 } else {
874 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
875 }
876 }
877 if (attrs & DF_DA) {
878 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700879 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700880 } else {
buzbee15bf9802012-06-12 17:49:27 -0700881 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700882 if (rlDest.ref) {
883 objectDefinition = true;
884 }
buzbee2cfc6392012-05-07 14:51:40 -0700885 }
886 }
887
888 switch (opcode) {
889 case Instruction::NOP:
890 break;
891
892 case Instruction::MOVE:
893 case Instruction::MOVE_OBJECT:
894 case Instruction::MOVE_16:
895 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700896 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700897 case Instruction::MOVE_FROM16:
898 case Instruction::MOVE_WIDE:
899 case Instruction::MOVE_WIDE_16:
900 case Instruction::MOVE_WIDE_FROM16: {
901 /*
902 * Moves/copies are meaningless in pure SSA register form,
903 * but we need to preserve them for the conversion back into
904 * MIR (at least until we stop using the Dalvik register maps).
905 * Insert a dummy intrinsic copy call, which will be recognized
906 * by the quick path and removed by the portable path.
907 */
908 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
909 llvm::Value* res = emitCopy(cUnit, src, rlDest);
910 defineValue(cUnit, res, rlDest.origSReg);
911 }
912 break;
913
914 case Instruction::CONST:
915 case Instruction::CONST_4:
916 case Instruction::CONST_16: {
buzbee6969d502012-06-15 16:40:31 -0700917 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700918 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
919 defineValue(cUnit, res, rlDest.origSReg);
920 }
921 break;
922
923 case Instruction::CONST_WIDE_16:
924 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700925 // Sign extend to 64 bits
926 int64_t imm = static_cast<int32_t>(vB);
927 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700928 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
929 defineValue(cUnit, res, rlDest.origSReg);
930 }
931 break;
932
933 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700934 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700935 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
936 defineValue(cUnit, res, rlDest.origSReg);
937 }
938 break;
939
940 case Instruction::CONST_WIDE: {
941 llvm::Constant* immValue =
942 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
943 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
944 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700945 }
946 break;
buzbee2cfc6392012-05-07 14:51:40 -0700947 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700948 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700949 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
950 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
951 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700952 }
953 break;
954
buzbee8fa0fda2012-06-27 15:44:52 -0700955 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700956 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700957 rlSrc[0]);
958 break;
959 case Instruction::SPUT:
960 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700961 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700962 rlSrc[0]);
963 } else {
buzbee76592632012-06-29 15:18:35 -0700964 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700965 }
966 break;
967 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700968 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700969 rlSrc[0]);
970 break;
971 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700972 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700973 break;
974 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -0700975 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700976 break;
977 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -0700978 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700979 break;
980 case Instruction::SPUT_WIDE:
981 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700982 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -0700983 rlSrc[0]);
984 } else {
buzbee76592632012-06-29 15:18:35 -0700985 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -0700986 rlSrc[0]);
987 }
988 break;
989
990 case Instruction::SGET_OBJECT:
991 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
992 break;
993 case Instruction::SGET:
994 if (rlDest.fp) {
995 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
996 } else {
997 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
998 }
999 break;
1000 case Instruction::SGET_BOOLEAN:
1001 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
1002 break;
1003 case Instruction::SGET_BYTE:
1004 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
1005 break;
1006 case Instruction::SGET_CHAR:
1007 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
1008 break;
1009 case Instruction::SGET_SHORT:
1010 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
1011 break;
1012 case Instruction::SGET_WIDE:
1013 if (rlDest.fp) {
1014 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
1015 rlDest);
1016 } else {
1017 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001018 }
1019 break;
buzbee2cfc6392012-05-07 14:51:40 -07001020
1021 case Instruction::RETURN_WIDE:
1022 case Instruction::RETURN:
1023 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -07001024 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001025 emitSuspendCheck(cUnit);
1026 }
buzbeeb03f4872012-06-11 15:22:11 -07001027 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001028 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
1029 bb->hasReturn = true;
1030 }
1031 break;
1032
1033 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -07001034 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001035 emitSuspendCheck(cUnit);
1036 }
buzbeeb03f4872012-06-11 15:22:11 -07001037 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001038 cUnit->irb->CreateRetVoid();
1039 bb->hasReturn = true;
1040 }
1041 break;
1042
1043 case Instruction::IF_EQ:
1044 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1045 break;
1046 case Instruction::IF_NE:
1047 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1048 break;
1049 case Instruction::IF_LT:
1050 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1051 break;
1052 case Instruction::IF_GE:
1053 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1054 break;
1055 case Instruction::IF_GT:
1056 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1057 break;
1058 case Instruction::IF_LE:
1059 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1060 break;
1061 case Instruction::IF_EQZ:
1062 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1063 break;
1064 case Instruction::IF_NEZ:
1065 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1066 break;
1067 case Instruction::IF_LTZ:
1068 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1069 break;
1070 case Instruction::IF_GEZ:
1071 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1072 break;
1073 case Instruction::IF_GTZ:
1074 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1075 break;
1076 case Instruction::IF_LEZ:
1077 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1078 break;
1079
1080 case Instruction::GOTO:
1081 case Instruction::GOTO_16:
1082 case Instruction::GOTO_32: {
1083 if (bb->taken->startOffset <= bb->startOffset) {
1084 emitSuspendCheck(cUnit);
1085 }
1086 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1087 }
1088 break;
1089
1090 case Instruction::ADD_LONG:
1091 case Instruction::ADD_LONG_2ADDR:
1092 case Instruction::ADD_INT:
1093 case Instruction::ADD_INT_2ADDR:
1094 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1095 break;
1096 case Instruction::SUB_LONG:
1097 case Instruction::SUB_LONG_2ADDR:
1098 case Instruction::SUB_INT:
1099 case Instruction::SUB_INT_2ADDR:
1100 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1101 break;
1102 case Instruction::MUL_LONG:
1103 case Instruction::MUL_LONG_2ADDR:
1104 case Instruction::MUL_INT:
1105 case Instruction::MUL_INT_2ADDR:
1106 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1107 break;
1108 case Instruction::DIV_LONG:
1109 case Instruction::DIV_LONG_2ADDR:
1110 case Instruction::DIV_INT:
1111 case Instruction::DIV_INT_2ADDR:
1112 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1113 break;
1114 case Instruction::REM_LONG:
1115 case Instruction::REM_LONG_2ADDR:
1116 case Instruction::REM_INT:
1117 case Instruction::REM_INT_2ADDR:
1118 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1119 break;
1120 case Instruction::AND_LONG:
1121 case Instruction::AND_LONG_2ADDR:
1122 case Instruction::AND_INT:
1123 case Instruction::AND_INT_2ADDR:
1124 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1125 break;
1126 case Instruction::OR_LONG:
1127 case Instruction::OR_LONG_2ADDR:
1128 case Instruction::OR_INT:
1129 case Instruction::OR_INT_2ADDR:
1130 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1131 break;
1132 case Instruction::XOR_LONG:
1133 case Instruction::XOR_LONG_2ADDR:
1134 case Instruction::XOR_INT:
1135 case Instruction::XOR_INT_2ADDR:
1136 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1137 break;
1138 case Instruction::SHL_LONG:
1139 case Instruction::SHL_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001140 convertShift(cUnit, greenland::IntrinsicHelper::SHLLong,
1141 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001142 break;
buzbee2cfc6392012-05-07 14:51:40 -07001143 case Instruction::SHL_INT:
1144 case Instruction::SHL_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001145 convertShift(cUnit, greenland::IntrinsicHelper::SHLInt,
1146 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001147 break;
1148 case Instruction::SHR_LONG:
1149 case Instruction::SHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001150 convertShift(cUnit, greenland::IntrinsicHelper::SHRLong,
1151 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001152 break;
buzbee2cfc6392012-05-07 14:51:40 -07001153 case Instruction::SHR_INT:
1154 case Instruction::SHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001155 convertShift(cUnit, greenland::IntrinsicHelper::SHRInt,
1156 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001157 break;
1158 case Instruction::USHR_LONG:
1159 case Instruction::USHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001160 convertShift(cUnit, greenland::IntrinsicHelper::USHRLong,
1161 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001162 break;
buzbee2cfc6392012-05-07 14:51:40 -07001163 case Instruction::USHR_INT:
1164 case Instruction::USHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001165 convertShift(cUnit, greenland::IntrinsicHelper::USHRInt,
1166 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001167 break;
1168
1169 case Instruction::ADD_INT_LIT16:
1170 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001171 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001172 break;
1173 case Instruction::RSUB_INT:
1174 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001175 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001176 break;
1177 case Instruction::MUL_INT_LIT16:
1178 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001179 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001180 break;
1181 case Instruction::DIV_INT_LIT16:
1182 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001183 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001184 break;
1185 case Instruction::REM_INT_LIT16:
1186 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001187 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001188 break;
1189 case Instruction::AND_INT_LIT16:
1190 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001191 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001192 break;
1193 case Instruction::OR_INT_LIT16:
1194 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001195 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001196 break;
1197 case Instruction::XOR_INT_LIT16:
1198 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001199 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001200 break;
1201 case Instruction::SHL_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001202 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHLInt,
1203 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001204 break;
1205 case Instruction::SHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001206 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHRInt,
1207 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001208 break;
1209 case Instruction::USHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001210 convertShiftLit(cUnit, greenland::IntrinsicHelper::USHRInt,
1211 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001212 break;
1213
1214 case Instruction::ADD_FLOAT:
1215 case Instruction::ADD_FLOAT_2ADDR:
1216 case Instruction::ADD_DOUBLE:
1217 case Instruction::ADD_DOUBLE_2ADDR:
1218 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1219 break;
1220
1221 case Instruction::SUB_FLOAT:
1222 case Instruction::SUB_FLOAT_2ADDR:
1223 case Instruction::SUB_DOUBLE:
1224 case Instruction::SUB_DOUBLE_2ADDR:
1225 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1226 break;
1227
1228 case Instruction::MUL_FLOAT:
1229 case Instruction::MUL_FLOAT_2ADDR:
1230 case Instruction::MUL_DOUBLE:
1231 case Instruction::MUL_DOUBLE_2ADDR:
1232 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1233 break;
1234
1235 case Instruction::DIV_FLOAT:
1236 case Instruction::DIV_FLOAT_2ADDR:
1237 case Instruction::DIV_DOUBLE:
1238 case Instruction::DIV_DOUBLE_2ADDR:
1239 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1240 break;
1241
1242 case Instruction::REM_FLOAT:
1243 case Instruction::REM_FLOAT_2ADDR:
1244 case Instruction::REM_DOUBLE:
1245 case Instruction::REM_DOUBLE_2ADDR:
1246 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1247 break;
1248
buzbee6969d502012-06-15 16:40:31 -07001249 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001250 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1251 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001252 break;
1253 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001254 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1255 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001256 break;
1257
1258 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001259 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1260 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001261 break;
1262 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001263 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1264 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001265 break;
1266
1267 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001268 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1269 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001270 break;
1271 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001272 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1273 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001274 break;
1275
1276 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001277 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1278 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001279 break;
1280 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001281 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1282 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001283 break;
1284
1285 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001286 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1287 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001288 break;
1289 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001290 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1291 false /* NewFilledArray */);
1292 break;
1293 case Instruction::FILLED_NEW_ARRAY:
1294 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1295 true /* NewFilledArray */);
1296 break;
1297 case Instruction::FILLED_NEW_ARRAY_RANGE:
1298 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1299 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001300 break;
1301
1302 case Instruction::CONST_STRING:
1303 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001304 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1305 rlDest);
1306 break;
1307
1308 case Instruction::CONST_CLASS:
1309 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1310 rlDest);
1311 break;
1312
1313 case Instruction::CHECK_CAST:
1314 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001315 break;
1316
buzbee4f1181f2012-06-22 13:52:12 -07001317 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001318 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001319 break;
1320
buzbee32412962012-06-26 16:27:56 -07001321 case Instruction::MOVE_EXCEPTION:
1322 convertMoveException(cUnit, rlDest);
1323 break;
1324
1325 case Instruction::THROW:
1326 convertThrow(cUnit, rlSrc[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001327 /*
1328 * If this throw is standalone, terminate.
1329 * If it might rethrow, force termination
1330 * of the following block.
1331 */
1332 if (bb->fallThrough == NULL) {
1333 cUnit->irb->CreateUnreachable();
1334 } else {
1335 bb->fallThrough->fallThrough = NULL;
1336 bb->fallThrough->taken = NULL;
1337 }
buzbee32412962012-06-26 16:27:56 -07001338 break;
1339
buzbee2cfc6392012-05-07 14:51:40 -07001340 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001341 case Instruction::MOVE_RESULT:
1342 case Instruction::MOVE_RESULT_OBJECT:
buzbee9a2487f2012-07-26 14:01:13 -07001343 /*
jeffhao9a4f0032012-08-30 16:17:40 -07001344 * All move_results should have been folded into the preceeding invoke.
buzbee9a2487f2012-07-26 14:01:13 -07001345 */
jeffhao9a4f0032012-08-30 16:17:40 -07001346 LOG(FATAL) << "Unexpected move_result";
buzbee2cfc6392012-05-07 14:51:40 -07001347 break;
1348
1349 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001350 convertMonitorEnterExit(cUnit, optFlags,
1351 greenland::IntrinsicHelper::MonitorEnter,
1352 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001353 break;
1354
1355 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001356 convertMonitorEnterExit(cUnit, optFlags,
1357 greenland::IntrinsicHelper::MonitorExit,
1358 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001359 break;
1360
1361 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001362 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001363 break;
1364
1365 case Instruction::NEW_ARRAY:
1366 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1367 break;
1368
1369 case Instruction::INSTANCE_OF:
1370 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1371 break;
1372
1373 case Instruction::AGET:
1374 if (rlDest.fp) {
1375 convertAget(cUnit, optFlags,
1376 greenland::IntrinsicHelper::HLArrayGetFloat,
1377 rlDest, rlSrc[0], rlSrc[1]);
1378 } else {
1379 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1380 rlDest, rlSrc[0], rlSrc[1]);
1381 }
1382 break;
1383 case Instruction::AGET_OBJECT:
1384 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1385 rlDest, rlSrc[0], rlSrc[1]);
1386 break;
1387 case Instruction::AGET_BOOLEAN:
1388 convertAget(cUnit, optFlags,
1389 greenland::IntrinsicHelper::HLArrayGetBoolean,
1390 rlDest, rlSrc[0], rlSrc[1]);
1391 break;
1392 case Instruction::AGET_BYTE:
1393 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1394 rlDest, rlSrc[0], rlSrc[1]);
1395 break;
1396 case Instruction::AGET_CHAR:
1397 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1398 rlDest, rlSrc[0], rlSrc[1]);
1399 break;
1400 case Instruction::AGET_SHORT:
1401 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1402 rlDest, rlSrc[0], rlSrc[1]);
1403 break;
1404 case Instruction::AGET_WIDE:
1405 if (rlDest.fp) {
1406 convertAget(cUnit, optFlags,
1407 greenland::IntrinsicHelper::HLArrayGetDouble,
1408 rlDest, rlSrc[0], rlSrc[1]);
1409 } else {
1410 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1411 rlDest, rlSrc[0], rlSrc[1]);
1412 }
1413 break;
1414
1415 case Instruction::APUT:
1416 if (rlSrc[0].fp) {
1417 convertAput(cUnit, optFlags,
1418 greenland::IntrinsicHelper::HLArrayPutFloat,
1419 rlSrc[0], rlSrc[1], rlSrc[2]);
1420 } else {
1421 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1422 rlSrc[0], rlSrc[1], rlSrc[2]);
1423 }
1424 break;
1425 case Instruction::APUT_OBJECT:
1426 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1427 rlSrc[0], rlSrc[1], rlSrc[2]);
1428 break;
1429 case Instruction::APUT_BOOLEAN:
1430 convertAput(cUnit, optFlags,
1431 greenland::IntrinsicHelper::HLArrayPutBoolean,
1432 rlSrc[0], rlSrc[1], rlSrc[2]);
1433 break;
1434 case Instruction::APUT_BYTE:
1435 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1436 rlSrc[0], rlSrc[1], rlSrc[2]);
1437 break;
1438 case Instruction::APUT_CHAR:
1439 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1440 rlSrc[0], rlSrc[1], rlSrc[2]);
1441 break;
1442 case Instruction::APUT_SHORT:
1443 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1444 rlSrc[0], rlSrc[1], rlSrc[2]);
1445 break;
1446 case Instruction::APUT_WIDE:
1447 if (rlSrc[0].fp) {
1448 convertAput(cUnit, optFlags,
1449 greenland::IntrinsicHelper::HLArrayPutDouble,
1450 rlSrc[0], rlSrc[1], rlSrc[2]);
1451 } else {
1452 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1453 rlSrc[0], rlSrc[1], rlSrc[2]);
1454 }
1455 break;
1456
buzbee101305f2012-06-28 18:00:56 -07001457 case Instruction::IGET:
1458 if (rlDest.fp) {
1459 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001460 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001461 } else {
1462 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001463 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001464 }
buzbee2cfc6392012-05-07 14:51:40 -07001465 break;
buzbee101305f2012-06-28 18:00:56 -07001466 case Instruction::IGET_OBJECT:
1467 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001468 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001469 break;
1470 case Instruction::IGET_BOOLEAN:
1471 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001472 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001473 break;
1474 case Instruction::IGET_BYTE:
1475 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001476 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001477 break;
1478 case Instruction::IGET_CHAR:
1479 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001480 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001481 break;
1482 case Instruction::IGET_SHORT:
1483 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001484 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001485 break;
1486 case Instruction::IGET_WIDE:
1487 if (rlDest.fp) {
1488 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001489 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001490 } else {
1491 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001492 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001493 }
1494 break;
1495 case Instruction::IPUT:
buzbee85eee022012-07-16 22:12:38 -07001496 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001497 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1498 rlSrc[0], rlSrc[1], vC);
1499 } else {
1500 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1501 rlSrc[0], rlSrc[1], vC);
1502 }
1503 break;
1504 case Instruction::IPUT_OBJECT:
1505 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1506 rlSrc[0], rlSrc[1], vC);
1507 break;
1508 case Instruction::IPUT_BOOLEAN:
1509 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1510 rlSrc[0], rlSrc[1], vC);
1511 break;
1512 case Instruction::IPUT_BYTE:
1513 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1514 rlSrc[0], rlSrc[1], vC);
1515 break;
1516 case Instruction::IPUT_CHAR:
1517 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1518 rlSrc[0], rlSrc[1], vC);
1519 break;
1520 case Instruction::IPUT_SHORT:
1521 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1522 rlSrc[0], rlSrc[1], vC);
1523 break;
1524 case Instruction::IPUT_WIDE:
buzbee85eee022012-07-16 22:12:38 -07001525 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001526 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1527 rlSrc[0], rlSrc[1], vC);
1528 } else {
1529 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1530 rlSrc[0], rlSrc[1], vC);
1531 }
buzbee2cfc6392012-05-07 14:51:40 -07001532 break;
1533
1534 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001535 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001536 break;
1537
buzbee76592632012-06-29 15:18:35 -07001538 case Instruction::LONG_TO_INT:
1539 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1540 break;
1541
buzbee101305f2012-06-28 18:00:56 -07001542 case Instruction::INT_TO_LONG:
1543 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001544 break;
1545
buzbee101305f2012-06-28 18:00:56 -07001546 case Instruction::INT_TO_CHAR:
1547 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1548 greenland::IntrinsicHelper::IntToChar);
1549 break;
1550 case Instruction::INT_TO_BYTE:
1551 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1552 greenland::IntrinsicHelper::IntToByte);
1553 break;
1554 case Instruction::INT_TO_SHORT:
1555 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1556 greenland::IntrinsicHelper::IntToShort);
1557 break;
1558
buzbee76592632012-06-29 15:18:35 -07001559 case Instruction::INT_TO_FLOAT:
1560 case Instruction::LONG_TO_FLOAT:
1561 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001562 break;
1563
buzbee76592632012-06-29 15:18:35 -07001564 case Instruction::INT_TO_DOUBLE:
1565 case Instruction::LONG_TO_DOUBLE:
1566 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001567 break;
1568
buzbee76592632012-06-29 15:18:35 -07001569 case Instruction::FLOAT_TO_DOUBLE:
1570 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001571 break;
1572
buzbee76592632012-06-29 15:18:35 -07001573 case Instruction::DOUBLE_TO_FLOAT:
1574 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001575 break;
1576
1577 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001578 case Instruction::NEG_INT:
1579 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001580 break;
1581
1582 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001583 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001584 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001585 break;
1586
buzbee76592632012-06-29 15:18:35 -07001587 case Instruction::NOT_LONG:
1588 case Instruction::NOT_INT:
1589 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001590 break;
1591
buzbee2cfc6392012-05-07 14:51:40 -07001592 case Instruction::FLOAT_TO_INT:
buzbee2cfc6392012-05-07 14:51:40 -07001593 case Instruction::DOUBLE_TO_INT:
buzbee76592632012-06-29 15:18:35 -07001594 convertFPToInt(cUnit, cUnit->irb->getInt32Ty(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001595 break;
1596
buzbee76592632012-06-29 15:18:35 -07001597 case Instruction::FLOAT_TO_LONG:
1598 case Instruction::DOUBLE_TO_LONG:
1599 convertFPToInt(cUnit, cUnit->irb->getInt64Ty(), rlDest, rlSrc[0]);
1600 break;
1601
1602 case Instruction::CMPL_FLOAT:
1603 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1604 rlDest, rlSrc[0], rlSrc[1]);
1605 break;
1606 case Instruction::CMPG_FLOAT:
1607 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1608 rlDest, rlSrc[0], rlSrc[1]);
1609 break;
1610 case Instruction::CMPL_DOUBLE:
1611 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1612 rlDest, rlSrc[0], rlSrc[1]);
1613 break;
1614 case Instruction::CMPG_DOUBLE:
1615 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1616 rlDest, rlSrc[0], rlSrc[1]);
1617 break;
1618 case Instruction::CMP_LONG:
1619 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1620 rlDest, rlSrc[0], rlSrc[1]);
1621 break;
1622
buzbee76592632012-06-29 15:18:35 -07001623 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001624 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001625 break;
1626
1627 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001628 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001629 break;
buzbee2cfc6392012-05-07 14:51:40 -07001630
1631 default:
buzbee32412962012-06-26 16:27:56 -07001632 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001633 res = true;
1634 }
buzbeeb03f4872012-06-11 15:22:11 -07001635 if (objectDefinition) {
1636 setShadowFrameEntry(cUnit, (llvm::Value*)
1637 cUnit->llvmValues.elemList[rlDest.origSReg]);
1638 }
buzbee2cfc6392012-05-07 14:51:40 -07001639 return res;
1640}
1641
1642/* Extended MIR instructions like PHI */
1643void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1644 llvm::BasicBlock* llvmBB)
1645{
1646
1647 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1648 case kMirOpPhi: {
buzbee2cfc6392012-05-07 14:51:40 -07001649 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001650 /*
1651 * The Art compiler's Phi nodes only handle 32-bit operands,
1652 * representing wide values using a matched set of Phi nodes
1653 * for the lower and upper halves. In the llvm world, we only
1654 * want a single Phi for wides. Here we will simply discard
1655 * the Phi node representing the high word.
1656 */
1657 if (rlDest.highWord) {
1658 return; // No Phi node - handled via low word
1659 }
1660 int* incoming = (int*)mir->dalvikInsn.vB;
buzbee2cfc6392012-05-07 14:51:40 -07001661 llvm::Type* phiType =
1662 llvmTypeFromLocRec(cUnit, rlDest);
1663 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1664 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1665 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001666 // Don't check width here.
1667 loc = oatGetRawSrc(cUnit, mir, i);
1668 DCHECK_EQ(rlDest.wide, loc.wide);
1669 DCHECK_EQ(rlDest.wide & rlDest.highWord, loc.wide & loc.highWord);
1670 DCHECK_EQ(rlDest.fp, loc.fp);
1671 DCHECK_EQ(rlDest.core, loc.core);
1672 DCHECK_EQ(rlDest.ref, loc.ref);
buzbeed1643e42012-09-05 14:06:51 -07001673 SafeMap<unsigned int, unsigned int>::iterator it;
1674 it = cUnit->blockIdMap.find(incoming[i]);
1675 DCHECK(it != cUnit->blockIdMap.end());
buzbee2cfc6392012-05-07 14:51:40 -07001676 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
buzbeed1643e42012-09-05 14:06:51 -07001677 getLLVMBlock(cUnit, it->second));
buzbee2cfc6392012-05-07 14:51:40 -07001678 }
1679 defineValue(cUnit, phi, rlDest.origSReg);
1680 break;
1681 }
1682 case kMirOpCopy: {
1683 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1684 break;
1685 }
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001686 case kMirOpNop:
1687 if ((mir == bb->lastMIRInsn) && (bb->taken == NULL) &&
1688 (bb->fallThrough == NULL)) {
1689 cUnit->irb->CreateUnreachable();
1690 }
1691 break;
1692
buzbee2cfc6392012-05-07 14:51:40 -07001693#if defined(TARGET_ARM)
1694 case kMirOpFusedCmplFloat:
1695 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1696 break;
1697 case kMirOpFusedCmpgFloat:
1698 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1699 break;
1700 case kMirOpFusedCmplDouble:
1701 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1702 break;
1703 case kMirOpFusedCmpgDouble:
1704 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1705 break;
1706 case kMirOpFusedCmpLong:
1707 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1708 break;
1709#endif
1710 default:
1711 break;
1712 }
1713}
1714
1715void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1716{
1717 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001718 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001719 arrayRef.push_back(cUnit->irb->getInt32(offset));
1720 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1721 cUnit->irb->SetDexOffset(node);
1722}
1723
1724// Attach method info as metadata to special intrinsic
1725void setMethodInfo(CompilationUnit* cUnit)
1726{
1727 // We don't want dex offset on this
1728 cUnit->irb->SetDexOffset(NULL);
1729 greenland::IntrinsicHelper::IntrinsicId id;
1730 id = greenland::IntrinsicHelper::MethodInfo;
1731 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1732 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1733 llvm::SmallVector<llvm::Value*, 2> regInfo;
1734 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1735 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1736 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1737 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1738 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1739 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1740 inst->setMetadata("RegInfo", regInfoNode);
1741 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1742 llvm::SmallVector<llvm::Value*, 50> pmap;
1743 for (int i = 0; i < promoSize; i++) {
1744 PromotionMap* p = &cUnit->promotionMap[i];
1745 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1746 ((p->fpReg & 0xff) << 16) |
1747 ((p->coreReg & 0xff) << 8) |
1748 ((p->fpLocation & 0xf) << 4) |
1749 (p->coreLocation & 0xf);
1750 pmap.push_back(cUnit->irb->getInt32(mapData));
1751 }
1752 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1753 inst->setMetadata("PromotionMap", mapNode);
1754 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1755}
1756
1757/* Handle the content in each basic block */
1758bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1759{
buzbeed1643e42012-09-05 14:06:51 -07001760 if (bb->blockType == kDead) return false;
buzbee2cfc6392012-05-07 14:51:40 -07001761 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
1762 cUnit->irb->SetInsertPoint(llvmBB);
1763 setDexOffset(cUnit, bb->startOffset);
1764
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001765 if (cUnit->printMe) {
1766 LOG(INFO) << "................................";
1767 LOG(INFO) << "Block id " << bb->id;
1768 if (llvmBB != NULL) {
1769 LOG(INFO) << "label " << llvmBB->getName().str().c_str();
1770 } else {
1771 LOG(INFO) << "llvmBB is NULL";
1772 }
1773 }
1774
buzbee2cfc6392012-05-07 14:51:40 -07001775 if (bb->blockType == kEntryBlock) {
1776 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001777 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1778 cUnit->numDalvikRegisters, true,
1779 kAllocMisc);
1780 for (int i = 0; i < cUnit->numSSARegs; i++) {
1781 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1782 }
1783 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1784 if (canBeRef[i]) {
1785 cUnit->numShadowFrameEntries++;
1786 }
1787 }
1788 if (cUnit->numShadowFrameEntries > 0) {
1789 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1790 cUnit->numShadowFrameEntries, true,
1791 kAllocMisc);
1792 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1793 if (canBeRef[i]) {
1794 cUnit->shadowMap[j++] = i;
1795 }
1796 }
1797 greenland::IntrinsicHelper::IntrinsicId id =
1798 greenland::IntrinsicHelper::AllocaShadowFrame;
1799 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1800 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1801 cUnit->irb->CreateCall(func, entries);
1802 }
buzbee2cfc6392012-05-07 14:51:40 -07001803 } else if (bb->blockType == kExitBlock) {
1804 /*
1805 * Because of the differences between how MIR/LIR and llvm handle exit
1806 * blocks, we won't explicitly covert them. On the llvm-to-lir
1807 * path, it will need to be regenereated.
1808 */
1809 return false;
buzbee6969d502012-06-15 16:40:31 -07001810 } else if (bb->blockType == kExceptionHandling) {
1811 /*
1812 * Because we're deferring null checking, delete the associated empty
1813 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001814 */
1815 llvmBB->eraseFromParent();
1816 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001817 }
1818
1819 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1820
1821 setDexOffset(cUnit, mir->offset);
1822
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001823 int opcode = mir->dalvikInsn.opcode;
1824 Instruction::Format dalvikFormat =
1825 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001826
1827 /* If we're compiling for the debugger, generate an update callout */
1828 if (cUnit->genDebugger) {
1829 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1830 //genDebuggerUpdate(cUnit, mir->offset);
1831 }
1832
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001833 if (opcode == kMirOpCheck) {
1834 // Combine check and work halves of throwing instruction.
1835 MIR* workHalf = mir->meta.throwInsn;
1836 mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
1837 opcode = mir->dalvikInsn.opcode;
1838 SSARepresentation* ssaRep = workHalf->ssaRep;
1839 workHalf->ssaRep = mir->ssaRep;
1840 mir->ssaRep = ssaRep;
1841 workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1842 if (bb->successorBlockList.blockListType == kCatch) {
1843 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
1844 greenland::IntrinsicHelper::CatchTargets);
1845 llvm::Value* switchKey =
1846 cUnit->irb->CreateCall(intr, cUnit->irb->getInt32(mir->offset));
1847 GrowableListIterator iter;
1848 oatGrowableListIteratorInit(&bb->successorBlockList.blocks, &iter);
1849 // New basic block to use for work half
1850 llvm::BasicBlock* workBB =
1851 llvm::BasicBlock::Create(*cUnit->context, "", cUnit->func);
1852 llvm::SwitchInst* sw =
1853 cUnit->irb->CreateSwitch(switchKey, workBB,
1854 bb->successorBlockList.blocks.numUsed);
1855 while (true) {
1856 SuccessorBlockInfo *successorBlockInfo =
1857 (SuccessorBlockInfo *) oatGrowableListIteratorNext(&iter);
1858 if (successorBlockInfo == NULL) break;
1859 llvm::BasicBlock *target =
1860 getLLVMBlock(cUnit, successorBlockInfo->block->id);
1861 int typeIndex = successorBlockInfo->key;
1862 sw->addCase(cUnit->irb->getInt32(typeIndex), target);
1863 }
1864 llvmBB = workBB;
1865 cUnit->irb->SetInsertPoint(llvmBB);
1866 }
1867 }
1868
1869 if (opcode >= kMirOpFirst) {
buzbee2cfc6392012-05-07 14:51:40 -07001870 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1871 continue;
1872 }
1873
1874 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1875 NULL /* labelList */);
1876 if (notHandled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001877 Instruction::Code dalvikOpcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001878 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001879 mir->offset, opcode,
buzbee2cfc6392012-05-07 14:51:40 -07001880 Instruction::Name(dalvikOpcode),
1881 dalvikFormat);
1882 }
1883 }
1884
buzbee4be777b2012-07-12 14:38:18 -07001885 if (bb->blockType == kEntryBlock) {
1886 cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
1887 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001888 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1889 }
1890
1891 return false;
1892}
1893
buzbee4f4dfc72012-07-02 14:54:44 -07001894char remapShorty(char shortyType) {
1895 /*
1896 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1897 * and longs/doubles are represented as a pair of registers. When sub-word
1898 * arguments (and method results) are passed, they are extended to Dalvik
1899 * virtual register containers. Because llvm is picky about type consistency,
1900 * we must either cast the "real" type to 32-bit container multiple Dalvik
1901 * register types, or always use the expanded values.
1902 * Here, we're doing the latter. We map the shorty signature to container
1903 * types (which is valid so long as we always do a real expansion of passed
1904 * arguments and field loads).
1905 */
1906 switch(shortyType) {
1907 case 'Z' : shortyType = 'I'; break;
1908 case 'B' : shortyType = 'I'; break;
1909 case 'S' : shortyType = 'I'; break;
1910 case 'C' : shortyType = 'I'; break;
1911 default: break;
1912 }
1913 return shortyType;
1914}
1915
buzbee2cfc6392012-05-07 14:51:40 -07001916llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1917
1918 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001919 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001920 greenland::kAccurate);
1921
1922 // Get argument type
1923 std::vector<llvm::Type*> args_type;
1924
1925 // method object
1926 args_type.push_back(cUnit->irb->GetJMethodTy());
1927
1928 // Do we have a "this"?
1929 if ((cUnit->access_flags & kAccStatic) == 0) {
1930 args_type.push_back(cUnit->irb->GetJObjectTy());
1931 }
1932
1933 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001934 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001935 greenland::kAccurate));
1936 }
1937
1938 return llvm::FunctionType::get(ret_type, args_type, false);
1939}
1940
1941bool createFunction(CompilationUnit* cUnit) {
1942 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1943 /* with_signature */ false));
1944 llvm::FunctionType* func_type = getFunctionType(cUnit);
1945
1946 if (func_type == NULL) {
1947 return false;
1948 }
1949
1950 cUnit->func = llvm::Function::Create(func_type,
1951 llvm::Function::ExternalLinkage,
1952 func_name, cUnit->module);
1953
1954 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1955 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1956
1957 arg_iter->setName("method");
1958 ++arg_iter;
1959
1960 int startSReg = cUnit->numRegs;
1961
1962 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1963 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1964 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1965 }
1966
1967 return true;
1968}
1969
1970bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
1971{
1972 // Skip the exit block
buzbeed1643e42012-09-05 14:06:51 -07001973 if ((bb->blockType == kDead) ||(bb->blockType == kExitBlock)) {
buzbee2cfc6392012-05-07 14:51:40 -07001974 cUnit->idToBlockMap.Put(bb->id, NULL);
1975 } else {
1976 int offset = bb->startOffset;
1977 bool entryBlock = (bb->blockType == kEntryBlock);
1978 llvm::BasicBlock* llvmBB =
1979 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
buzbee8320f382012-09-11 16:29:42 -07001980 StringPrintf(kLabelFormat, bb->catchEntry ? kCatchBlock :
1981 kNormalBlock, offset, bb->id), cUnit->func);
buzbee2cfc6392012-05-07 14:51:40 -07001982 if (entryBlock) {
1983 cUnit->entryBB = llvmBB;
1984 cUnit->placeholderBB =
1985 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
1986 cUnit->func);
1987 }
1988 cUnit->idToBlockMap.Put(bb->id, llvmBB);
1989 }
1990 return false;
1991}
1992
1993
1994/*
1995 * Convert MIR to LLVM_IR
1996 * o For each ssa name, create LLVM named value. Type these
1997 * appropriately, and ignore high half of wide and double operands.
1998 * o For each MIR basic block, create an LLVM basic block.
1999 * o Iterate through the MIR a basic block at a time, setting arguments
2000 * to recovered ssa name.
2001 */
2002void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
2003{
2004 initIR(cUnit);
2005 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
2006
2007 // Create the function
2008 createFunction(cUnit);
2009
2010 // Create an LLVM basic block for each MIR block in dfs preorder
2011 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
2012 kPreOrderDFSTraversal, false /* isIterative */);
2013 /*
2014 * Create an llvm named value for each MIR SSA name. Note: we'll use
2015 * placeholders for all non-argument values (because we haven't seen
2016 * the definition yet).
2017 */
2018 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2019 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2020 arg_iter++; /* Skip path method */
2021 for (int i = 0; i < cUnit->numSSARegs; i++) {
2022 llvm::Value* val;
buzbee85eee022012-07-16 22:12:38 -07002023 RegLocation rlTemp = cUnit->regLocation[i];
2024 if ((SRegToVReg(cUnit, i) < 0) || rlTemp.highWord) {
buzbee2a83e8f2012-07-13 16:42:30 -07002025 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
2026 } else if ((i < cUnit->numRegs) ||
2027 (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee85eee022012-07-16 22:12:38 -07002028 llvm::Constant* immValue = cUnit->regLocation[i].wide ?
2029 cUnit->irb->GetJLong(0) : cUnit->irb->GetJInt(0);
buzbee2a83e8f2012-07-13 16:42:30 -07002030 val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
2031 val->setName(llvmSSAName(cUnit, i));
buzbee2cfc6392012-05-07 14:51:40 -07002032 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
buzbee2cfc6392012-05-07 14:51:40 -07002033 } else {
2034 // Recover previously-created argument values
2035 llvm::Value* argVal = arg_iter++;
2036 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
2037 }
2038 }
buzbee2cfc6392012-05-07 14:51:40 -07002039
2040 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
2041 kPreOrderDFSTraversal, false /* Iterative */);
2042
buzbee4be777b2012-07-12 14:38:18 -07002043 /*
2044 * In a few rare cases of verification failure, the verifier will
2045 * replace one or more Dalvik opcodes with the special
2046 * throw-verification-failure opcode. This can leave the SSA graph
2047 * in an invalid state, as definitions may be lost, while uses retained.
2048 * To work around this problem, we insert placeholder definitions for
2049 * all Dalvik SSA regs in the "placeholder" block. Here, after
2050 * bitcode conversion is complete, we examine those placeholder definitions
2051 * and delete any with no references (which normally is all of them).
2052 *
2053 * If any definitions remain, we link the placeholder block into the
2054 * CFG. Otherwise, it is deleted.
2055 */
2056 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
2057 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
2058 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2059 DCHECK(inst != NULL);
2060 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2061 DCHECK(val != NULL);
2062 if (val->getNumUses() == 0) {
2063 inst->eraseFromParent();
2064 }
2065 }
2066 setDexOffset(cUnit, 0);
2067 if (cUnit->placeholderBB->empty()) {
2068 cUnit->placeholderBB->eraseFromParent();
2069 } else {
2070 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2071 cUnit->irb->CreateBr(cUnit->entryTargetBB);
2072 cUnit->entryTargetBB = cUnit->placeholderBB;
2073 }
2074 cUnit->irb->SetInsertPoint(cUnit->entryBB);
2075 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07002076
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002077 if (cUnit->enableDebug & (1 << kDebugVerifyBitcode)) {
2078 if (llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction)) {
2079 LOG(INFO) << "Bitcode verification FAILED for "
2080 << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
2081 << " of size " << cUnit->insnsSize;
2082 cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
2083 }
2084 }
buzbee2cfc6392012-05-07 14:51:40 -07002085
buzbeead8f15e2012-06-18 14:49:45 -07002086 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
2087 // Write bitcode to file
2088 std::string errmsg;
2089 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
2090 oatReplaceSpecialChars(fname);
2091 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07002092 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002093
buzbeead8f15e2012-06-18 14:49:45 -07002094 llvm::OwningPtr<llvm::tool_output_file> out_file(
2095 new llvm::tool_output_file(fname.c_str(), errmsg,
2096 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002097
buzbeead8f15e2012-06-18 14:49:45 -07002098 if (!errmsg.empty()) {
2099 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2100 }
2101
2102 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
2103 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002104 }
buzbee2cfc6392012-05-07 14:51:40 -07002105}
2106
2107RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
2108 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002109 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002110 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2111 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07002112 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07002113 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002114 // FIXME: need to be more robust, handle FP and be in a position to
2115 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002116 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2117 memset(&res, 0, sizeof(res));
2118 res.location = kLocPhysReg;
2119 res.lowReg = oatAllocTemp(cUnit);
2120 res.home = true;
2121 res.sRegLow = INVALID_SREG;
2122 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002123 llvm::Type* ty = val->getType();
2124 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2125 (ty == cUnit->irb->getDoubleTy()));
2126 if (res.wide) {
2127 res.highReg = oatAllocTemp(cUnit);
2128 }
buzbee4f1181f2012-06-22 13:52:12 -07002129 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002130 } else {
2131 DCHECK_EQ(valName[0], 'v');
2132 int baseSReg = INVALID_SREG;
2133 sscanf(valName.c_str(), "v%d_", &baseSReg);
2134 res = cUnit->regLocation[baseSReg];
2135 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002136 }
2137 } else {
2138 res = it->second;
2139 }
2140 return res;
2141}
2142
2143Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
2144{
2145 Instruction::Code res = Instruction::NOP;
2146 if (isWide) {
2147 switch(op) {
2148 case kOpAdd: res = Instruction::ADD_LONG; break;
2149 case kOpSub: res = Instruction::SUB_LONG; break;
2150 case kOpMul: res = Instruction::MUL_LONG; break;
2151 case kOpDiv: res = Instruction::DIV_LONG; break;
2152 case kOpRem: res = Instruction::REM_LONG; break;
2153 case kOpAnd: res = Instruction::AND_LONG; break;
2154 case kOpOr: res = Instruction::OR_LONG; break;
2155 case kOpXor: res = Instruction::XOR_LONG; break;
2156 case kOpLsl: res = Instruction::SHL_LONG; break;
2157 case kOpLsr: res = Instruction::USHR_LONG; break;
2158 case kOpAsr: res = Instruction::SHR_LONG; break;
2159 default: LOG(FATAL) << "Unexpected OpKind " << op;
2160 }
2161 } else if (isConst){
2162 switch(op) {
2163 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2164 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2165 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2166 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2167 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2168 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2169 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2170 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2171 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2172 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2173 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2174 default: LOG(FATAL) << "Unexpected OpKind " << op;
2175 }
2176 } else {
2177 switch(op) {
2178 case kOpAdd: res = Instruction::ADD_INT; break;
2179 case kOpSub: res = Instruction::SUB_INT; break;
2180 case kOpMul: res = Instruction::MUL_INT; break;
2181 case kOpDiv: res = Instruction::DIV_INT; break;
2182 case kOpRem: res = Instruction::REM_INT; break;
2183 case kOpAnd: res = Instruction::AND_INT; break;
2184 case kOpOr: res = Instruction::OR_INT; break;
2185 case kOpXor: res = Instruction::XOR_INT; break;
2186 case kOpLsl: res = Instruction::SHL_INT; break;
2187 case kOpLsr: res = Instruction::USHR_INT; break;
2188 case kOpAsr: res = Instruction::SHR_INT; break;
2189 default: LOG(FATAL) << "Unexpected OpKind " << op;
2190 }
2191 }
2192 return res;
2193}
2194
buzbee4f1181f2012-06-22 13:52:12 -07002195Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2196{
2197 Instruction::Code res = Instruction::NOP;
2198 if (isWide) {
2199 switch(op) {
2200 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2201 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2202 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2203 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2204 case kOpRem: res = Instruction::REM_DOUBLE; break;
2205 default: LOG(FATAL) << "Unexpected OpKind " << op;
2206 }
2207 } else {
2208 switch(op) {
2209 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2210 case kOpSub: res = Instruction::SUB_FLOAT; break;
2211 case kOpMul: res = Instruction::MUL_FLOAT; break;
2212 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2213 case kOpRem: res = Instruction::REM_FLOAT; break;
2214 default: LOG(FATAL) << "Unexpected OpKind " << op;
2215 }
2216 }
2217 return res;
2218}
2219
2220void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2221{
2222 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002223 /*
2224 * Normally, we won't ever generate an FP operation with an immediate
2225 * operand (not supported in Dex instruction set). However, the IR builder
2226 * may insert them - in particular for createNegFP. Recognize this case
2227 * and deal with it.
2228 */
2229 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2230 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2231 DCHECK(op2C == NULL);
2232 if ((op1C != NULL) && (op == kOpSub)) {
2233 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2234 if (rlDest.wide) {
2235 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2236 } else {
2237 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2238 }
buzbee4f1181f2012-06-22 13:52:12 -07002239 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002240 DCHECK(op1C == NULL);
2241 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2242 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2243 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2244 if (rlDest.wide) {
2245 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2246 } else {
2247 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2248 }
buzbee4f1181f2012-06-22 13:52:12 -07002249 }
2250}
2251
buzbee101305f2012-06-28 18:00:56 -07002252void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2253 Instruction::Code opcode)
2254{
2255 RegLocation rlDest = getLoc(cUnit, inst);
2256 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2257 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2258}
2259
buzbee76592632012-06-29 15:18:35 -07002260void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2261{
2262 RegLocation rlDest = getLoc(cUnit, inst);
2263 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2264 Instruction::Code opcode;
2265 if (rlDest.wide) {
2266 if (rlSrc.wide) {
2267 opcode = Instruction::LONG_TO_DOUBLE;
2268 } else {
2269 opcode = Instruction::INT_TO_DOUBLE;
2270 }
2271 } else {
2272 if (rlSrc.wide) {
2273 opcode = Instruction::LONG_TO_FLOAT;
2274 } else {
2275 opcode = Instruction::INT_TO_FLOAT;
2276 }
2277 }
2278 genConversion(cUnit, opcode, rlDest, rlSrc);
2279}
2280
2281void cvtFPToInt(CompilationUnit* cUnit, llvm::Instruction* inst)
2282{
2283 RegLocation rlDest = getLoc(cUnit, inst);
2284 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2285 Instruction::Code opcode;
2286 if (rlDest.wide) {
2287 if (rlSrc.wide) {
2288 opcode = Instruction::DOUBLE_TO_LONG;
2289 } else {
2290 opcode = Instruction::FLOAT_TO_LONG;
2291 }
2292 } else {
2293 if (rlSrc.wide) {
2294 opcode = Instruction::DOUBLE_TO_INT;
2295 } else {
2296 opcode = Instruction::FLOAT_TO_INT;
2297 }
2298 }
2299 genConversion(cUnit, opcode, rlDest, rlSrc);
2300}
2301
2302void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2303{
2304 RegLocation rlDest = getLoc(cUnit, inst);
2305 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2306 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2307}
2308
2309void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2310{
2311 RegLocation rlDest = getLoc(cUnit, inst);
2312 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2313 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2314 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2315 storeValue(cUnit, rlDest, rlSrc);
2316}
2317
2318void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2319{
2320 RegLocation rlDest = getLoc(cUnit, inst);
2321 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2322 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2323}
2324
2325
buzbee101305f2012-06-28 18:00:56 -07002326void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2327{
2328 // TODO: evaluate src/tgt types and add general support for more than int to long
2329 RegLocation rlDest = getLoc(cUnit, inst);
2330 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2331 DCHECK(rlDest.wide);
2332 DCHECK(!rlSrc.wide);
2333 DCHECK(!rlDest.fp);
2334 DCHECK(!rlSrc.fp);
2335 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2336 if (rlSrc.location == kLocPhysReg) {
2337 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2338 } else {
2339 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2340 }
2341 if (isSigned) {
2342 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2343 } else {
2344 loadConstant(cUnit, rlResult.highReg, 0);
2345 }
2346 storeValueWide(cUnit, rlDest, rlResult);
2347}
2348
buzbee2cfc6392012-05-07 14:51:40 -07002349void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2350{
2351 RegLocation rlDest = getLoc(cUnit, inst);
2352 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002353 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002354 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2355 if ((op == kOpSub) && (lhsImm != NULL)) {
2356 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002357 if (rlSrc1.wide) {
2358 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2359 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2360 } else {
2361 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2362 lhsImm->getSExtValue());
2363 }
buzbee4f1181f2012-06-22 13:52:12 -07002364 return;
2365 }
2366 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002367 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2368 llvm::Value* rhs = inst->getOperand(1);
buzbee9a2487f2012-07-26 14:01:13 -07002369 llvm::ConstantInt* constRhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2370 if (!rlDest.wide && (constRhs != NULL)) {
buzbee2cfc6392012-05-07 14:51:40 -07002371 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
buzbee9a2487f2012-07-26 14:01:13 -07002372 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, constRhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002373 } else {
2374 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
buzbee9a2487f2012-07-26 14:01:13 -07002375 RegLocation rlSrc2;
2376 if (constRhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002377 // ir_builder converts NOT_LONG to xor src, -1. Restore
2378 DCHECK_EQ(dalvikOp, Instruction::XOR_LONG);
2379 DCHECK_EQ(-1L, constRhs->getSExtValue());
2380 dalvikOp = Instruction::NOT_LONG;
buzbee9a2487f2012-07-26 14:01:13 -07002381 rlSrc2 = rlSrc1;
2382 } else {
2383 rlSrc2 = getLoc(cUnit, rhs);
2384 }
buzbee2cfc6392012-05-07 14:51:40 -07002385 if (rlDest.wide) {
2386 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2387 } else {
2388 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2389 }
2390 }
2391}
2392
buzbee2a83e8f2012-07-13 16:42:30 -07002393void cvtShiftOp(CompilationUnit* cUnit, Instruction::Code opcode,
2394 llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002395{
buzbee2a83e8f2012-07-13 16:42:30 -07002396 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2397 RegLocation rlDest = getLoc(cUnit, callInst);
2398 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2399 llvm::Value* rhs = callInst->getArgOperand(1);
2400 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2401 DCHECK(!rlDest.wide);
2402 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002403 } else {
buzbee2a83e8f2012-07-13 16:42:30 -07002404 RegLocation rlShift = getLoc(cUnit, rhs);
2405 if (callInst->getType() == cUnit->irb->getInt64Ty()) {
2406 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2407 } else {
2408 genArithOpInt(cUnit, opcode, rlDest, rlSrc, rlShift);
2409 }
buzbee101305f2012-06-28 18:00:56 -07002410 }
2411}
2412
buzbee2cfc6392012-05-07 14:51:40 -07002413void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2414{
2415 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2416 DCHECK(brInst != NULL);
2417 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2418 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2419 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2420}
2421
2422void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2423{
2424 // Nop - these have already been processed
2425}
2426
2427void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2428{
2429 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2430 llvm::Value* retVal = retInst->getReturnValue();
2431 if (retVal != NULL) {
2432 RegLocation rlSrc = getLoc(cUnit, retVal);
2433 if (rlSrc.wide) {
2434 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2435 } else {
2436 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2437 }
2438 }
2439 genExitSequence(cUnit);
2440}
2441
2442ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2443{
2444 ConditionCode res = kCondAl;
2445 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002446 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002447 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2448 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2449 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002450 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002451 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002452 default: LOG(FATAL) << "Unexpected llvm condition";
2453 }
2454 return res;
2455}
2456
2457void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2458{
2459 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2460 UNIMPLEMENTED(FATAL);
2461}
2462
2463void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2464 llvm::BranchInst* brInst)
2465{
2466 // Get targets
2467 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2468 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2469 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2470 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2471 // Get comparison operands
2472 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2473 ConditionCode cond = getCond(iCmpInst->getPredicate());
2474 llvm::Value* lhs = iCmpInst->getOperand(0);
2475 // Not expecting a constant as 1st operand
2476 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2477 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2478 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2479 llvm::Value* rhs = inst->getOperand(1);
2480#if defined(TARGET_MIPS)
2481 // Compare and branch in one shot
2482 (void)taken;
2483 (void)cond;
2484 (void)rhs;
2485 UNIMPLEMENTED(FATAL);
2486#else
2487 //Compare, then branch
2488 // TODO: handle fused CMP_LONG/IF_xxZ case
2489 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2490 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002491 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
2492 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002493 } else {
2494 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2495 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2496 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2497 }
2498 opCondBranch(cUnit, cond, taken);
2499#endif
2500 // Fallthrough
2501 opUnconditionalBranch(cUnit, fallThrough);
2502}
2503
2504void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2505 llvm::Function* callee)
2506{
2507 UNIMPLEMENTED(FATAL);
2508}
2509
buzbee2cfc6392012-05-07 14:51:40 -07002510void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2511{
buzbee4f1181f2012-06-22 13:52:12 -07002512 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002513 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2514 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002515 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2516 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002517 if (rlSrc.wide) {
2518 storeValueWide(cUnit, rlDest, rlSrc);
2519 } else {
2520 storeValue(cUnit, rlDest, rlSrc);
2521 }
2522}
2523
2524// Note: Immediate arg is a ConstantInt regardless of result type
2525void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2526{
buzbee4f1181f2012-06-22 13:52:12 -07002527 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002528 llvm::ConstantInt* src =
2529 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2530 uint64_t immval = src->getZExtValue();
2531 RegLocation rlDest = getLoc(cUnit, callInst);
2532 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2533 if (rlDest.wide) {
2534 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2535 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2536 storeValueWide(cUnit, rlDest, rlResult);
2537 } else {
2538 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2539 storeValue(cUnit, rlDest, rlResult);
2540 }
2541}
2542
buzbee101305f2012-06-28 18:00:56 -07002543void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2544 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002545{
buzbee4f1181f2012-06-22 13:52:12 -07002546 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002547 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002548 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002549 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002550 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002551 if (isString) {
2552 genConstString(cUnit, index, rlDest);
2553 } else {
2554 genConstClass(cUnit, index, rlDest);
2555 }
2556}
2557
2558void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2559{
2560 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2561 llvm::ConstantInt* offsetVal =
2562 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2563 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2564 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002565}
2566
buzbee4f1181f2012-06-22 13:52:12 -07002567void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2568{
buzbee32412962012-06-26 16:27:56 -07002569 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002570 llvm::ConstantInt* typeIdxVal =
2571 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2572 uint32_t typeIdx = typeIdxVal->getZExtValue();
2573 RegLocation rlDest = getLoc(cUnit, callInst);
2574 genNewInstance(cUnit, typeIdx, rlDest);
2575}
2576
buzbee8fa0fda2012-06-27 15:44:52 -07002577void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2578{
2579 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2580 llvm::ConstantInt* typeIdxVal =
2581 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2582 uint32_t typeIdx = typeIdxVal->getZExtValue();
2583 llvm::Value* len = callInst->getArgOperand(1);
2584 RegLocation rlLen = getLoc(cUnit, len);
2585 RegLocation rlDest = getLoc(cUnit, callInst);
2586 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2587}
2588
2589void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2590{
2591 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2592 llvm::ConstantInt* typeIdxVal =
2593 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2594 uint32_t typeIdx = typeIdxVal->getZExtValue();
2595 llvm::Value* src = callInst->getArgOperand(1);
2596 RegLocation rlSrc = getLoc(cUnit, src);
2597 RegLocation rlDest = getLoc(cUnit, callInst);
2598 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2599}
2600
buzbee32412962012-06-26 16:27:56 -07002601void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2602{
2603 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2604 llvm::Value* src = callInst->getArgOperand(0);
2605 RegLocation rlSrc = getLoc(cUnit, src);
2606 genThrow(cUnit, rlSrc);
2607}
2608
buzbee8fa0fda2012-06-27 15:44:52 -07002609void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2610 llvm::CallInst* callInst)
2611{
2612 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2613 llvm::ConstantInt* optFlags =
2614 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2615 llvm::Value* src = callInst->getArgOperand(1);
2616 RegLocation rlSrc = getLoc(cUnit, src);
2617 if (isEnter) {
2618 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2619 } else {
2620 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2621 }
2622}
2623
buzbee76592632012-06-29 15:18:35 -07002624void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002625{
2626 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2627 llvm::ConstantInt* optFlags =
2628 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2629 llvm::Value* src = callInst->getArgOperand(1);
2630 RegLocation rlSrc = getLoc(cUnit, src);
2631 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2632 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2633 RegLocation rlDest = getLoc(cUnit, callInst);
2634 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2635 int lenOffset = Array::LengthOffset().Int32Value();
2636 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2637 storeValue(cUnit, rlDest, rlResult);
2638}
2639
buzbee32412962012-06-26 16:27:56 -07002640void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2641{
2642 DCHECK_EQ(callInst->getNumArgOperands(), 0U);
2643 int exOffset = Thread::ExceptionOffset().Int32Value();
2644 RegLocation rlDest = getLoc(cUnit, callInst);
2645 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2646#if defined(TARGET_X86)
2647 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
2648 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
2649#else
2650 int resetReg = oatAllocTemp(cUnit);
2651 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
2652 loadConstant(cUnit, resetReg, 0);
2653 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
2654 oatFreeTemp(cUnit, resetReg);
2655#endif
2656 storeValue(cUnit, rlDest, rlResult);
2657}
2658
buzbee4f1181f2012-06-22 13:52:12 -07002659void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2660 bool isObject)
2661{
buzbee32412962012-06-26 16:27:56 -07002662 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002663 llvm::ConstantInt* typeIdxVal =
2664 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2665 uint32_t typeIdx = typeIdxVal->getZExtValue();
2666 RegLocation rlDest = getLoc(cUnit, callInst);
2667 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2668}
2669
buzbee8fa0fda2012-06-27 15:44:52 -07002670void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2671 bool isObject)
2672{
2673 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2674 llvm::ConstantInt* typeIdxVal =
2675 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2676 uint32_t typeIdx = typeIdxVal->getZExtValue();
2677 llvm::Value* src = callInst->getArgOperand(1);
2678 RegLocation rlSrc = getLoc(cUnit, src);
2679 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2680}
2681
2682void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2683 int scale)
2684{
2685 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2686 llvm::ConstantInt* optFlags =
2687 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2688 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2689 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2690 RegLocation rlDest = getLoc(cUnit, callInst);
2691 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2692 rlDest, scale);
2693}
2694
2695void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002696 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002697{
2698 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2699 llvm::ConstantInt* optFlags =
2700 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2701 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2702 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2703 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002704 if (isObject) {
2705 genArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
2706 rlSrc, scale);
2707 } else {
2708 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2709 rlSrc, scale);
2710 }
2711}
2712
2713void cvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
2714{
2715 cvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
2716}
2717
2718void cvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
2719 OpSize size, int scale)
2720{
2721 cvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002722}
2723
buzbee101305f2012-06-28 18:00:56 -07002724void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2725 bool isWide, bool isObj)
2726{
2727 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2728 llvm::ConstantInt* optFlags =
2729 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2730 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2731 llvm::ConstantInt* fieldIdx =
2732 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2733 RegLocation rlDest = getLoc(cUnit, callInst);
2734 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2735 size, rlDest, rlObj, isWide, isObj);
2736}
2737
2738void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2739 bool isWide, bool isObj)
2740{
2741 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2742 llvm::ConstantInt* optFlags =
2743 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2744 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2745 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2746 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002747 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002748 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2749 size, rlSrc, rlObj, isWide, isObj);
2750}
2751
2752void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2753{
2754 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2755 llvm::ConstantInt* typeIdx =
2756 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2757 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2758 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2759}
2760
buzbee76592632012-06-29 15:18:35 -07002761void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2762 Instruction::Code opcode)
2763{
2764 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2765 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2766 RegLocation rlDest = getLoc(cUnit, callInst);
2767 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2768}
2769
2770void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2771{
2772 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2773 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2774 RegLocation rlDest = getLoc(cUnit, callInst);
2775 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2776}
2777
buzbeef58c12c2012-07-03 15:06:29 -07002778void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2779{
2780 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2781 DCHECK(swInst != NULL);
2782 llvm::Value* testVal = swInst->getCondition();
2783 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2784 DCHECK(tableOffsetNode != NULL);
2785 llvm::ConstantInt* tableOffsetValue =
2786 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2787 int32_t tableOffset = tableOffsetValue->getSExtValue();
2788 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeea1da8a52012-07-09 14:00:21 -07002789 const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2790 u2 tableMagic = *table;
2791 if (tableMagic == 0x100) {
2792 genPackedSwitch(cUnit, tableOffset, rlSrc);
2793 } else {
2794 DCHECK_EQ(tableMagic, 0x200);
2795 genSparseSwitch(cUnit, tableOffset, rlSrc);
2796 }
buzbeef58c12c2012-07-03 15:06:29 -07002797}
2798
buzbee6969d502012-06-15 16:40:31 -07002799void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002800 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002801{
2802 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2803 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002804 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002805 info->result.location = kLocInvalid;
2806 } else {
2807 info->result = getLoc(cUnit, callInst);
2808 }
2809 llvm::ConstantInt* invokeTypeVal =
2810 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2811 llvm::ConstantInt* methodIndexVal =
2812 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2813 llvm::ConstantInt* optFlagsVal =
2814 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2815 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2816 info->index = methodIndexVal->getZExtValue();
2817 info->optFlags = optFlagsVal->getZExtValue();
2818 info->offset = cUnit->currentDalvikOffset;
2819
buzbee6969d502012-06-15 16:40:31 -07002820 // Count the argument words, and then build argument array.
2821 info->numArgWords = 0;
2822 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2823 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2824 info->numArgWords += tLoc.wide ? 2 : 1;
2825 }
2826 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2827 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2828 // Now, fill in the location records, synthesizing high loc of wide vals
2829 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002830 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002831 if (info->args[next].wide) {
2832 next++;
2833 // TODO: Might make sense to mark this as an invalid loc
2834 info->args[next].origSReg = info->args[next-1].origSReg+1;
2835 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2836 }
2837 next++;
2838 }
buzbee4f4dfc72012-07-02 14:54:44 -07002839 // TODO - rework such that we no longer need isRange
2840 info->isRange = (info->numArgWords > 5);
2841
buzbee76592632012-06-29 15:18:35 -07002842 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002843 genFilledNewArray(cUnit, info);
2844 } else {
2845 genInvoke(cUnit, info);
2846 }
buzbee6969d502012-06-15 16:40:31 -07002847}
2848
buzbeead8f15e2012-06-18 14:49:45 -07002849/* Look up the RegLocation associated with a Value. Must already be defined */
2850RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2851{
2852 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2853 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2854 return it->second;
2855}
2856
buzbee2cfc6392012-05-07 14:51:40 -07002857bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2858{
2859 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2860 // Define the starting label
2861 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
buzbee8320f382012-09-11 16:29:42 -07002862 // Extract the type and starting offset from the block's name
2863 char blockType = kNormalBlock;
buzbee2cfc6392012-05-07 14:51:40 -07002864 if (!isEntry) {
2865 const char* blockName = bb->getName().str().c_str();
2866 int dummy;
buzbee8320f382012-09-11 16:29:42 -07002867 sscanf(blockName, kLabelFormat, &blockType, &blockLabel->operands[0], &dummy);
2868 cUnit->currentDalvikOffset = blockLabel->operands[0];
2869 } else {
2870 cUnit->currentDalvikOffset = 0;
buzbee2cfc6392012-05-07 14:51:40 -07002871 }
2872 // Set the label kind
2873 blockLabel->opcode = kPseudoNormalBlockLabel;
2874 // Insert the label
2875 oatAppendLIR(cUnit, blockLabel);
2876
buzbee8320f382012-09-11 16:29:42 -07002877 LIR* headLIR = NULL;
2878
2879 if (blockType == kCatchBlock) {
2880 headLIR = newLIR0(cUnit, kPseudoSafepointPC);
2881 }
2882
buzbee2cfc6392012-05-07 14:51:40 -07002883 // Free temp registers and reset redundant store tracking */
2884 oatResetRegPool(cUnit);
2885 oatResetDefTracking(cUnit);
2886
2887 //TODO: restore oat incoming liveness optimization
2888 oatClobberAllRegs(cUnit);
2889
buzbee2cfc6392012-05-07 14:51:40 -07002890 if (isEntry) {
buzbeead8f15e2012-06-18 14:49:45 -07002891 RegLocation* argLocs = (RegLocation*)
2892 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2893 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2894 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
buzbeeca7a5e42012-08-20 11:12:18 -07002895 // Skip past Method*
2896 it++;
buzbeead8f15e2012-06-18 14:49:45 -07002897 for (unsigned i = 0; it != it_end; ++it) {
2898 llvm::Value* val = it;
2899 argLocs[i++] = valToLoc(cUnit, val);
2900 llvm::Type* ty = val->getType();
2901 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
buzbeeca7a5e42012-08-20 11:12:18 -07002902 argLocs[i] = argLocs[i-1];
2903 argLocs[i].lowReg = argLocs[i].highReg;
2904 argLocs[i].origSReg++;
2905 argLocs[i].sRegLow = INVALID_SREG;
2906 argLocs[i].highWord = true;
2907 i++;
buzbeead8f15e2012-06-18 14:49:45 -07002908 }
2909 }
2910 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
buzbee2cfc6392012-05-07 14:51:40 -07002911 }
2912
2913 // Visit all of the instructions in the block
2914 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2915 llvm::Instruction* inst = it;
2916 llvm::BasicBlock::iterator nextIt = ++it;
2917 // Extract the Dalvik offset from the instruction
2918 uint32_t opcode = inst->getOpcode();
2919 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2920 if (dexOffsetNode != NULL) {
2921 llvm::ConstantInt* dexOffsetValue =
2922 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2923 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2924 }
2925
buzbee6969d502012-06-15 16:40:31 -07002926 oatResetRegPool(cUnit);
2927 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2928 oatClobberAllRegs(cUnit);
2929 }
2930
2931 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2932 oatResetDefTracking(cUnit);
2933 }
2934
2935#ifndef NDEBUG
2936 /* Reset temp tracking sanity check */
2937 cUnit->liveSReg = INVALID_SREG;
2938#endif
2939
buzbeed1643e42012-09-05 14:06:51 -07002940 // TODO: use llvm opcode name here instead of "boundary" if verbose
2941 LIR* boundaryLIR = markBoundary(cUnit, cUnit->currentDalvikOffset, "boundary");
buzbee6969d502012-06-15 16:40:31 -07002942
2943 /* Remember the first LIR for thisl block*/
2944 if (headLIR == NULL) {
2945 headLIR = boundaryLIR;
2946 headLIR->defMask = ENCODE_ALL;
2947 }
2948
buzbee2cfc6392012-05-07 14:51:40 -07002949 switch(opcode) {
2950
2951 case llvm::Instruction::ICmp: {
2952 llvm::Instruction* nextInst = nextIt;
2953 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2954 if (brInst != NULL /* and... */) {
2955 cvtICmpBr(cUnit, inst, brInst);
2956 ++it;
2957 } else {
2958 cvtICmp(cUnit, inst);
2959 }
2960 }
2961 break;
2962
2963 case llvm::Instruction::Call: {
2964 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2965 llvm::Function* callee = callInst->getCalledFunction();
2966 greenland::IntrinsicHelper::IntrinsicId id =
2967 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2968 switch (id) {
buzbeeb03f4872012-06-11 15:22:11 -07002969 case greenland::IntrinsicHelper::AllocaShadowFrame:
2970 case greenland::IntrinsicHelper::SetShadowFrameEntry:
buzbee6969d502012-06-15 16:40:31 -07002971 case greenland::IntrinsicHelper::PopShadowFrame:
buzbeeb03f4872012-06-11 15:22:11 -07002972 // Ignore shadow frame stuff for quick compiler
2973 break;
buzbee2cfc6392012-05-07 14:51:40 -07002974 case greenland::IntrinsicHelper::CopyInt:
2975 case greenland::IntrinsicHelper::CopyObj:
2976 case greenland::IntrinsicHelper::CopyFloat:
2977 case greenland::IntrinsicHelper::CopyLong:
2978 case greenland::IntrinsicHelper::CopyDouble:
2979 cvtCopy(cUnit, callInst);
2980 break;
2981 case greenland::IntrinsicHelper::ConstInt:
2982 case greenland::IntrinsicHelper::ConstObj:
2983 case greenland::IntrinsicHelper::ConstLong:
2984 case greenland::IntrinsicHelper::ConstFloat:
2985 case greenland::IntrinsicHelper::ConstDouble:
2986 cvtConst(cUnit, callInst);
2987 break;
buzbee4f1181f2012-06-22 13:52:12 -07002988 case greenland::IntrinsicHelper::DivInt:
2989 case greenland::IntrinsicHelper::DivLong:
2990 cvtBinOp(cUnit, kOpDiv, inst);
2991 break;
2992 case greenland::IntrinsicHelper::RemInt:
2993 case greenland::IntrinsicHelper::RemLong:
2994 cvtBinOp(cUnit, kOpRem, inst);
2995 break;
buzbee2cfc6392012-05-07 14:51:40 -07002996 case greenland::IntrinsicHelper::MethodInfo:
buzbeead8f15e2012-06-18 14:49:45 -07002997 // Already dealt with - just ignore it here.
buzbee2cfc6392012-05-07 14:51:40 -07002998 break;
2999 case greenland::IntrinsicHelper::CheckSuspend:
3000 genSuspendTest(cUnit, 0 /* optFlags already applied */);
3001 break;
buzbee4f1181f2012-06-22 13:52:12 -07003002 case greenland::IntrinsicHelper::HLInvokeObj:
buzbee8fa0fda2012-06-27 15:44:52 -07003003 case greenland::IntrinsicHelper::HLInvokeFloat:
3004 case greenland::IntrinsicHelper::HLInvokeDouble:
3005 case greenland::IntrinsicHelper::HLInvokeLong:
3006 case greenland::IntrinsicHelper::HLInvokeInt:
buzbee101305f2012-06-28 18:00:56 -07003007 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
buzbee4f1181f2012-06-22 13:52:12 -07003008 break;
buzbee6969d502012-06-15 16:40:31 -07003009 case greenland::IntrinsicHelper::HLInvokeVoid:
buzbee101305f2012-06-28 18:00:56 -07003010 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
3011 break;
3012 case greenland::IntrinsicHelper::FilledNewArray:
3013 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
3014 break;
3015 case greenland::IntrinsicHelper::FillArrayData:
3016 cvtFillArrayData(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07003017 break;
3018 case greenland::IntrinsicHelper::ConstString:
buzbee101305f2012-06-28 18:00:56 -07003019 cvtConstObject(cUnit, callInst, true /* isString */);
3020 break;
3021 case greenland::IntrinsicHelper::ConstClass:
3022 cvtConstObject(cUnit, callInst, false /* isString */);
3023 break;
3024 case greenland::IntrinsicHelper::CheckCast:
3025 cvtCheckCast(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07003026 break;
buzbee4f1181f2012-06-22 13:52:12 -07003027 case greenland::IntrinsicHelper::NewInstance:
3028 cvtNewInstance(cUnit, callInst);
3029 break;
buzbee8fa0fda2012-06-27 15:44:52 -07003030 case greenland::IntrinsicHelper::HLSgetObject:
buzbee4f1181f2012-06-22 13:52:12 -07003031 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
3032 break;
buzbee8fa0fda2012-06-27 15:44:52 -07003033 case greenland::IntrinsicHelper::HLSget:
3034 case greenland::IntrinsicHelper::HLSgetFloat:
3035 case greenland::IntrinsicHelper::HLSgetBoolean:
3036 case greenland::IntrinsicHelper::HLSgetByte:
3037 case greenland::IntrinsicHelper::HLSgetChar:
3038 case greenland::IntrinsicHelper::HLSgetShort:
3039 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
3040 break;
3041 case greenland::IntrinsicHelper::HLSgetWide:
3042 case greenland::IntrinsicHelper::HLSgetDouble:
3043 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
3044 break;
buzbee76592632012-06-29 15:18:35 -07003045 case greenland::IntrinsicHelper::HLSput:
3046 case greenland::IntrinsicHelper::HLSputFloat:
3047 case greenland::IntrinsicHelper::HLSputBoolean:
3048 case greenland::IntrinsicHelper::HLSputByte:
3049 case greenland::IntrinsicHelper::HLSputChar:
3050 case greenland::IntrinsicHelper::HLSputShort:
3051 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
3052 break;
3053 case greenland::IntrinsicHelper::HLSputWide:
3054 case greenland::IntrinsicHelper::HLSputDouble:
3055 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
3056 break;
buzbeea1da8a52012-07-09 14:00:21 -07003057 case greenland::IntrinsicHelper::HLSputObject:
3058 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
3059 break;
buzbee32412962012-06-26 16:27:56 -07003060 case greenland::IntrinsicHelper::GetException:
3061 cvtMoveException(cUnit, callInst);
3062 break;
3063 case greenland::IntrinsicHelper::Throw:
3064 cvtThrow(cUnit, callInst);
3065 break;
buzbee8fa0fda2012-06-27 15:44:52 -07003066 case greenland::IntrinsicHelper::MonitorEnter:
3067 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
3068 break;
3069 case greenland::IntrinsicHelper::MonitorExit:
3070 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
3071 break;
3072 case greenland::IntrinsicHelper::ArrayLength:
buzbee76592632012-06-29 15:18:35 -07003073 cvtArrayLength(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07003074 break;
3075 case greenland::IntrinsicHelper::NewArray:
3076 cvtNewArray(cUnit, callInst);
3077 break;
3078 case greenland::IntrinsicHelper::InstanceOf:
3079 cvtInstanceOf(cUnit, callInst);
3080 break;
3081
3082 case greenland::IntrinsicHelper::HLArrayGet:
3083 case greenland::IntrinsicHelper::HLArrayGetObject:
3084 case greenland::IntrinsicHelper::HLArrayGetFloat:
3085 cvtAget(cUnit, callInst, kWord, 2);
3086 break;
3087 case greenland::IntrinsicHelper::HLArrayGetWide:
3088 case greenland::IntrinsicHelper::HLArrayGetDouble:
3089 cvtAget(cUnit, callInst, kLong, 3);
3090 break;
3091 case greenland::IntrinsicHelper::HLArrayGetBoolean:
3092 cvtAget(cUnit, callInst, kUnsignedByte, 0);
3093 break;
3094 case greenland::IntrinsicHelper::HLArrayGetByte:
3095 cvtAget(cUnit, callInst, kSignedByte, 0);
3096 break;
3097 case greenland::IntrinsicHelper::HLArrayGetChar:
3098 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
3099 break;
3100 case greenland::IntrinsicHelper::HLArrayGetShort:
3101 cvtAget(cUnit, callInst, kSignedHalf, 1);
3102 break;
3103
3104 case greenland::IntrinsicHelper::HLArrayPut:
buzbee8fa0fda2012-06-27 15:44:52 -07003105 case greenland::IntrinsicHelper::HLArrayPutFloat:
buzbeef1f86362012-07-10 15:18:31 -07003106 cvtAputPrimitive(cUnit, callInst, kWord, 2);
3107 break;
3108 case greenland::IntrinsicHelper::HLArrayPutObject:
3109 cvtAputObj(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07003110 break;
3111 case greenland::IntrinsicHelper::HLArrayPutWide:
3112 case greenland::IntrinsicHelper::HLArrayPutDouble:
buzbeef1f86362012-07-10 15:18:31 -07003113 cvtAputPrimitive(cUnit, callInst, kLong, 3);
buzbee8fa0fda2012-06-27 15:44:52 -07003114 break;
3115 case greenland::IntrinsicHelper::HLArrayPutBoolean:
buzbeef1f86362012-07-10 15:18:31 -07003116 cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
buzbee8fa0fda2012-06-27 15:44:52 -07003117 break;
3118 case greenland::IntrinsicHelper::HLArrayPutByte:
buzbeef1f86362012-07-10 15:18:31 -07003119 cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
buzbee8fa0fda2012-06-27 15:44:52 -07003120 break;
3121 case greenland::IntrinsicHelper::HLArrayPutChar:
buzbeef1f86362012-07-10 15:18:31 -07003122 cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
buzbee8fa0fda2012-06-27 15:44:52 -07003123 break;
3124 case greenland::IntrinsicHelper::HLArrayPutShort:
buzbeef1f86362012-07-10 15:18:31 -07003125 cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
buzbee8fa0fda2012-06-27 15:44:52 -07003126 break;
3127
buzbee101305f2012-06-28 18:00:56 -07003128 case greenland::IntrinsicHelper::HLIGet:
3129 case greenland::IntrinsicHelper::HLIGetFloat:
3130 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3131 break;
3132 case greenland::IntrinsicHelper::HLIGetObject:
3133 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3134 break;
3135 case greenland::IntrinsicHelper::HLIGetWide:
3136 case greenland::IntrinsicHelper::HLIGetDouble:
3137 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3138 break;
3139 case greenland::IntrinsicHelper::HLIGetBoolean:
3140 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
3141 false /* obj */);
3142 break;
3143 case greenland::IntrinsicHelper::HLIGetByte:
3144 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
3145 false /* obj */);
3146 break;
3147 case greenland::IntrinsicHelper::HLIGetChar:
3148 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3149 false /* obj */);
3150 break;
3151 case greenland::IntrinsicHelper::HLIGetShort:
3152 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
3153 false /* obj */);
3154 break;
3155
3156 case greenland::IntrinsicHelper::HLIPut:
3157 case greenland::IntrinsicHelper::HLIPutFloat:
3158 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3159 break;
3160 case greenland::IntrinsicHelper::HLIPutObject:
3161 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3162 break;
3163 case greenland::IntrinsicHelper::HLIPutWide:
3164 case greenland::IntrinsicHelper::HLIPutDouble:
3165 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3166 break;
3167 case greenland::IntrinsicHelper::HLIPutBoolean:
3168 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3169 false /* obj */);
3170 break;
3171 case greenland::IntrinsicHelper::HLIPutByte:
3172 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3173 false /* obj */);
3174 break;
3175 case greenland::IntrinsicHelper::HLIPutChar:
3176 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3177 false /* obj */);
3178 break;
3179 case greenland::IntrinsicHelper::HLIPutShort:
3180 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3181 false /* obj */);
3182 break;
3183
3184 case greenland::IntrinsicHelper::IntToChar:
3185 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3186 break;
3187 case greenland::IntrinsicHelper::IntToShort:
3188 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3189 break;
3190 case greenland::IntrinsicHelper::IntToByte:
3191 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3192 break;
3193
buzbee76592632012-06-29 15:18:35 -07003194 case greenland::IntrinsicHelper::CmplFloat:
3195 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3196 break;
3197 case greenland::IntrinsicHelper::CmpgFloat:
3198 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3199 break;
3200 case greenland::IntrinsicHelper::CmplDouble:
3201 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3202 break;
3203 case greenland::IntrinsicHelper::CmpgDouble:
3204 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3205 break;
3206
3207 case greenland::IntrinsicHelper::CmpLong:
3208 cvtLongCompare(cUnit, callInst);
3209 break;
3210
buzbee2a83e8f2012-07-13 16:42:30 -07003211 case greenland::IntrinsicHelper::SHLLong:
3212 cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
buzbee2cfc6392012-05-07 14:51:40 -07003213 break;
buzbee2a83e8f2012-07-13 16:42:30 -07003214 case greenland::IntrinsicHelper::SHRLong:
3215 cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
3216 break;
3217 case greenland::IntrinsicHelper::USHRLong:
3218 cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
3219 break;
3220 case greenland::IntrinsicHelper::SHLInt:
3221 cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
3222 break;
3223 case greenland::IntrinsicHelper::SHRInt:
3224 cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
3225 break;
3226 case greenland::IntrinsicHelper::USHRInt:
3227 cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
3228 break;
3229
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07003230 case greenland::IntrinsicHelper::CatchTargets: {
3231 llvm::SwitchInst* swInst =
3232 llvm::dyn_cast<llvm::SwitchInst>(nextIt);
3233 DCHECK(swInst != NULL);
3234 /*
3235 * Discard the edges and the following conditional branch.
3236 * Do a direct branch to the default target (which is the
3237 * "work" portion of the pair.
3238 * TODO: awful code layout - rework
3239 */
3240 llvm::BasicBlock* targetBB = swInst->getDefaultDest();
3241 DCHECK(targetBB != NULL);
3242 opUnconditionalBranch(cUnit,
3243 cUnit->blockToLabelMap.Get(targetBB));
3244 ++it;
3245 }
3246 break;
3247
buzbee2cfc6392012-05-07 14:51:40 -07003248 default:
3249 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
3250 << cUnit->intrinsic_helper->GetName(id);
3251 }
3252 }
3253 break;
3254
3255 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3256 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3257 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3258 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3259 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3260 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3261 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3262 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3263 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003264 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3265 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
buzbee4f1181f2012-06-22 13:52:12 -07003266 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3267 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3268 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3269 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3270 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
buzbee76592632012-06-29 15:18:35 -07003271 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
3272 case llvm::Instruction::FPToSI: cvtFPToInt(cUnit, inst); break;
3273 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3274 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3275 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003276
buzbee101305f2012-06-28 18:00:56 -07003277 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3278 break;
3279 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3280 break;
3281
buzbeef58c12c2012-07-03 15:06:29 -07003282 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3283
buzbee32412962012-06-26 16:27:56 -07003284 case llvm::Instruction::Unreachable:
3285 break; // FIXME: can we really ignore these?
3286
buzbee2a83e8f2012-07-13 16:42:30 -07003287 case llvm::Instruction::Shl:
3288 case llvm::Instruction::LShr:
3289 case llvm::Instruction::AShr:
buzbee2cfc6392012-05-07 14:51:40 -07003290 case llvm::Instruction::Invoke:
buzbee2cfc6392012-05-07 14:51:40 -07003291 case llvm::Instruction::FPToUI:
buzbee2cfc6392012-05-07 14:51:40 -07003292 case llvm::Instruction::UIToFP:
buzbee2cfc6392012-05-07 14:51:40 -07003293 case llvm::Instruction::PtrToInt:
3294 case llvm::Instruction::IntToPtr:
buzbee2cfc6392012-05-07 14:51:40 -07003295 case llvm::Instruction::FCmp:
buzbee2cfc6392012-05-07 14:51:40 -07003296 case llvm::Instruction::URem:
3297 case llvm::Instruction::UDiv:
3298 case llvm::Instruction::Resume:
buzbee2cfc6392012-05-07 14:51:40 -07003299 case llvm::Instruction::Alloca:
3300 case llvm::Instruction::GetElementPtr:
3301 case llvm::Instruction::Fence:
3302 case llvm::Instruction::AtomicCmpXchg:
3303 case llvm::Instruction::AtomicRMW:
3304 case llvm::Instruction::BitCast:
3305 case llvm::Instruction::VAArg:
3306 case llvm::Instruction::Select:
3307 case llvm::Instruction::UserOp1:
3308 case llvm::Instruction::UserOp2:
3309 case llvm::Instruction::ExtractElement:
3310 case llvm::Instruction::InsertElement:
3311 case llvm::Instruction::ShuffleVector:
3312 case llvm::Instruction::ExtractValue:
3313 case llvm::Instruction::InsertValue:
3314 case llvm::Instruction::LandingPad:
3315 case llvm::Instruction::IndirectBr:
3316 case llvm::Instruction::Load:
3317 case llvm::Instruction::Store:
3318 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3319
3320 default:
buzbee2a83e8f2012-07-13 16:42:30 -07003321 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3322 break;
buzbee2cfc6392012-05-07 14:51:40 -07003323 }
3324 }
buzbee6969d502012-06-15 16:40:31 -07003325
3326 if (headLIR != NULL) {
3327 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
3328 }
buzbee2cfc6392012-05-07 14:51:40 -07003329 return false;
3330}
3331
3332/*
3333 * Convert LLVM_IR to MIR:
3334 * o Iterate through the LLVM_IR and construct a graph using
3335 * standard MIR building blocks.
3336 * o Perform a basic-block optimization pass to remove unnecessary
3337 * store/load sequences.
3338 * o Convert the LLVM Value operands into RegLocations where applicable.
3339 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3340 * o Perform register promotion
3341 * o Iterate through the graph a basic block at a time, generating
3342 * LIR.
3343 * o Assemble LIR as usual.
3344 * o Profit.
3345 */
3346void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3347{
buzbeead8f15e2012-06-18 14:49:45 -07003348 llvm::Function* func = cUnit->func;
3349 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003350 // Allocate a list for LIR basic block labels
3351 cUnit->blockLabelList =
buzbeea1da8a52012-07-09 14:00:21 -07003352 (LIR*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3353 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003354 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003355 for (llvm::Function::iterator i = func->begin(),
3356 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003357 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3358 &labelList[nextLabel++]);
3359 }
buzbeead8f15e2012-06-18 14:49:45 -07003360
3361 /*
3362 * Keep honest - clear regLocations, Value => RegLocation,
3363 * promotion map and VmapTables.
3364 */
3365 cUnit->locMap.clear(); // Start fresh
3366 cUnit->regLocation = NULL;
3367 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3368 i++) {
3369 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3370 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3371 }
3372 cUnit->coreSpillMask = 0;
3373 cUnit->numCoreSpills = 0;
3374 cUnit->fpSpillMask = 0;
3375 cUnit->numFPSpills = 0;
3376 cUnit->coreVmapTable.clear();
3377 cUnit->fpVmapTable.clear();
buzbeead8f15e2012-06-18 14:49:45 -07003378
3379 /*
3380 * At this point, we've lost all knowledge of register promotion.
3381 * Rebuild that info from the MethodInfo intrinsic (if it
buzbeeca7a5e42012-08-20 11:12:18 -07003382 * exists - not required for correctness). Normally, this will
3383 * be the first instruction we encounter, so we won't have to iterate
3384 * through everything.
buzbeead8f15e2012-06-18 14:49:45 -07003385 */
buzbeeca7a5e42012-08-20 11:12:18 -07003386 for (llvm::inst_iterator i = llvm::inst_begin(func),
3387 e = llvm::inst_end(func); i != e; ++i) {
3388 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(&*i);
3389 if (callInst != NULL) {
3390 llvm::Function* callee = callInst->getCalledFunction();
3391 greenland::IntrinsicHelper::IntrinsicId id =
3392 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3393 if (id == greenland::IntrinsicHelper::MethodInfo) {
3394 if (cUnit->printMe) {
3395 LOG(INFO) << "Found MethodInfo";
3396 }
3397 llvm::MDNode* regInfoNode = callInst->getMetadata("RegInfo");
3398 if (regInfoNode != NULL) {
3399 llvm::ConstantInt* numInsValue =
3400 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(0));
3401 llvm::ConstantInt* numRegsValue =
3402 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(1));
3403 llvm::ConstantInt* numOutsValue =
3404 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(2));
3405 llvm::ConstantInt* numCompilerTempsValue =
3406 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(3));
3407 llvm::ConstantInt* numSSARegsValue =
3408 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(4));
3409 if (cUnit->printMe) {
3410 LOG(INFO) << "RegInfo - Ins:" << numInsValue->getZExtValue()
3411 << ", Regs:" << numRegsValue->getZExtValue()
3412 << ", Outs:" << numOutsValue->getZExtValue()
3413 << ", CTemps:" << numCompilerTempsValue->getZExtValue()
3414 << ", SSARegs:" << numSSARegsValue->getZExtValue();
3415 }
3416 }
3417 llvm::MDNode* pmapInfoNode = callInst->getMetadata("PromotionMap");
3418 if (pmapInfoNode != NULL) {
3419 int elems = pmapInfoNode->getNumOperands();
3420 if (cUnit->printMe) {
3421 LOG(INFO) << "PMap size: " << elems;
3422 }
3423 for (int i = 0; i < elems; i++) {
3424 llvm::ConstantInt* rawMapData =
3425 static_cast<llvm::ConstantInt*>(pmapInfoNode->getOperand(i));
3426 uint32_t mapData = rawMapData->getZExtValue();
3427 PromotionMap* p = &cUnit->promotionMap[i];
3428 p->firstInPair = (mapData >> 24) & 0xff;
3429 p->fpReg = (mapData >> 16) & 0xff;
3430 p->coreReg = (mapData >> 8) & 0xff;
3431 p->fpLocation = static_cast<RegLocationType>((mapData >> 4) & 0xf);
3432 if (p->fpLocation == kLocPhysReg) {
3433 oatRecordFpPromotion(cUnit, p->fpReg, i);
3434 }
3435 p->coreLocation = static_cast<RegLocationType>(mapData & 0xf);
3436 if (p->coreLocation == kLocPhysReg) {
3437 oatRecordCorePromotion(cUnit, p->coreReg, i);
3438 }
3439 }
3440 if (cUnit->printMe) {
3441 oatDumpPromotionMap(cUnit);
3442 }
3443 }
3444 break;
3445 }
3446 }
3447 }
3448 oatAdjustSpillMask(cUnit);
3449 cUnit->frameSize = oatComputeFrameSize(cUnit);
buzbeead8f15e2012-06-18 14:49:45 -07003450
3451 // Create RegLocations for arguments
3452 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3453 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3454 for (; it != it_end; ++it) {
3455 llvm::Value* val = it;
3456 createLocFromValue(cUnit, val);
3457 }
3458 // Create RegLocations for all non-argument defintions
3459 for (llvm::inst_iterator i = llvm::inst_begin(func),
3460 e = llvm::inst_end(func); i != e; ++i) {
3461 llvm::Value* val = &*i;
3462 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3463 createLocFromValue(cUnit, val);
3464 }
3465 }
3466
buzbee2cfc6392012-05-07 14:51:40 -07003467 // Walk the blocks, generating code.
3468 for (llvm::Function::iterator i = cUnit->func->begin(),
3469 e = cUnit->func->end(); i != e; ++i) {
3470 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3471 }
3472
3473 handleSuspendLaunchpads(cUnit);
3474
3475 handleThrowLaunchpads(cUnit);
3476
3477 handleIntrinsicLaunchpads(cUnit);
3478
buzbee692be802012-08-29 15:52:59 -07003479 cUnit->func->eraseFromParent();
3480 cUnit->func = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07003481}
3482
3483
3484} // namespace art
3485
3486#endif // ART_USE_QUICK_COMPILER