blob: 6b78765490e08c33e213218db25ba6bc84e88123 [file] [log] [blame]
buzbee2cfc6392012-05-07 14:51:40 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#if defined(ART_USE_QUICK_COMPILER)
18
19#include "object_utils.h"
20
21#include <llvm/Support/ToolOutputFile.h>
22#include <llvm/Bitcode/ReaderWriter.h>
23#include <llvm/Analysis/Verifier.h>
24#include <llvm/Metadata.h>
25#include <llvm/ADT/DepthFirstIterator.h>
26#include <llvm/Instruction.h>
27#include <llvm/Type.h>
28#include <llvm/Instructions.h>
29#include <llvm/Support/Casting.h>
buzbeead8f15e2012-06-18 14:49:45 -070030#include <llvm/Support/InstIterator.h>
buzbee2cfc6392012-05-07 14:51:40 -070031
Elliott Hughes74847412012-06-20 18:10:21 -070032static const char* kLabelFormat = "L0x%x_%d";
buzbee2cfc6392012-05-07 14:51:40 -070033
34namespace art {
35extern const RegLocation badLoc;
buzbeeb03f4872012-06-11 15:22:11 -070036RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val);
buzbee2cfc6392012-05-07 14:51:40 -070037
38llvm::BasicBlock* getLLVMBlock(CompilationUnit* cUnit, int id)
39{
40 return cUnit->idToBlockMap.Get(id);
41}
42
43llvm::Value* getLLVMValue(CompilationUnit* cUnit, int sReg)
44{
45 return (llvm::Value*)oatGrowableListGetElement(&cUnit->llvmValues, sReg);
46}
47
48// Replace the placeholder value with the real definition
49void defineValue(CompilationUnit* cUnit, llvm::Value* val, int sReg)
50{
51 llvm::Value* placeholder = getLLVMValue(cUnit, sReg);
buzbee9a2487f2012-07-26 14:01:13 -070052 if (placeholder == NULL) {
53 // This can happen on instruction rewrite on verification failure
Bill Buzbeec9f40dd2012-08-15 11:35:25 -070054 LOG(WARNING) << "Null placeholder";
buzbee9a2487f2012-07-26 14:01:13 -070055 return;
56 }
buzbee2cfc6392012-05-07 14:51:40 -070057 placeholder->replaceAllUsesWith(val);
58 val->takeName(placeholder);
59 cUnit->llvmValues.elemList[sReg] = (intptr_t)val;
buzbee4be777b2012-07-12 14:38:18 -070060 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(placeholder);
61 DCHECK(inst != NULL);
62 inst->eraseFromParent();
buzbee2cfc6392012-05-07 14:51:40 -070063}
64
65llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
66{
67 llvm::Type* res = NULL;
68 if (loc.wide) {
69 if (loc.fp)
buzbee4f1181f2012-06-22 13:52:12 -070070 res = cUnit->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070071 else
buzbee4f1181f2012-06-22 13:52:12 -070072 res = cUnit->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070073 } else {
74 if (loc.fp) {
buzbee4f1181f2012-06-22 13:52:12 -070075 res = cUnit->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -070076 } else {
77 if (loc.ref)
78 res = cUnit->irb->GetJObjectTy();
79 else
buzbee4f1181f2012-06-22 13:52:12 -070080 res = cUnit->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -070081 }
82 }
83 return res;
84}
85
buzbeead8f15e2012-06-18 14:49:45 -070086/* Create an in-memory RegLocation from an llvm Value. */
87void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val)
88{
89 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
90 std::string s(val->getName().str());
91 const char* valName = s.c_str();
buzbeead8f15e2012-06-18 14:49:45 -070092 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
93 DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName;
94 int baseSReg = INVALID_SREG;
95 int subscript = -1;
96 sscanf(valName, "v%d_%d", &baseSReg, &subscript);
97 if ((baseSReg == INVALID_SREG) && (!strcmp(valName, "method"))) {
98 baseSReg = SSA_METHOD_BASEREG;
99 subscript = 0;
100 }
buzbeead8f15e2012-06-18 14:49:45 -0700101 DCHECK_NE(baseSReg, INVALID_SREG);
102 DCHECK_NE(subscript, -1);
103 // TODO: redo during C++'ification
104 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
105 INVALID_REG, INVALID_SREG, INVALID_SREG};
106 llvm::Type* ty = val->getType();
107 loc.wide = ((ty == cUnit->irb->getInt64Ty()) ||
108 (ty == cUnit->irb->getDoubleTy()));
109 loc.defined = true;
buzbeeca7a5e42012-08-20 11:12:18 -0700110 loc.home = false; // May change during promotion
buzbeead8f15e2012-06-18 14:49:45 -0700111 loc.sRegLow = baseSReg;
112 loc.origSReg = cUnit->locMap.size();
buzbeeca7a5e42012-08-20 11:12:18 -0700113 PromotionMap pMap = cUnit->promotionMap[baseSReg];
114 if (ty == cUnit->irb->getFloatTy()) {
115 loc.fp = true;
116 if (pMap.fpLocation == kLocPhysReg) {
117 loc.lowReg = pMap.fpReg;
118 loc.location = kLocPhysReg;
119 loc.home = true;
120 }
121 } else if (ty == cUnit->irb->getDoubleTy()) {
122 loc.fp = true;
123 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
124 if ((pMap.fpLocation == kLocPhysReg) &&
125 (pMapHigh.fpLocation == kLocPhysReg) &&
126 ((pMap.fpReg & 0x1) == 0) &&
127 (pMap.fpReg + 1 == pMapHigh.fpReg)) {
128 loc.lowReg = pMap.fpReg;
129 loc.highReg = pMapHigh.fpReg;
130 loc.location = kLocPhysReg;
131 loc.home = true;
132 }
133 } else if (ty == cUnit->irb->GetJObjectTy()) {
134 loc.ref = true;
135 if (pMap.coreLocation == kLocPhysReg) {
136 loc.lowReg = pMap.coreReg;
137 loc.location = kLocPhysReg;
138 loc.home = true;
139 }
140 } else if (ty == cUnit->irb->getInt64Ty()) {
141 loc.core = true;
142 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
143 if ((pMap.coreLocation == kLocPhysReg) &&
144 (pMapHigh.coreLocation == kLocPhysReg)) {
145 loc.lowReg = pMap.coreReg;
146 loc.highReg = pMapHigh.coreReg;
147 loc.location = kLocPhysReg;
148 loc.home = true;
149 }
150 } else {
151 loc.core = true;
152 if (pMap.coreLocation == kLocPhysReg) {
153 loc.lowReg = pMap.coreReg;
154 loc.location = kLocPhysReg;
155 loc.home = true;
156 }
157 }
158
159 if (cUnit->printMe && loc.home) {
160 if (loc.wide) {
161 LOG(INFO) << "Promoted wide " << s << " to regs " << loc.lowReg
162 << "/" << loc.highReg;
163 } else {
164 LOG(INFO) << "Promoted " << s << " to reg " << loc.lowReg;
165 }
166 }
buzbeead8f15e2012-06-18 14:49:45 -0700167 cUnit->locMap.Put(val, loc);
168}
169
buzbee2cfc6392012-05-07 14:51:40 -0700170void initIR(CompilationUnit* cUnit)
171{
172 cUnit->context = new llvm::LLVMContext();
173 cUnit->module = new llvm::Module("art", *cUnit->context);
174 llvm::StructType::create(*cUnit->context, "JavaObject");
175 llvm::StructType::create(*cUnit->context, "Method");
176 llvm::StructType::create(*cUnit->context, "Thread");
177 cUnit->intrinsic_helper =
178 new greenland::IntrinsicHelper(*cUnit->context, *cUnit->module);
179 cUnit->irb =
180 new greenland::IRBuilder(*cUnit->context, *cUnit->module,
181 *cUnit->intrinsic_helper);
182}
183
184void freeIR(CompilationUnit* cUnit)
185{
186 delete cUnit->irb;
187 delete cUnit->intrinsic_helper;
188 delete cUnit->module;
189 delete cUnit->context;
190}
191
192const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
193 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
194}
195
buzbeef58c12c2012-07-03 15:06:29 -0700196llvm::BasicBlock* findCaseTarget(CompilationUnit* cUnit, uint32_t vaddr)
197{
198 BasicBlock* bb = oatFindBlock(cUnit, vaddr);
199 DCHECK(bb != NULL);
200 return getLLVMBlock(cUnit, bb->id);
201}
202
203void convertPackedSwitch(CompilationUnit* cUnit, BasicBlock* bb,
204 int32_t tableOffset, RegLocation rlSrc)
205{
206 const Instruction::PackedSwitchPayload* payload =
207 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
208 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
209
210 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
211
212 llvm::SwitchInst* sw =
213 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
214 payload->case_count);
215
216 for (uint16_t i = 0; i < payload->case_count; ++i) {
217 llvm::BasicBlock* llvmBB =
218 findCaseTarget(cUnit, cUnit->currentDalvikOffset + payload->targets[i]);
219 sw->addCase(cUnit->irb->getInt32(payload->first_key + i), llvmBB);
220 }
221 llvm::MDNode* switchNode =
222 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
223 sw->setMetadata("SwitchTable", switchNode);
224 bb->taken = NULL;
225 bb->fallThrough = NULL;
226}
227
buzbeea1da8a52012-07-09 14:00:21 -0700228void convertSparseSwitch(CompilationUnit* cUnit, BasicBlock* bb,
229 int32_t tableOffset, RegLocation rlSrc)
230{
231 const Instruction::SparseSwitchPayload* payload =
232 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
233 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
234
235 const int32_t* keys = payload->GetKeys();
236 const int32_t* targets = payload->GetTargets();
237
238 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
239
240 llvm::SwitchInst* sw =
241 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
242 payload->case_count);
243
244 for (size_t i = 0; i < payload->case_count; ++i) {
245 llvm::BasicBlock* llvmBB =
246 findCaseTarget(cUnit, cUnit->currentDalvikOffset + targets[i]);
247 sw->addCase(cUnit->irb->getInt32(keys[i]), llvmBB);
248 }
249 llvm::MDNode* switchNode =
250 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
251 sw->setMetadata("SwitchTable", switchNode);
252 bb->taken = NULL;
253 bb->fallThrough = NULL;
254}
255
buzbee8fa0fda2012-06-27 15:44:52 -0700256void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
257 greenland::IntrinsicHelper::IntrinsicId id,
258 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700259{
buzbee8fa0fda2012-06-27 15:44:52 -0700260 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700261 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700262 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
263 defineValue(cUnit, res, rlDest.origSReg);
264}
265
266void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
267 greenland::IntrinsicHelper::IntrinsicId id,
268 RegLocation rlSrc)
269{
270 llvm::SmallVector<llvm::Value*, 2> args;
271 args.push_back(cUnit->irb->getInt32(fieldIndex));
272 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
273 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
274 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700275}
276
buzbee101305f2012-06-28 18:00:56 -0700277void convertFillArrayData(CompilationUnit* cUnit, int32_t offset,
278 RegLocation rlArray)
279{
280 greenland::IntrinsicHelper::IntrinsicId id;
281 id = greenland::IntrinsicHelper::FillArrayData;
282 llvm::SmallVector<llvm::Value*, 2> args;
283 args.push_back(cUnit->irb->getInt32(offset));
284 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
285 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
286 cUnit->irb->CreateCall(intr, args);
287}
288
buzbee2cfc6392012-05-07 14:51:40 -0700289llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
290 RegLocation loc)
291{
292 greenland::IntrinsicHelper::IntrinsicId id;
293 if (loc.wide) {
294 if (loc.fp) {
295 id = greenland::IntrinsicHelper::ConstDouble;
296 } else {
297 id = greenland::IntrinsicHelper::ConstLong;
298 }
299 } else {
300 if (loc.fp) {
301 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700302 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700303 id = greenland::IntrinsicHelper::ConstObj;
304 } else {
305 id = greenland::IntrinsicHelper::ConstInt;
306 }
307 }
308 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
309 return cUnit->irb->CreateCall(intr, src);
310}
buzbeeb03f4872012-06-11 15:22:11 -0700311
312void emitPopShadowFrame(CompilationUnit* cUnit)
313{
314 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
315 greenland::IntrinsicHelper::PopShadowFrame);
316 cUnit->irb->CreateCall(intr);
317}
318
buzbee2cfc6392012-05-07 14:51:40 -0700319llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
320 RegLocation loc)
321{
322 greenland::IntrinsicHelper::IntrinsicId id;
323 if (loc.wide) {
324 if (loc.fp) {
325 id = greenland::IntrinsicHelper::CopyDouble;
326 } else {
327 id = greenland::IntrinsicHelper::CopyLong;
328 }
329 } else {
330 if (loc.fp) {
331 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700332 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700333 id = greenland::IntrinsicHelper::CopyObj;
334 } else {
335 id = greenland::IntrinsicHelper::CopyInt;
336 }
337 }
338 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
339 return cUnit->irb->CreateCall(intr, src);
340}
341
buzbee32412962012-06-26 16:27:56 -0700342void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
343{
344 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
345 greenland::IntrinsicHelper::GetException);
346 llvm::Value* res = cUnit->irb->CreateCall(func);
347 defineValue(cUnit, res, rlDest.origSReg);
348}
349
350void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
351{
352 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
353 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
354 greenland::IntrinsicHelper::Throw);
355 cUnit->irb->CreateCall(func, src);
buzbee32412962012-06-26 16:27:56 -0700356}
357
buzbee8fa0fda2012-06-27 15:44:52 -0700358void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
359 greenland::IntrinsicHelper::IntrinsicId id,
360 RegLocation rlSrc)
361{
362 llvm::SmallVector<llvm::Value*, 2> args;
363 args.push_back(cUnit->irb->getInt32(optFlags));
364 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
365 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
366 cUnit->irb->CreateCall(func, args);
367}
368
buzbee76592632012-06-29 15:18:35 -0700369void convertArrayLength(CompilationUnit* cUnit, int optFlags,
370 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700371{
372 llvm::SmallVector<llvm::Value*, 2> args;
373 args.push_back(cUnit->irb->getInt32(optFlags));
374 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
375 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
376 greenland::IntrinsicHelper::ArrayLength);
buzbee76592632012-06-29 15:18:35 -0700377 llvm::Value* res = cUnit->irb->CreateCall(func, args);
378 defineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700379}
380
buzbee32412962012-06-26 16:27:56 -0700381void convertThrowVerificationError(CompilationUnit* cUnit, int info1, int info2)
382{
383 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
buzbeea1da8a52012-07-09 14:00:21 -0700384 greenland::IntrinsicHelper::ThrowVerificationError);
buzbee32412962012-06-26 16:27:56 -0700385 llvm::SmallVector<llvm::Value*, 2> args;
386 args.push_back(cUnit->irb->getInt32(info1));
387 args.push_back(cUnit->irb->getInt32(info2));
388 cUnit->irb->CreateCall(func, args);
buzbee32412962012-06-26 16:27:56 -0700389}
390
buzbee2cfc6392012-05-07 14:51:40 -0700391void emitSuspendCheck(CompilationUnit* cUnit)
392{
393 greenland::IntrinsicHelper::IntrinsicId id =
394 greenland::IntrinsicHelper::CheckSuspend;
395 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
396 cUnit->irb->CreateCall(intr);
397}
398
399llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
400 llvm::Value* src1, llvm::Value* src2)
401{
402 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700403 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700404 switch(cc) {
405 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
406 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
407 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
408 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
409 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
410 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
411 default: LOG(FATAL) << "Unexpected cc value " << cc;
412 }
413 return res;
414}
415
416void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
417 ConditionCode cc, RegLocation rlSrc1,
418 RegLocation rlSrc2)
419{
420 if (bb->taken->startOffset <= mir->offset) {
421 emitSuspendCheck(cUnit);
422 }
423 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
424 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
425 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
426 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
427 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
428 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700429 // Don't redo the fallthrough branch in the BB driver
430 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700431}
432
433void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
434 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
435{
436 if (bb->taken->startOffset <= mir->offset) {
437 emitSuspendCheck(cUnit);
438 }
439 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
440 llvm::Value* src2;
441 if (rlSrc1.ref) {
442 src2 = cUnit->irb->GetJNull();
443 } else {
444 src2 = cUnit->irb->getInt32(0);
445 }
446 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
buzbee2cfc6392012-05-07 14:51:40 -0700447 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
448 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700449 // Don't redo the fallthrough branch in the BB driver
450 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700451}
452
453llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
454 llvm::Value* src1, llvm::Value* src2)
455{
456 greenland::IntrinsicHelper::IntrinsicId id;
457 if (isLong) {
458 if (isDiv) {
459 id = greenland::IntrinsicHelper::DivLong;
460 } else {
461 id = greenland::IntrinsicHelper::RemLong;
462 }
463 } else if (isDiv) {
464 id = greenland::IntrinsicHelper::DivInt;
465 } else {
466 id = greenland::IntrinsicHelper::RemInt;
467 }
468 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
469 llvm::SmallVector<llvm::Value*, 2>args;
470 args.push_back(src1);
471 args.push_back(src2);
472 return cUnit->irb->CreateCall(intr, args);
473}
474
475llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
476 llvm::Value* src1, llvm::Value* src2)
477{
478 llvm::Value* res = NULL;
479 switch(op) {
480 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
481 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700482 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700483 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
484 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
485 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
486 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
487 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
488 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700489 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
490 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
491 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700492 default:
493 LOG(FATAL) << "Invalid op " << op;
494 }
495 return res;
496}
497
498void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
499 RegLocation rlSrc1, RegLocation rlSrc2)
500{
501 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
502 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
503 llvm::Value* res = NULL;
504 switch(op) {
505 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
506 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
507 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
508 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
509 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
510 default:
511 LOG(FATAL) << "Invalid op " << op;
512 }
513 defineValue(cUnit, res, rlDest.origSReg);
514}
515
buzbee2a83e8f2012-07-13 16:42:30 -0700516void convertShift(CompilationUnit* cUnit,
517 greenland::IntrinsicHelper::IntrinsicId id,
518 RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2)
buzbee4f1181f2012-06-22 13:52:12 -0700519{
buzbee2a83e8f2012-07-13 16:42:30 -0700520 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
521 llvm::SmallVector<llvm::Value*, 2>args;
522 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
523 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
524 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
525 defineValue(cUnit, res, rlDest.origSReg);
526}
527
528void convertShiftLit(CompilationUnit* cUnit,
529 greenland::IntrinsicHelper::IntrinsicId id,
530 RegLocation rlDest, RegLocation rlSrc, int shiftAmount)
531{
532 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
533 llvm::SmallVector<llvm::Value*, 2>args;
534 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
535 args.push_back(cUnit->irb->getInt32(shiftAmount));
536 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700537 defineValue(cUnit, res, rlDest.origSReg);
538}
539
buzbee2cfc6392012-05-07 14:51:40 -0700540void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
541 RegLocation rlSrc1, RegLocation rlSrc2)
542{
543 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
544 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700545 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700546 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
547 defineValue(cUnit, res, rlDest.origSReg);
548}
549
buzbeeb03f4872012-06-11 15:22:11 -0700550void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
551{
552 int index = -1;
553 DCHECK(newVal != NULL);
554 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
555 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
556 if (cUnit->shadowMap[i] == vReg) {
557 index = i;
558 break;
559 }
560 }
Elliott Hughes74847412012-06-20 18:10:21 -0700561 DCHECK_NE(index, -1) << "Corrupt shadowMap";
buzbeeb03f4872012-06-11 15:22:11 -0700562 greenland::IntrinsicHelper::IntrinsicId id =
563 greenland::IntrinsicHelper::SetShadowFrameEntry;
564 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
565 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
566 llvm::Value* args[] = { newVal, tableSlot };
567 cUnit->irb->CreateCall(func, args);
568}
569
buzbee2cfc6392012-05-07 14:51:40 -0700570void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
571 RegLocation rlSrc1, int32_t imm)
572{
573 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
574 llvm::Value* src2 = cUnit->irb->getInt32(imm);
575 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
576 defineValue(cUnit, res, rlDest.origSReg);
577}
578
buzbee101305f2012-06-28 18:00:56 -0700579/*
580 * Process arguments for invoke. Note: this code is also used to
581 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
582 * The requirements are similar.
583 */
buzbee6969d502012-06-15 16:40:31 -0700584void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700585 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700586{
587 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
588 llvm::SmallVector<llvm::Value*, 10> args;
589 // Insert the invokeType
590 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
591 // Insert the method_idx
592 args.push_back(cUnit->irb->getInt32(info->index));
593 // Insert the optimization flags
594 args.push_back(cUnit->irb->getInt32(info->optFlags));
595 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700596 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700597 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
598 args.push_back(val);
599 i += info->args[i].wide ? 2 : 1;
600 }
601 /*
602 * Choose the invoke return type based on actual usage. Note: may
603 * be different than shorty. For example, if a function return value
604 * is not used, we'll treat this as a void invoke.
605 */
606 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700607 if (isFilledNewArray) {
608 id = greenland::IntrinsicHelper::FilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700609 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700610 id = greenland::IntrinsicHelper::HLInvokeVoid;
611 } else {
612 if (info->result.wide) {
613 if (info->result.fp) {
614 id = greenland::IntrinsicHelper::HLInvokeDouble;
615 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700616 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700617 }
618 } else if (info->result.ref) {
619 id = greenland::IntrinsicHelper::HLInvokeObj;
620 } else if (info->result.fp) {
621 id = greenland::IntrinsicHelper::HLInvokeFloat;
622 } else {
623 id = greenland::IntrinsicHelper::HLInvokeInt;
624 }
625 }
626 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
627 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
628 if (info->result.location != kLocInvalid) {
629 defineValue(cUnit, res, info->result.origSReg);
630 }
631}
632
buzbee101305f2012-06-28 18:00:56 -0700633void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
634 greenland::IntrinsicHelper::IntrinsicId id,
635 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700636{
buzbee6969d502012-06-15 16:40:31 -0700637 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700638 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700639 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
640 defineValue(cUnit, res, rlDest.origSReg);
641}
642
buzbee101305f2012-06-28 18:00:56 -0700643void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
644 RegLocation rlSrc)
645{
646 greenland::IntrinsicHelper::IntrinsicId id;
647 id = greenland::IntrinsicHelper::CheckCast;
648 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
649 llvm::SmallVector<llvm::Value*, 2> args;
650 args.push_back(cUnit->irb->getInt32(type_idx));
651 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
652 cUnit->irb->CreateCall(intr, args);
653}
654
buzbee8fa0fda2012-06-27 15:44:52 -0700655void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
656 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700657{
658 greenland::IntrinsicHelper::IntrinsicId id;
659 id = greenland::IntrinsicHelper::NewInstance;
660 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
661 llvm::Value* index = cUnit->irb->getInt32(type_idx);
662 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
663 defineValue(cUnit, res, rlDest.origSReg);
664}
665
buzbee8fa0fda2012-06-27 15:44:52 -0700666void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
667 RegLocation rlDest, RegLocation rlSrc)
668{
669 greenland::IntrinsicHelper::IntrinsicId id;
670 id = greenland::IntrinsicHelper::NewArray;
671 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
672 llvm::SmallVector<llvm::Value*, 2> args;
673 args.push_back(cUnit->irb->getInt32(type_idx));
674 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
675 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
676 defineValue(cUnit, res, rlDest.origSReg);
677}
678
679void convertAget(CompilationUnit* cUnit, int optFlags,
680 greenland::IntrinsicHelper::IntrinsicId id,
681 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
682{
683 llvm::SmallVector<llvm::Value*, 3> args;
684 args.push_back(cUnit->irb->getInt32(optFlags));
685 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
686 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
687 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
688 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
689 defineValue(cUnit, res, rlDest.origSReg);
690}
691
692void convertAput(CompilationUnit* cUnit, int optFlags,
693 greenland::IntrinsicHelper::IntrinsicId id,
694 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
695{
696 llvm::SmallVector<llvm::Value*, 4> args;
697 args.push_back(cUnit->irb->getInt32(optFlags));
698 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
699 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
700 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
701 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
702 cUnit->irb->CreateCall(intr, args);
703}
704
buzbee101305f2012-06-28 18:00:56 -0700705void convertIget(CompilationUnit* cUnit, int optFlags,
706 greenland::IntrinsicHelper::IntrinsicId id,
707 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
708{
709 llvm::SmallVector<llvm::Value*, 3> args;
710 args.push_back(cUnit->irb->getInt32(optFlags));
711 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
712 args.push_back(cUnit->irb->getInt32(fieldIndex));
713 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
714 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
715 defineValue(cUnit, res, rlDest.origSReg);
716}
717
718void convertIput(CompilationUnit* cUnit, int optFlags,
719 greenland::IntrinsicHelper::IntrinsicId id,
720 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
721{
722 llvm::SmallVector<llvm::Value*, 4> args;
723 args.push_back(cUnit->irb->getInt32(optFlags));
724 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
725 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
726 args.push_back(cUnit->irb->getInt32(fieldIndex));
727 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
728 cUnit->irb->CreateCall(intr, args);
729}
730
buzbee8fa0fda2012-06-27 15:44:52 -0700731void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
732 RegLocation rlDest, RegLocation rlSrc)
733{
734 greenland::IntrinsicHelper::IntrinsicId id;
735 id = greenland::IntrinsicHelper::InstanceOf;
736 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
737 llvm::SmallVector<llvm::Value*, 2> args;
738 args.push_back(cUnit->irb->getInt32(type_idx));
739 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
740 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
741 defineValue(cUnit, res, rlDest.origSReg);
742}
743
buzbee101305f2012-06-28 18:00:56 -0700744void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
745 RegLocation rlSrc)
746{
747 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
748 cUnit->irb->getInt64Ty());
749 defineValue(cUnit, res, rlDest.origSReg);
750}
751
buzbee76592632012-06-29 15:18:35 -0700752void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
753 RegLocation rlSrc)
754{
755 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
756 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
757 defineValue(cUnit, res, rlDest.origSReg);
758}
759
760void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
761 RegLocation rlSrc)
762{
763 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
764 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
765 defineValue(cUnit, res, rlDest.origSReg);
766}
767
768void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
769 RegLocation rlSrc)
770{
771 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
772 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
773 defineValue(cUnit, res, rlDest.origSReg);
774}
775
776void convertWideComparison(CompilationUnit* cUnit,
777 greenland::IntrinsicHelper::IntrinsicId id,
778 RegLocation rlDest, RegLocation rlSrc1,
779 RegLocation rlSrc2)
780{
781 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
782 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
783 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
784 llvm::SmallVector<llvm::Value*, 2> args;
785 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
786 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
787 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
788 defineValue(cUnit, res, rlDest.origSReg);
789}
790
buzbee101305f2012-06-28 18:00:56 -0700791void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
792 RegLocation rlSrc,
793 greenland::IntrinsicHelper::IntrinsicId id)
794{
795 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700796 llvm::Value* res =
797 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
798 defineValue(cUnit, res, rlDest.origSReg);
799}
800
801void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
802 RegLocation rlSrc)
803{
804 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
805 defineValue(cUnit, res, rlDest.origSReg);
806}
807
808void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
809 RegLocation rlSrc)
810{
811 llvm::Value* res =
812 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
813 defineValue(cUnit, res, rlDest.origSReg);
814}
815
816void convertFPToInt(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
817 RegLocation rlSrc)
818{
819 llvm::Value* res =
820 cUnit->irb->CreateFPToSI(getLLVMValue(cUnit, rlSrc.origSReg), ty);
821 defineValue(cUnit, res, rlDest.origSReg);
822}
823
824
825void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
826 RegLocation rlSrc)
827{
828 llvm::Value* res =
829 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
830 defineValue(cUnit, res, rlDest.origSReg);
831}
832
833void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
834 RegLocation rlSrc)
835{
836 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
837 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700838 defineValue(cUnit, res, rlDest.origSReg);
839}
840
buzbee2cfc6392012-05-07 14:51:40 -0700841/*
842 * Target-independent code generation. Use only high-level
843 * load/store utilities here, or target-dependent genXX() handlers
844 * when necessary.
845 */
846bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
847 llvm::BasicBlock* llvmBB, LIR* labelList)
848{
849 bool res = false; // Assume success
850 RegLocation rlSrc[3];
851 RegLocation rlDest = badLoc;
buzbee2cfc6392012-05-07 14:51:40 -0700852 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee32412962012-06-26 16:27:56 -0700853 uint32_t vA = mir->dalvikInsn.vA;
buzbee6969d502012-06-15 16:40:31 -0700854 uint32_t vB = mir->dalvikInsn.vB;
855 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700856 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700857
buzbeeb03f4872012-06-11 15:22:11 -0700858 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700859
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700860 if (cUnit->printMe) {
861 if ((int)opcode < kMirOpFirst) {
862 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x"
863 << std::hex << (int)opcode;
864 } else {
865 LOG(INFO) << ".. opcode 0x" << std::hex << (int)opcode;
866 }
867 }
868
buzbee2cfc6392012-05-07 14:51:40 -0700869 /* Prep Src and Dest locations */
870 int nextSreg = 0;
871 int nextLoc = 0;
872 int attrs = oatDataFlowAttributes[opcode];
873 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
874 if (attrs & DF_UA) {
875 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700876 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700877 nextSreg+= 2;
878 } else {
879 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
880 nextSreg++;
881 }
882 }
883 if (attrs & DF_UB) {
884 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700885 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700886 nextSreg+= 2;
887 } else {
888 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
889 nextSreg++;
890 }
891 }
892 if (attrs & DF_UC) {
893 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700894 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700895 } else {
896 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
897 }
898 }
899 if (attrs & DF_DA) {
900 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700901 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700902 } else {
buzbee15bf9802012-06-12 17:49:27 -0700903 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700904 if (rlDest.ref) {
905 objectDefinition = true;
906 }
buzbee2cfc6392012-05-07 14:51:40 -0700907 }
908 }
909
910 switch (opcode) {
911 case Instruction::NOP:
912 break;
913
914 case Instruction::MOVE:
915 case Instruction::MOVE_OBJECT:
916 case Instruction::MOVE_16:
917 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700918 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700919 case Instruction::MOVE_FROM16:
920 case Instruction::MOVE_WIDE:
921 case Instruction::MOVE_WIDE_16:
922 case Instruction::MOVE_WIDE_FROM16: {
923 /*
924 * Moves/copies are meaningless in pure SSA register form,
925 * but we need to preserve them for the conversion back into
926 * MIR (at least until we stop using the Dalvik register maps).
927 * Insert a dummy intrinsic copy call, which will be recognized
928 * by the quick path and removed by the portable path.
929 */
930 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
931 llvm::Value* res = emitCopy(cUnit, src, rlDest);
932 defineValue(cUnit, res, rlDest.origSReg);
933 }
934 break;
935
936 case Instruction::CONST:
937 case Instruction::CONST_4:
938 case Instruction::CONST_16: {
buzbee6969d502012-06-15 16:40:31 -0700939 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700940 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
941 defineValue(cUnit, res, rlDest.origSReg);
942 }
943 break;
944
945 case Instruction::CONST_WIDE_16:
946 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700947 // Sign extend to 64 bits
948 int64_t imm = static_cast<int32_t>(vB);
949 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700950 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
951 defineValue(cUnit, res, rlDest.origSReg);
952 }
953 break;
954
955 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700956 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700957 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
958 defineValue(cUnit, res, rlDest.origSReg);
959 }
960 break;
961
962 case Instruction::CONST_WIDE: {
963 llvm::Constant* immValue =
964 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
965 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
966 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700967 }
968 break;
buzbee2cfc6392012-05-07 14:51:40 -0700969 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700970 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700971 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
972 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
973 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700974 }
975 break;
976
buzbee8fa0fda2012-06-27 15:44:52 -0700977 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700978 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700979 rlSrc[0]);
980 break;
981 case Instruction::SPUT:
982 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700983 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700984 rlSrc[0]);
985 } else {
buzbee76592632012-06-29 15:18:35 -0700986 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700987 }
988 break;
989 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700990 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700991 rlSrc[0]);
992 break;
993 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700994 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700995 break;
996 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -0700997 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700998 break;
999 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -07001000 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001001 break;
1002 case Instruction::SPUT_WIDE:
1003 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -07001004 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -07001005 rlSrc[0]);
1006 } else {
buzbee76592632012-06-29 15:18:35 -07001007 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -07001008 rlSrc[0]);
1009 }
1010 break;
1011
1012 case Instruction::SGET_OBJECT:
1013 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
1014 break;
1015 case Instruction::SGET:
1016 if (rlDest.fp) {
1017 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
1018 } else {
1019 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
1020 }
1021 break;
1022 case Instruction::SGET_BOOLEAN:
1023 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
1024 break;
1025 case Instruction::SGET_BYTE:
1026 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
1027 break;
1028 case Instruction::SGET_CHAR:
1029 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
1030 break;
1031 case Instruction::SGET_SHORT:
1032 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
1033 break;
1034 case Instruction::SGET_WIDE:
1035 if (rlDest.fp) {
1036 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
1037 rlDest);
1038 } else {
1039 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001040 }
1041 break;
buzbee2cfc6392012-05-07 14:51:40 -07001042
1043 case Instruction::RETURN_WIDE:
1044 case Instruction::RETURN:
1045 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -07001046 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001047 emitSuspendCheck(cUnit);
1048 }
buzbeeb03f4872012-06-11 15:22:11 -07001049 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001050 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
1051 bb->hasReturn = true;
1052 }
1053 break;
1054
1055 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -07001056 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001057 emitSuspendCheck(cUnit);
1058 }
buzbeeb03f4872012-06-11 15:22:11 -07001059 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001060 cUnit->irb->CreateRetVoid();
1061 bb->hasReturn = true;
1062 }
1063 break;
1064
1065 case Instruction::IF_EQ:
1066 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1067 break;
1068 case Instruction::IF_NE:
1069 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1070 break;
1071 case Instruction::IF_LT:
1072 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1073 break;
1074 case Instruction::IF_GE:
1075 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1076 break;
1077 case Instruction::IF_GT:
1078 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1079 break;
1080 case Instruction::IF_LE:
1081 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1082 break;
1083 case Instruction::IF_EQZ:
1084 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1085 break;
1086 case Instruction::IF_NEZ:
1087 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1088 break;
1089 case Instruction::IF_LTZ:
1090 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1091 break;
1092 case Instruction::IF_GEZ:
1093 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1094 break;
1095 case Instruction::IF_GTZ:
1096 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1097 break;
1098 case Instruction::IF_LEZ:
1099 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1100 break;
1101
1102 case Instruction::GOTO:
1103 case Instruction::GOTO_16:
1104 case Instruction::GOTO_32: {
1105 if (bb->taken->startOffset <= bb->startOffset) {
1106 emitSuspendCheck(cUnit);
1107 }
1108 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1109 }
1110 break;
1111
1112 case Instruction::ADD_LONG:
1113 case Instruction::ADD_LONG_2ADDR:
1114 case Instruction::ADD_INT:
1115 case Instruction::ADD_INT_2ADDR:
1116 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1117 break;
1118 case Instruction::SUB_LONG:
1119 case Instruction::SUB_LONG_2ADDR:
1120 case Instruction::SUB_INT:
1121 case Instruction::SUB_INT_2ADDR:
1122 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1123 break;
1124 case Instruction::MUL_LONG:
1125 case Instruction::MUL_LONG_2ADDR:
1126 case Instruction::MUL_INT:
1127 case Instruction::MUL_INT_2ADDR:
1128 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1129 break;
1130 case Instruction::DIV_LONG:
1131 case Instruction::DIV_LONG_2ADDR:
1132 case Instruction::DIV_INT:
1133 case Instruction::DIV_INT_2ADDR:
1134 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1135 break;
1136 case Instruction::REM_LONG:
1137 case Instruction::REM_LONG_2ADDR:
1138 case Instruction::REM_INT:
1139 case Instruction::REM_INT_2ADDR:
1140 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1141 break;
1142 case Instruction::AND_LONG:
1143 case Instruction::AND_LONG_2ADDR:
1144 case Instruction::AND_INT:
1145 case Instruction::AND_INT_2ADDR:
1146 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1147 break;
1148 case Instruction::OR_LONG:
1149 case Instruction::OR_LONG_2ADDR:
1150 case Instruction::OR_INT:
1151 case Instruction::OR_INT_2ADDR:
1152 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1153 break;
1154 case Instruction::XOR_LONG:
1155 case Instruction::XOR_LONG_2ADDR:
1156 case Instruction::XOR_INT:
1157 case Instruction::XOR_INT_2ADDR:
1158 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1159 break;
1160 case Instruction::SHL_LONG:
1161 case Instruction::SHL_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001162 convertShift(cUnit, greenland::IntrinsicHelper::SHLLong,
1163 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001164 break;
buzbee2cfc6392012-05-07 14:51:40 -07001165 case Instruction::SHL_INT:
1166 case Instruction::SHL_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001167 convertShift(cUnit, greenland::IntrinsicHelper::SHLInt,
1168 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001169 break;
1170 case Instruction::SHR_LONG:
1171 case Instruction::SHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001172 convertShift(cUnit, greenland::IntrinsicHelper::SHRLong,
1173 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001174 break;
buzbee2cfc6392012-05-07 14:51:40 -07001175 case Instruction::SHR_INT:
1176 case Instruction::SHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001177 convertShift(cUnit, greenland::IntrinsicHelper::SHRInt,
1178 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001179 break;
1180 case Instruction::USHR_LONG:
1181 case Instruction::USHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001182 convertShift(cUnit, greenland::IntrinsicHelper::USHRLong,
1183 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001184 break;
buzbee2cfc6392012-05-07 14:51:40 -07001185 case Instruction::USHR_INT:
1186 case Instruction::USHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001187 convertShift(cUnit, greenland::IntrinsicHelper::USHRInt,
1188 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001189 break;
1190
1191 case Instruction::ADD_INT_LIT16:
1192 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001193 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001194 break;
1195 case Instruction::RSUB_INT:
1196 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001197 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001198 break;
1199 case Instruction::MUL_INT_LIT16:
1200 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001201 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001202 break;
1203 case Instruction::DIV_INT_LIT16:
1204 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001205 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001206 break;
1207 case Instruction::REM_INT_LIT16:
1208 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001209 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001210 break;
1211 case Instruction::AND_INT_LIT16:
1212 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001213 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001214 break;
1215 case Instruction::OR_INT_LIT16:
1216 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001217 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001218 break;
1219 case Instruction::XOR_INT_LIT16:
1220 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001221 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001222 break;
1223 case Instruction::SHL_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001224 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHLInt,
1225 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001226 break;
1227 case Instruction::SHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001228 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHRInt,
1229 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001230 break;
1231 case Instruction::USHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001232 convertShiftLit(cUnit, greenland::IntrinsicHelper::USHRInt,
1233 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001234 break;
1235
1236 case Instruction::ADD_FLOAT:
1237 case Instruction::ADD_FLOAT_2ADDR:
1238 case Instruction::ADD_DOUBLE:
1239 case Instruction::ADD_DOUBLE_2ADDR:
1240 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1241 break;
1242
1243 case Instruction::SUB_FLOAT:
1244 case Instruction::SUB_FLOAT_2ADDR:
1245 case Instruction::SUB_DOUBLE:
1246 case Instruction::SUB_DOUBLE_2ADDR:
1247 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1248 break;
1249
1250 case Instruction::MUL_FLOAT:
1251 case Instruction::MUL_FLOAT_2ADDR:
1252 case Instruction::MUL_DOUBLE:
1253 case Instruction::MUL_DOUBLE_2ADDR:
1254 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1255 break;
1256
1257 case Instruction::DIV_FLOAT:
1258 case Instruction::DIV_FLOAT_2ADDR:
1259 case Instruction::DIV_DOUBLE:
1260 case Instruction::DIV_DOUBLE_2ADDR:
1261 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1262 break;
1263
1264 case Instruction::REM_FLOAT:
1265 case Instruction::REM_FLOAT_2ADDR:
1266 case Instruction::REM_DOUBLE:
1267 case Instruction::REM_DOUBLE_2ADDR:
1268 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1269 break;
1270
buzbee6969d502012-06-15 16:40:31 -07001271 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001272 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1273 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001274 break;
1275 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001276 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1277 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001278 break;
1279
1280 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001281 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1282 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001283 break;
1284 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001285 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1286 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001287 break;
1288
1289 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001290 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1291 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001292 break;
1293 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001294 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1295 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001296 break;
1297
1298 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001299 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1300 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001301 break;
1302 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001303 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1304 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001305 break;
1306
1307 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001308 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1309 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001310 break;
1311 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001312 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1313 false /* NewFilledArray */);
1314 break;
1315 case Instruction::FILLED_NEW_ARRAY:
1316 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1317 true /* NewFilledArray */);
1318 break;
1319 case Instruction::FILLED_NEW_ARRAY_RANGE:
1320 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1321 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001322 break;
1323
1324 case Instruction::CONST_STRING:
1325 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001326 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1327 rlDest);
1328 break;
1329
1330 case Instruction::CONST_CLASS:
1331 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1332 rlDest);
1333 break;
1334
1335 case Instruction::CHECK_CAST:
1336 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001337 break;
1338
buzbee4f1181f2012-06-22 13:52:12 -07001339 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001340 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001341 break;
1342
buzbee32412962012-06-26 16:27:56 -07001343 case Instruction::MOVE_EXCEPTION:
1344 convertMoveException(cUnit, rlDest);
1345 break;
1346
1347 case Instruction::THROW:
1348 convertThrow(cUnit, rlSrc[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001349 /*
1350 * If this throw is standalone, terminate.
1351 * If it might rethrow, force termination
1352 * of the following block.
1353 */
1354 if (bb->fallThrough == NULL) {
1355 cUnit->irb->CreateUnreachable();
1356 } else {
1357 bb->fallThrough->fallThrough = NULL;
1358 bb->fallThrough->taken = NULL;
1359 }
buzbee32412962012-06-26 16:27:56 -07001360 break;
1361
1362 case Instruction::THROW_VERIFICATION_ERROR:
1363 convertThrowVerificationError(cUnit, vA, vB);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001364 UNIMPLEMENTED(WARNING) << "Need dead code elimination pass"
1365 << " - disabling bitcode verification";
1366 cUnit->enableDebug &= ~(1 << kDebugVerifyBitcode);
buzbee32412962012-06-26 16:27:56 -07001367 break;
buzbee6969d502012-06-15 16:40:31 -07001368
buzbee2cfc6392012-05-07 14:51:40 -07001369 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001370 case Instruction::MOVE_RESULT:
1371 case Instruction::MOVE_RESULT_OBJECT:
buzbee85eee022012-07-16 22:12:38 -07001372#if defined(TARGET_ARM)
buzbee9a2487f2012-07-26 14:01:13 -07001373 /*
1374 * Instruction rewriting on verification failure can eliminate
1375 * the invoke that feeds this move0result. It won't ever be reached,
1376 * so we can ignore it.
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001377 * TODO: verify that previous instruction is THROW_VERIFICATION_ERROR,
1378 * or better, add dead-code elimination.
buzbee9a2487f2012-07-26 14:01:13 -07001379 */
1380 UNIMPLEMENTED(WARNING) << "Need to verify previous inst was rewritten";
buzbee85eee022012-07-16 22:12:38 -07001381#else
1382 UNIMPLEMENTED(WARNING) << "need x86 move-result fusing";
1383#endif
1384
buzbee2cfc6392012-05-07 14:51:40 -07001385 break;
1386
1387 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001388 convertMonitorEnterExit(cUnit, optFlags,
1389 greenland::IntrinsicHelper::MonitorEnter,
1390 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001391 break;
1392
1393 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001394 convertMonitorEnterExit(cUnit, optFlags,
1395 greenland::IntrinsicHelper::MonitorExit,
1396 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001397 break;
1398
1399 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001400 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001401 break;
1402
1403 case Instruction::NEW_ARRAY:
1404 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1405 break;
1406
1407 case Instruction::INSTANCE_OF:
1408 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1409 break;
1410
1411 case Instruction::AGET:
1412 if (rlDest.fp) {
1413 convertAget(cUnit, optFlags,
1414 greenland::IntrinsicHelper::HLArrayGetFloat,
1415 rlDest, rlSrc[0], rlSrc[1]);
1416 } else {
1417 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1418 rlDest, rlSrc[0], rlSrc[1]);
1419 }
1420 break;
1421 case Instruction::AGET_OBJECT:
1422 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1423 rlDest, rlSrc[0], rlSrc[1]);
1424 break;
1425 case Instruction::AGET_BOOLEAN:
1426 convertAget(cUnit, optFlags,
1427 greenland::IntrinsicHelper::HLArrayGetBoolean,
1428 rlDest, rlSrc[0], rlSrc[1]);
1429 break;
1430 case Instruction::AGET_BYTE:
1431 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1432 rlDest, rlSrc[0], rlSrc[1]);
1433 break;
1434 case Instruction::AGET_CHAR:
1435 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1436 rlDest, rlSrc[0], rlSrc[1]);
1437 break;
1438 case Instruction::AGET_SHORT:
1439 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1440 rlDest, rlSrc[0], rlSrc[1]);
1441 break;
1442 case Instruction::AGET_WIDE:
1443 if (rlDest.fp) {
1444 convertAget(cUnit, optFlags,
1445 greenland::IntrinsicHelper::HLArrayGetDouble,
1446 rlDest, rlSrc[0], rlSrc[1]);
1447 } else {
1448 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1449 rlDest, rlSrc[0], rlSrc[1]);
1450 }
1451 break;
1452
1453 case Instruction::APUT:
1454 if (rlSrc[0].fp) {
1455 convertAput(cUnit, optFlags,
1456 greenland::IntrinsicHelper::HLArrayPutFloat,
1457 rlSrc[0], rlSrc[1], rlSrc[2]);
1458 } else {
1459 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1460 rlSrc[0], rlSrc[1], rlSrc[2]);
1461 }
1462 break;
1463 case Instruction::APUT_OBJECT:
1464 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1465 rlSrc[0], rlSrc[1], rlSrc[2]);
1466 break;
1467 case Instruction::APUT_BOOLEAN:
1468 convertAput(cUnit, optFlags,
1469 greenland::IntrinsicHelper::HLArrayPutBoolean,
1470 rlSrc[0], rlSrc[1], rlSrc[2]);
1471 break;
1472 case Instruction::APUT_BYTE:
1473 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1474 rlSrc[0], rlSrc[1], rlSrc[2]);
1475 break;
1476 case Instruction::APUT_CHAR:
1477 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1478 rlSrc[0], rlSrc[1], rlSrc[2]);
1479 break;
1480 case Instruction::APUT_SHORT:
1481 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1482 rlSrc[0], rlSrc[1], rlSrc[2]);
1483 break;
1484 case Instruction::APUT_WIDE:
1485 if (rlSrc[0].fp) {
1486 convertAput(cUnit, optFlags,
1487 greenland::IntrinsicHelper::HLArrayPutDouble,
1488 rlSrc[0], rlSrc[1], rlSrc[2]);
1489 } else {
1490 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1491 rlSrc[0], rlSrc[1], rlSrc[2]);
1492 }
1493 break;
1494
buzbee101305f2012-06-28 18:00:56 -07001495 case Instruction::IGET:
1496 if (rlDest.fp) {
1497 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001498 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001499 } else {
1500 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001501 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001502 }
buzbee2cfc6392012-05-07 14:51:40 -07001503 break;
buzbee101305f2012-06-28 18:00:56 -07001504 case Instruction::IGET_OBJECT:
1505 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001506 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001507 break;
1508 case Instruction::IGET_BOOLEAN:
1509 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001510 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001511 break;
1512 case Instruction::IGET_BYTE:
1513 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001514 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001515 break;
1516 case Instruction::IGET_CHAR:
1517 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001518 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001519 break;
1520 case Instruction::IGET_SHORT:
1521 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001522 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001523 break;
1524 case Instruction::IGET_WIDE:
1525 if (rlDest.fp) {
1526 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001527 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001528 } else {
1529 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001530 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001531 }
1532 break;
1533 case Instruction::IPUT:
buzbee85eee022012-07-16 22:12:38 -07001534 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001535 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1536 rlSrc[0], rlSrc[1], vC);
1537 } else {
1538 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1539 rlSrc[0], rlSrc[1], vC);
1540 }
1541 break;
1542 case Instruction::IPUT_OBJECT:
1543 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1544 rlSrc[0], rlSrc[1], vC);
1545 break;
1546 case Instruction::IPUT_BOOLEAN:
1547 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1548 rlSrc[0], rlSrc[1], vC);
1549 break;
1550 case Instruction::IPUT_BYTE:
1551 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1552 rlSrc[0], rlSrc[1], vC);
1553 break;
1554 case Instruction::IPUT_CHAR:
1555 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1556 rlSrc[0], rlSrc[1], vC);
1557 break;
1558 case Instruction::IPUT_SHORT:
1559 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1560 rlSrc[0], rlSrc[1], vC);
1561 break;
1562 case Instruction::IPUT_WIDE:
buzbee85eee022012-07-16 22:12:38 -07001563 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001564 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1565 rlSrc[0], rlSrc[1], vC);
1566 } else {
1567 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1568 rlSrc[0], rlSrc[1], vC);
1569 }
buzbee2cfc6392012-05-07 14:51:40 -07001570 break;
1571
1572 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001573 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001574 break;
1575
buzbee76592632012-06-29 15:18:35 -07001576 case Instruction::LONG_TO_INT:
1577 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1578 break;
1579
buzbee101305f2012-06-28 18:00:56 -07001580 case Instruction::INT_TO_LONG:
1581 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001582 break;
1583
buzbee101305f2012-06-28 18:00:56 -07001584 case Instruction::INT_TO_CHAR:
1585 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1586 greenland::IntrinsicHelper::IntToChar);
1587 break;
1588 case Instruction::INT_TO_BYTE:
1589 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1590 greenland::IntrinsicHelper::IntToByte);
1591 break;
1592 case Instruction::INT_TO_SHORT:
1593 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1594 greenland::IntrinsicHelper::IntToShort);
1595 break;
1596
buzbee76592632012-06-29 15:18:35 -07001597 case Instruction::INT_TO_FLOAT:
1598 case Instruction::LONG_TO_FLOAT:
1599 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001600 break;
1601
buzbee76592632012-06-29 15:18:35 -07001602 case Instruction::INT_TO_DOUBLE:
1603 case Instruction::LONG_TO_DOUBLE:
1604 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001605 break;
1606
buzbee76592632012-06-29 15:18:35 -07001607 case Instruction::FLOAT_TO_DOUBLE:
1608 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001609 break;
1610
buzbee76592632012-06-29 15:18:35 -07001611 case Instruction::DOUBLE_TO_FLOAT:
1612 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001613 break;
1614
1615 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001616 case Instruction::NEG_INT:
1617 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001618 break;
1619
1620 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001621 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001622 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001623 break;
1624
buzbee76592632012-06-29 15:18:35 -07001625 case Instruction::NOT_LONG:
1626 case Instruction::NOT_INT:
1627 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001628 break;
1629
buzbee2cfc6392012-05-07 14:51:40 -07001630 case Instruction::FLOAT_TO_INT:
buzbee2cfc6392012-05-07 14:51:40 -07001631 case Instruction::DOUBLE_TO_INT:
buzbee76592632012-06-29 15:18:35 -07001632 convertFPToInt(cUnit, cUnit->irb->getInt32Ty(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001633 break;
1634
buzbee76592632012-06-29 15:18:35 -07001635 case Instruction::FLOAT_TO_LONG:
1636 case Instruction::DOUBLE_TO_LONG:
1637 convertFPToInt(cUnit, cUnit->irb->getInt64Ty(), rlDest, rlSrc[0]);
1638 break;
1639
1640 case Instruction::CMPL_FLOAT:
1641 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1642 rlDest, rlSrc[0], rlSrc[1]);
1643 break;
1644 case Instruction::CMPG_FLOAT:
1645 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1646 rlDest, rlSrc[0], rlSrc[1]);
1647 break;
1648 case Instruction::CMPL_DOUBLE:
1649 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1650 rlDest, rlSrc[0], rlSrc[1]);
1651 break;
1652 case Instruction::CMPG_DOUBLE:
1653 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1654 rlDest, rlSrc[0], rlSrc[1]);
1655 break;
1656 case Instruction::CMP_LONG:
1657 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1658 rlDest, rlSrc[0], rlSrc[1]);
1659 break;
1660
buzbee76592632012-06-29 15:18:35 -07001661 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001662 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001663 break;
1664
1665 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001666 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001667 break;
buzbee2cfc6392012-05-07 14:51:40 -07001668
1669 default:
buzbee32412962012-06-26 16:27:56 -07001670 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001671 res = true;
1672 }
buzbeeb03f4872012-06-11 15:22:11 -07001673 if (objectDefinition) {
1674 setShadowFrameEntry(cUnit, (llvm::Value*)
1675 cUnit->llvmValues.elemList[rlDest.origSReg]);
1676 }
buzbee2cfc6392012-05-07 14:51:40 -07001677 return res;
1678}
1679
1680/* Extended MIR instructions like PHI */
1681void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1682 llvm::BasicBlock* llvmBB)
1683{
1684
1685 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1686 case kMirOpPhi: {
buzbee2cfc6392012-05-07 14:51:40 -07001687 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001688 /*
1689 * The Art compiler's Phi nodes only handle 32-bit operands,
1690 * representing wide values using a matched set of Phi nodes
1691 * for the lower and upper halves. In the llvm world, we only
1692 * want a single Phi for wides. Here we will simply discard
1693 * the Phi node representing the high word.
1694 */
1695 if (rlDest.highWord) {
1696 return; // No Phi node - handled via low word
1697 }
1698 int* incoming = (int*)mir->dalvikInsn.vB;
buzbee2cfc6392012-05-07 14:51:40 -07001699 llvm::Type* phiType =
1700 llvmTypeFromLocRec(cUnit, rlDest);
1701 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1702 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1703 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001704 // Don't check width here.
1705 loc = oatGetRawSrc(cUnit, mir, i);
1706 DCHECK_EQ(rlDest.wide, loc.wide);
1707 DCHECK_EQ(rlDest.wide & rlDest.highWord, loc.wide & loc.highWord);
1708 DCHECK_EQ(rlDest.fp, loc.fp);
1709 DCHECK_EQ(rlDest.core, loc.core);
1710 DCHECK_EQ(rlDest.ref, loc.ref);
buzbee2cfc6392012-05-07 14:51:40 -07001711 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
1712 getLLVMBlock(cUnit, incoming[i]));
1713 }
1714 defineValue(cUnit, phi, rlDest.origSReg);
1715 break;
1716 }
1717 case kMirOpCopy: {
1718 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1719 break;
1720 }
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001721 case kMirOpNop:
1722 if ((mir == bb->lastMIRInsn) && (bb->taken == NULL) &&
1723 (bb->fallThrough == NULL)) {
1724 cUnit->irb->CreateUnreachable();
1725 }
1726 break;
1727
buzbee2cfc6392012-05-07 14:51:40 -07001728#if defined(TARGET_ARM)
1729 case kMirOpFusedCmplFloat:
1730 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1731 break;
1732 case kMirOpFusedCmpgFloat:
1733 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1734 break;
1735 case kMirOpFusedCmplDouble:
1736 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1737 break;
1738 case kMirOpFusedCmpgDouble:
1739 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1740 break;
1741 case kMirOpFusedCmpLong:
1742 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1743 break;
1744#endif
1745 default:
1746 break;
1747 }
1748}
1749
1750void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1751{
1752 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001753 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001754 arrayRef.push_back(cUnit->irb->getInt32(offset));
1755 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1756 cUnit->irb->SetDexOffset(node);
1757}
1758
1759// Attach method info as metadata to special intrinsic
1760void setMethodInfo(CompilationUnit* cUnit)
1761{
1762 // We don't want dex offset on this
1763 cUnit->irb->SetDexOffset(NULL);
1764 greenland::IntrinsicHelper::IntrinsicId id;
1765 id = greenland::IntrinsicHelper::MethodInfo;
1766 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1767 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1768 llvm::SmallVector<llvm::Value*, 2> regInfo;
1769 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1770 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1771 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1772 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1773 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1774 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1775 inst->setMetadata("RegInfo", regInfoNode);
1776 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1777 llvm::SmallVector<llvm::Value*, 50> pmap;
1778 for (int i = 0; i < promoSize; i++) {
1779 PromotionMap* p = &cUnit->promotionMap[i];
1780 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1781 ((p->fpReg & 0xff) << 16) |
1782 ((p->coreReg & 0xff) << 8) |
1783 ((p->fpLocation & 0xf) << 4) |
1784 (p->coreLocation & 0xf);
1785 pmap.push_back(cUnit->irb->getInt32(mapData));
1786 }
1787 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1788 inst->setMetadata("PromotionMap", mapNode);
1789 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1790}
1791
1792/* Handle the content in each basic block */
1793bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1794{
1795 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
1796 cUnit->irb->SetInsertPoint(llvmBB);
1797 setDexOffset(cUnit, bb->startOffset);
1798
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001799 if (cUnit->printMe) {
1800 LOG(INFO) << "................................";
1801 LOG(INFO) << "Block id " << bb->id;
1802 if (llvmBB != NULL) {
1803 LOG(INFO) << "label " << llvmBB->getName().str().c_str();
1804 } else {
1805 LOG(INFO) << "llvmBB is NULL";
1806 }
1807 }
1808
buzbee2cfc6392012-05-07 14:51:40 -07001809 if (bb->blockType == kEntryBlock) {
1810 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001811 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1812 cUnit->numDalvikRegisters, true,
1813 kAllocMisc);
1814 for (int i = 0; i < cUnit->numSSARegs; i++) {
1815 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1816 }
1817 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1818 if (canBeRef[i]) {
1819 cUnit->numShadowFrameEntries++;
1820 }
1821 }
1822 if (cUnit->numShadowFrameEntries > 0) {
1823 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1824 cUnit->numShadowFrameEntries, true,
1825 kAllocMisc);
1826 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1827 if (canBeRef[i]) {
1828 cUnit->shadowMap[j++] = i;
1829 }
1830 }
1831 greenland::IntrinsicHelper::IntrinsicId id =
1832 greenland::IntrinsicHelper::AllocaShadowFrame;
1833 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1834 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1835 cUnit->irb->CreateCall(func, entries);
1836 }
buzbee2cfc6392012-05-07 14:51:40 -07001837 } else if (bb->blockType == kExitBlock) {
1838 /*
1839 * Because of the differences between how MIR/LIR and llvm handle exit
1840 * blocks, we won't explicitly covert them. On the llvm-to-lir
1841 * path, it will need to be regenereated.
1842 */
1843 return false;
buzbee6969d502012-06-15 16:40:31 -07001844 } else if (bb->blockType == kExceptionHandling) {
1845 /*
1846 * Because we're deferring null checking, delete the associated empty
1847 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001848 */
1849 llvmBB->eraseFromParent();
1850 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001851 }
1852
1853 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1854
1855 setDexOffset(cUnit, mir->offset);
1856
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001857 int opcode = mir->dalvikInsn.opcode;
1858 Instruction::Format dalvikFormat =
1859 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001860
1861 /* If we're compiling for the debugger, generate an update callout */
1862 if (cUnit->genDebugger) {
1863 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1864 //genDebuggerUpdate(cUnit, mir->offset);
1865 }
1866
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001867 if (opcode == kMirOpCheck) {
1868 // Combine check and work halves of throwing instruction.
1869 MIR* workHalf = mir->meta.throwInsn;
1870 mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
1871 opcode = mir->dalvikInsn.opcode;
1872 SSARepresentation* ssaRep = workHalf->ssaRep;
1873 workHalf->ssaRep = mir->ssaRep;
1874 mir->ssaRep = ssaRep;
1875 workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1876 if (bb->successorBlockList.blockListType == kCatch) {
1877 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
1878 greenland::IntrinsicHelper::CatchTargets);
1879 llvm::Value* switchKey =
1880 cUnit->irb->CreateCall(intr, cUnit->irb->getInt32(mir->offset));
1881 GrowableListIterator iter;
1882 oatGrowableListIteratorInit(&bb->successorBlockList.blocks, &iter);
1883 // New basic block to use for work half
1884 llvm::BasicBlock* workBB =
1885 llvm::BasicBlock::Create(*cUnit->context, "", cUnit->func);
1886 llvm::SwitchInst* sw =
1887 cUnit->irb->CreateSwitch(switchKey, workBB,
1888 bb->successorBlockList.blocks.numUsed);
1889 while (true) {
1890 SuccessorBlockInfo *successorBlockInfo =
1891 (SuccessorBlockInfo *) oatGrowableListIteratorNext(&iter);
1892 if (successorBlockInfo == NULL) break;
1893 llvm::BasicBlock *target =
1894 getLLVMBlock(cUnit, successorBlockInfo->block->id);
1895 int typeIndex = successorBlockInfo->key;
1896 sw->addCase(cUnit->irb->getInt32(typeIndex), target);
1897 }
1898 llvmBB = workBB;
1899 cUnit->irb->SetInsertPoint(llvmBB);
1900 }
1901 }
1902
1903 if (opcode >= kMirOpFirst) {
buzbee2cfc6392012-05-07 14:51:40 -07001904 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1905 continue;
1906 }
1907
1908 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1909 NULL /* labelList */);
1910 if (notHandled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001911 Instruction::Code dalvikOpcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001912 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001913 mir->offset, opcode,
buzbee2cfc6392012-05-07 14:51:40 -07001914 Instruction::Name(dalvikOpcode),
1915 dalvikFormat);
1916 }
1917 }
1918
buzbee4be777b2012-07-12 14:38:18 -07001919 if (bb->blockType == kEntryBlock) {
1920 cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
1921 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001922 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1923 }
1924
1925 return false;
1926}
1927
buzbee4f4dfc72012-07-02 14:54:44 -07001928char remapShorty(char shortyType) {
1929 /*
1930 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1931 * and longs/doubles are represented as a pair of registers. When sub-word
1932 * arguments (and method results) are passed, they are extended to Dalvik
1933 * virtual register containers. Because llvm is picky about type consistency,
1934 * we must either cast the "real" type to 32-bit container multiple Dalvik
1935 * register types, or always use the expanded values.
1936 * Here, we're doing the latter. We map the shorty signature to container
1937 * types (which is valid so long as we always do a real expansion of passed
1938 * arguments and field loads).
1939 */
1940 switch(shortyType) {
1941 case 'Z' : shortyType = 'I'; break;
1942 case 'B' : shortyType = 'I'; break;
1943 case 'S' : shortyType = 'I'; break;
1944 case 'C' : shortyType = 'I'; break;
1945 default: break;
1946 }
1947 return shortyType;
1948}
1949
buzbee2cfc6392012-05-07 14:51:40 -07001950llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1951
1952 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001953 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001954 greenland::kAccurate);
1955
1956 // Get argument type
1957 std::vector<llvm::Type*> args_type;
1958
1959 // method object
1960 args_type.push_back(cUnit->irb->GetJMethodTy());
1961
1962 // Do we have a "this"?
1963 if ((cUnit->access_flags & kAccStatic) == 0) {
1964 args_type.push_back(cUnit->irb->GetJObjectTy());
1965 }
1966
1967 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001968 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001969 greenland::kAccurate));
1970 }
1971
1972 return llvm::FunctionType::get(ret_type, args_type, false);
1973}
1974
1975bool createFunction(CompilationUnit* cUnit) {
1976 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1977 /* with_signature */ false));
1978 llvm::FunctionType* func_type = getFunctionType(cUnit);
1979
1980 if (func_type == NULL) {
1981 return false;
1982 }
1983
1984 cUnit->func = llvm::Function::Create(func_type,
1985 llvm::Function::ExternalLinkage,
1986 func_name, cUnit->module);
1987
1988 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1989 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1990
1991 arg_iter->setName("method");
1992 ++arg_iter;
1993
1994 int startSReg = cUnit->numRegs;
1995
1996 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1997 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1998 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1999 }
2000
2001 return true;
2002}
2003
2004bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
2005{
2006 // Skip the exit block
2007 if (bb->blockType == kExitBlock) {
2008 cUnit->idToBlockMap.Put(bb->id, NULL);
2009 } else {
2010 int offset = bb->startOffset;
2011 bool entryBlock = (bb->blockType == kEntryBlock);
2012 llvm::BasicBlock* llvmBB =
2013 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
Elliott Hughes74847412012-06-20 18:10:21 -07002014 StringPrintf(kLabelFormat, offset, bb->id),
buzbee2cfc6392012-05-07 14:51:40 -07002015 cUnit->func);
2016 if (entryBlock) {
2017 cUnit->entryBB = llvmBB;
2018 cUnit->placeholderBB =
2019 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
2020 cUnit->func);
2021 }
2022 cUnit->idToBlockMap.Put(bb->id, llvmBB);
2023 }
2024 return false;
2025}
2026
2027
2028/*
2029 * Convert MIR to LLVM_IR
2030 * o For each ssa name, create LLVM named value. Type these
2031 * appropriately, and ignore high half of wide and double operands.
2032 * o For each MIR basic block, create an LLVM basic block.
2033 * o Iterate through the MIR a basic block at a time, setting arguments
2034 * to recovered ssa name.
2035 */
2036void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
2037{
2038 initIR(cUnit);
2039 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
2040
2041 // Create the function
2042 createFunction(cUnit);
2043
2044 // Create an LLVM basic block for each MIR block in dfs preorder
2045 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
2046 kPreOrderDFSTraversal, false /* isIterative */);
2047 /*
2048 * Create an llvm named value for each MIR SSA name. Note: we'll use
2049 * placeholders for all non-argument values (because we haven't seen
2050 * the definition yet).
2051 */
2052 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2053 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2054 arg_iter++; /* Skip path method */
2055 for (int i = 0; i < cUnit->numSSARegs; i++) {
2056 llvm::Value* val;
buzbee85eee022012-07-16 22:12:38 -07002057 RegLocation rlTemp = cUnit->regLocation[i];
2058 if ((SRegToVReg(cUnit, i) < 0) || rlTemp.highWord) {
buzbee2a83e8f2012-07-13 16:42:30 -07002059 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
2060 } else if ((i < cUnit->numRegs) ||
2061 (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee85eee022012-07-16 22:12:38 -07002062 llvm::Constant* immValue = cUnit->regLocation[i].wide ?
2063 cUnit->irb->GetJLong(0) : cUnit->irb->GetJInt(0);
buzbee2a83e8f2012-07-13 16:42:30 -07002064 val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
2065 val->setName(llvmSSAName(cUnit, i));
buzbee2cfc6392012-05-07 14:51:40 -07002066 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
buzbee2cfc6392012-05-07 14:51:40 -07002067 } else {
2068 // Recover previously-created argument values
2069 llvm::Value* argVal = arg_iter++;
2070 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
2071 }
2072 }
buzbee2cfc6392012-05-07 14:51:40 -07002073
2074 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
2075 kPreOrderDFSTraversal, false /* Iterative */);
2076
buzbee4be777b2012-07-12 14:38:18 -07002077 /*
2078 * In a few rare cases of verification failure, the verifier will
2079 * replace one or more Dalvik opcodes with the special
2080 * throw-verification-failure opcode. This can leave the SSA graph
2081 * in an invalid state, as definitions may be lost, while uses retained.
2082 * To work around this problem, we insert placeholder definitions for
2083 * all Dalvik SSA regs in the "placeholder" block. Here, after
2084 * bitcode conversion is complete, we examine those placeholder definitions
2085 * and delete any with no references (which normally is all of them).
2086 *
2087 * If any definitions remain, we link the placeholder block into the
2088 * CFG. Otherwise, it is deleted.
2089 */
2090 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
2091 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
2092 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2093 DCHECK(inst != NULL);
2094 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2095 DCHECK(val != NULL);
2096 if (val->getNumUses() == 0) {
2097 inst->eraseFromParent();
2098 }
2099 }
2100 setDexOffset(cUnit, 0);
2101 if (cUnit->placeholderBB->empty()) {
2102 cUnit->placeholderBB->eraseFromParent();
2103 } else {
2104 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2105 cUnit->irb->CreateBr(cUnit->entryTargetBB);
2106 cUnit->entryTargetBB = cUnit->placeholderBB;
2107 }
2108 cUnit->irb->SetInsertPoint(cUnit->entryBB);
2109 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07002110
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002111 if (cUnit->enableDebug & (1 << kDebugVerifyBitcode)) {
2112 if (llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction)) {
2113 LOG(INFO) << "Bitcode verification FAILED for "
2114 << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
2115 << " of size " << cUnit->insnsSize;
2116 cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
2117 }
2118 }
buzbee2cfc6392012-05-07 14:51:40 -07002119
buzbeead8f15e2012-06-18 14:49:45 -07002120 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
2121 // Write bitcode to file
2122 std::string errmsg;
2123 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
2124 oatReplaceSpecialChars(fname);
2125 // TODO: make configurable
buzbee4f1181f2012-06-22 13:52:12 -07002126 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002127
buzbeead8f15e2012-06-18 14:49:45 -07002128 llvm::OwningPtr<llvm::tool_output_file> out_file(
2129 new llvm::tool_output_file(fname.c_str(), errmsg,
2130 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002131
buzbeead8f15e2012-06-18 14:49:45 -07002132 if (!errmsg.empty()) {
2133 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2134 }
2135
2136 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
2137 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002138 }
buzbee2cfc6392012-05-07 14:51:40 -07002139}
2140
2141RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
2142 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002143 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002144 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2145 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07002146 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07002147 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002148 // FIXME: need to be more robust, handle FP and be in a position to
2149 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002150 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2151 memset(&res, 0, sizeof(res));
2152 res.location = kLocPhysReg;
2153 res.lowReg = oatAllocTemp(cUnit);
2154 res.home = true;
2155 res.sRegLow = INVALID_SREG;
2156 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002157 llvm::Type* ty = val->getType();
2158 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2159 (ty == cUnit->irb->getDoubleTy()));
2160 if (res.wide) {
2161 res.highReg = oatAllocTemp(cUnit);
2162 }
buzbee4f1181f2012-06-22 13:52:12 -07002163 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002164 } else {
2165 DCHECK_EQ(valName[0], 'v');
2166 int baseSReg = INVALID_SREG;
2167 sscanf(valName.c_str(), "v%d_", &baseSReg);
2168 res = cUnit->regLocation[baseSReg];
2169 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002170 }
2171 } else {
2172 res = it->second;
2173 }
2174 return res;
2175}
2176
2177Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
2178{
2179 Instruction::Code res = Instruction::NOP;
2180 if (isWide) {
2181 switch(op) {
2182 case kOpAdd: res = Instruction::ADD_LONG; break;
2183 case kOpSub: res = Instruction::SUB_LONG; break;
2184 case kOpMul: res = Instruction::MUL_LONG; break;
2185 case kOpDiv: res = Instruction::DIV_LONG; break;
2186 case kOpRem: res = Instruction::REM_LONG; break;
2187 case kOpAnd: res = Instruction::AND_LONG; break;
2188 case kOpOr: res = Instruction::OR_LONG; break;
2189 case kOpXor: res = Instruction::XOR_LONG; break;
2190 case kOpLsl: res = Instruction::SHL_LONG; break;
2191 case kOpLsr: res = Instruction::USHR_LONG; break;
2192 case kOpAsr: res = Instruction::SHR_LONG; break;
2193 default: LOG(FATAL) << "Unexpected OpKind " << op;
2194 }
2195 } else if (isConst){
2196 switch(op) {
2197 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2198 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2199 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2200 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2201 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2202 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2203 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2204 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2205 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2206 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2207 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2208 default: LOG(FATAL) << "Unexpected OpKind " << op;
2209 }
2210 } else {
2211 switch(op) {
2212 case kOpAdd: res = Instruction::ADD_INT; break;
2213 case kOpSub: res = Instruction::SUB_INT; break;
2214 case kOpMul: res = Instruction::MUL_INT; break;
2215 case kOpDiv: res = Instruction::DIV_INT; break;
2216 case kOpRem: res = Instruction::REM_INT; break;
2217 case kOpAnd: res = Instruction::AND_INT; break;
2218 case kOpOr: res = Instruction::OR_INT; break;
2219 case kOpXor: res = Instruction::XOR_INT; break;
2220 case kOpLsl: res = Instruction::SHL_INT; break;
2221 case kOpLsr: res = Instruction::USHR_INT; break;
2222 case kOpAsr: res = Instruction::SHR_INT; break;
2223 default: LOG(FATAL) << "Unexpected OpKind " << op;
2224 }
2225 }
2226 return res;
2227}
2228
buzbee4f1181f2012-06-22 13:52:12 -07002229Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2230{
2231 Instruction::Code res = Instruction::NOP;
2232 if (isWide) {
2233 switch(op) {
2234 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2235 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2236 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2237 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2238 case kOpRem: res = Instruction::REM_DOUBLE; break;
2239 default: LOG(FATAL) << "Unexpected OpKind " << op;
2240 }
2241 } else {
2242 switch(op) {
2243 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2244 case kOpSub: res = Instruction::SUB_FLOAT; break;
2245 case kOpMul: res = Instruction::MUL_FLOAT; break;
2246 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2247 case kOpRem: res = Instruction::REM_FLOAT; break;
2248 default: LOG(FATAL) << "Unexpected OpKind " << op;
2249 }
2250 }
2251 return res;
2252}
2253
2254void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2255{
2256 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002257 /*
2258 * Normally, we won't ever generate an FP operation with an immediate
2259 * operand (not supported in Dex instruction set). However, the IR builder
2260 * may insert them - in particular for createNegFP. Recognize this case
2261 * and deal with it.
2262 */
2263 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2264 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2265 DCHECK(op2C == NULL);
2266 if ((op1C != NULL) && (op == kOpSub)) {
2267 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2268 if (rlDest.wide) {
2269 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2270 } else {
2271 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2272 }
buzbee4f1181f2012-06-22 13:52:12 -07002273 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002274 DCHECK(op1C == NULL);
2275 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2276 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2277 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2278 if (rlDest.wide) {
2279 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2280 } else {
2281 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2282 }
buzbee4f1181f2012-06-22 13:52:12 -07002283 }
2284}
2285
buzbee101305f2012-06-28 18:00:56 -07002286void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2287 Instruction::Code opcode)
2288{
2289 RegLocation rlDest = getLoc(cUnit, inst);
2290 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2291 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2292}
2293
buzbee76592632012-06-29 15:18:35 -07002294void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2295{
2296 RegLocation rlDest = getLoc(cUnit, inst);
2297 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2298 Instruction::Code opcode;
2299 if (rlDest.wide) {
2300 if (rlSrc.wide) {
2301 opcode = Instruction::LONG_TO_DOUBLE;
2302 } else {
2303 opcode = Instruction::INT_TO_DOUBLE;
2304 }
2305 } else {
2306 if (rlSrc.wide) {
2307 opcode = Instruction::LONG_TO_FLOAT;
2308 } else {
2309 opcode = Instruction::INT_TO_FLOAT;
2310 }
2311 }
2312 genConversion(cUnit, opcode, rlDest, rlSrc);
2313}
2314
2315void cvtFPToInt(CompilationUnit* cUnit, llvm::Instruction* inst)
2316{
2317 RegLocation rlDest = getLoc(cUnit, inst);
2318 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2319 Instruction::Code opcode;
2320 if (rlDest.wide) {
2321 if (rlSrc.wide) {
2322 opcode = Instruction::DOUBLE_TO_LONG;
2323 } else {
2324 opcode = Instruction::FLOAT_TO_LONG;
2325 }
2326 } else {
2327 if (rlSrc.wide) {
2328 opcode = Instruction::DOUBLE_TO_INT;
2329 } else {
2330 opcode = Instruction::FLOAT_TO_INT;
2331 }
2332 }
2333 genConversion(cUnit, opcode, rlDest, rlSrc);
2334}
2335
2336void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2337{
2338 RegLocation rlDest = getLoc(cUnit, inst);
2339 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2340 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2341}
2342
2343void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2344{
2345 RegLocation rlDest = getLoc(cUnit, inst);
2346 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2347 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2348 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2349 storeValue(cUnit, rlDest, rlSrc);
2350}
2351
2352void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2353{
2354 RegLocation rlDest = getLoc(cUnit, inst);
2355 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2356 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2357}
2358
2359
buzbee101305f2012-06-28 18:00:56 -07002360void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2361{
2362 // TODO: evaluate src/tgt types and add general support for more than int to long
2363 RegLocation rlDest = getLoc(cUnit, inst);
2364 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2365 DCHECK(rlDest.wide);
2366 DCHECK(!rlSrc.wide);
2367 DCHECK(!rlDest.fp);
2368 DCHECK(!rlSrc.fp);
2369 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2370 if (rlSrc.location == kLocPhysReg) {
2371 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2372 } else {
2373 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2374 }
2375 if (isSigned) {
2376 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2377 } else {
2378 loadConstant(cUnit, rlResult.highReg, 0);
2379 }
2380 storeValueWide(cUnit, rlDest, rlResult);
2381}
2382
buzbee2cfc6392012-05-07 14:51:40 -07002383void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2384{
2385 RegLocation rlDest = getLoc(cUnit, inst);
2386 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002387 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002388 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2389 if ((op == kOpSub) && (lhsImm != NULL)) {
2390 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002391 if (rlSrc1.wide) {
2392 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2393 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2394 } else {
2395 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2396 lhsImm->getSExtValue());
2397 }
buzbee4f1181f2012-06-22 13:52:12 -07002398 return;
2399 }
2400 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002401 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2402 llvm::Value* rhs = inst->getOperand(1);
buzbee9a2487f2012-07-26 14:01:13 -07002403 llvm::ConstantInt* constRhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2404 if (!rlDest.wide && (constRhs != NULL)) {
buzbee2cfc6392012-05-07 14:51:40 -07002405 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
buzbee9a2487f2012-07-26 14:01:13 -07002406 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, constRhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002407 } else {
2408 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
buzbee9a2487f2012-07-26 14:01:13 -07002409 RegLocation rlSrc2;
2410 if (constRhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002411 // ir_builder converts NOT_LONG to xor src, -1. Restore
2412 DCHECK_EQ(dalvikOp, Instruction::XOR_LONG);
2413 DCHECK_EQ(-1L, constRhs->getSExtValue());
2414 dalvikOp = Instruction::NOT_LONG;
buzbee9a2487f2012-07-26 14:01:13 -07002415 rlSrc2 = rlSrc1;
2416 } else {
2417 rlSrc2 = getLoc(cUnit, rhs);
2418 }
buzbee2cfc6392012-05-07 14:51:40 -07002419 if (rlDest.wide) {
2420 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2421 } else {
2422 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2423 }
2424 }
2425}
2426
buzbee2a83e8f2012-07-13 16:42:30 -07002427void cvtShiftOp(CompilationUnit* cUnit, Instruction::Code opcode,
2428 llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002429{
buzbee2a83e8f2012-07-13 16:42:30 -07002430 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2431 RegLocation rlDest = getLoc(cUnit, callInst);
2432 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2433 llvm::Value* rhs = callInst->getArgOperand(1);
2434 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2435 DCHECK(!rlDest.wide);
2436 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002437 } else {
buzbee2a83e8f2012-07-13 16:42:30 -07002438 RegLocation rlShift = getLoc(cUnit, rhs);
2439 if (callInst->getType() == cUnit->irb->getInt64Ty()) {
2440 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2441 } else {
2442 genArithOpInt(cUnit, opcode, rlDest, rlSrc, rlShift);
2443 }
buzbee101305f2012-06-28 18:00:56 -07002444 }
2445}
2446
buzbee2cfc6392012-05-07 14:51:40 -07002447void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2448{
2449 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2450 DCHECK(brInst != NULL);
2451 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2452 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2453 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2454}
2455
2456void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2457{
2458 // Nop - these have already been processed
2459}
2460
2461void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2462{
2463 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2464 llvm::Value* retVal = retInst->getReturnValue();
2465 if (retVal != NULL) {
2466 RegLocation rlSrc = getLoc(cUnit, retVal);
2467 if (rlSrc.wide) {
2468 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2469 } else {
2470 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2471 }
2472 }
2473 genExitSequence(cUnit);
2474}
2475
2476ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2477{
2478 ConditionCode res = kCondAl;
2479 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002480 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002481 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2482 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2483 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002484 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002485 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002486 default: LOG(FATAL) << "Unexpected llvm condition";
2487 }
2488 return res;
2489}
2490
2491void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2492{
2493 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2494 UNIMPLEMENTED(FATAL);
2495}
2496
2497void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2498 llvm::BranchInst* brInst)
2499{
2500 // Get targets
2501 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2502 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2503 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2504 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2505 // Get comparison operands
2506 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2507 ConditionCode cond = getCond(iCmpInst->getPredicate());
2508 llvm::Value* lhs = iCmpInst->getOperand(0);
2509 // Not expecting a constant as 1st operand
2510 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2511 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2512 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2513 llvm::Value* rhs = inst->getOperand(1);
2514#if defined(TARGET_MIPS)
2515 // Compare and branch in one shot
2516 (void)taken;
2517 (void)cond;
2518 (void)rhs;
2519 UNIMPLEMENTED(FATAL);
2520#else
2521 //Compare, then branch
2522 // TODO: handle fused CMP_LONG/IF_xxZ case
2523 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2524 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002525 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
2526 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002527 } else {
2528 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2529 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2530 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2531 }
2532 opCondBranch(cUnit, cond, taken);
2533#endif
2534 // Fallthrough
2535 opUnconditionalBranch(cUnit, fallThrough);
2536}
2537
2538void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2539 llvm::Function* callee)
2540{
2541 UNIMPLEMENTED(FATAL);
2542}
2543
buzbee2cfc6392012-05-07 14:51:40 -07002544void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2545{
buzbee4f1181f2012-06-22 13:52:12 -07002546 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002547 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2548 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002549 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2550 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002551 if (rlSrc.wide) {
2552 storeValueWide(cUnit, rlDest, rlSrc);
2553 } else {
2554 storeValue(cUnit, rlDest, rlSrc);
2555 }
2556}
2557
2558// Note: Immediate arg is a ConstantInt regardless of result type
2559void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2560{
buzbee4f1181f2012-06-22 13:52:12 -07002561 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002562 llvm::ConstantInt* src =
2563 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2564 uint64_t immval = src->getZExtValue();
2565 RegLocation rlDest = getLoc(cUnit, callInst);
2566 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2567 if (rlDest.wide) {
2568 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2569 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2570 storeValueWide(cUnit, rlDest, rlResult);
2571 } else {
2572 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2573 storeValue(cUnit, rlDest, rlResult);
2574 }
2575}
2576
buzbee101305f2012-06-28 18:00:56 -07002577void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2578 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002579{
buzbee4f1181f2012-06-22 13:52:12 -07002580 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002581 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002582 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002583 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002584 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002585 if (isString) {
2586 genConstString(cUnit, index, rlDest);
2587 } else {
2588 genConstClass(cUnit, index, rlDest);
2589 }
2590}
2591
2592void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2593{
2594 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2595 llvm::ConstantInt* offsetVal =
2596 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2597 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2598 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002599}
2600
buzbee4f1181f2012-06-22 13:52:12 -07002601void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2602{
buzbee32412962012-06-26 16:27:56 -07002603 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002604 llvm::ConstantInt* typeIdxVal =
2605 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2606 uint32_t typeIdx = typeIdxVal->getZExtValue();
2607 RegLocation rlDest = getLoc(cUnit, callInst);
2608 genNewInstance(cUnit, typeIdx, rlDest);
2609}
2610
buzbee8fa0fda2012-06-27 15:44:52 -07002611void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2612{
2613 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2614 llvm::ConstantInt* typeIdxVal =
2615 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2616 uint32_t typeIdx = typeIdxVal->getZExtValue();
2617 llvm::Value* len = callInst->getArgOperand(1);
2618 RegLocation rlLen = getLoc(cUnit, len);
2619 RegLocation rlDest = getLoc(cUnit, callInst);
2620 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2621}
2622
2623void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2624{
2625 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2626 llvm::ConstantInt* typeIdxVal =
2627 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2628 uint32_t typeIdx = typeIdxVal->getZExtValue();
2629 llvm::Value* src = callInst->getArgOperand(1);
2630 RegLocation rlSrc = getLoc(cUnit, src);
2631 RegLocation rlDest = getLoc(cUnit, callInst);
2632 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2633}
2634
buzbee32412962012-06-26 16:27:56 -07002635void cvtThrowVerificationError(CompilationUnit* cUnit, llvm::CallInst* callInst)
2636{
2637 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2638 llvm::ConstantInt* info1 =
2639 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2640 llvm::ConstantInt* info2 =
2641 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2642 genThrowVerificationError(cUnit, info1->getZExtValue(), info2->getZExtValue());
2643}
2644
2645void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2646{
2647 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2648 llvm::Value* src = callInst->getArgOperand(0);
2649 RegLocation rlSrc = getLoc(cUnit, src);
2650 genThrow(cUnit, rlSrc);
2651}
2652
buzbee8fa0fda2012-06-27 15:44:52 -07002653void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2654 llvm::CallInst* callInst)
2655{
2656 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2657 llvm::ConstantInt* optFlags =
2658 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2659 llvm::Value* src = callInst->getArgOperand(1);
2660 RegLocation rlSrc = getLoc(cUnit, src);
2661 if (isEnter) {
2662 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2663 } else {
2664 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2665 }
2666}
2667
buzbee76592632012-06-29 15:18:35 -07002668void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002669{
2670 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2671 llvm::ConstantInt* optFlags =
2672 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2673 llvm::Value* src = callInst->getArgOperand(1);
2674 RegLocation rlSrc = getLoc(cUnit, src);
2675 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2676 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2677 RegLocation rlDest = getLoc(cUnit, callInst);
2678 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2679 int lenOffset = Array::LengthOffset().Int32Value();
2680 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2681 storeValue(cUnit, rlDest, rlResult);
2682}
2683
buzbee32412962012-06-26 16:27:56 -07002684void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2685{
2686 DCHECK_EQ(callInst->getNumArgOperands(), 0U);
2687 int exOffset = Thread::ExceptionOffset().Int32Value();
2688 RegLocation rlDest = getLoc(cUnit, callInst);
2689 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2690#if defined(TARGET_X86)
2691 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
2692 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
2693#else
2694 int resetReg = oatAllocTemp(cUnit);
2695 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
2696 loadConstant(cUnit, resetReg, 0);
2697 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
2698 oatFreeTemp(cUnit, resetReg);
2699#endif
2700 storeValue(cUnit, rlDest, rlResult);
2701}
2702
buzbee4f1181f2012-06-22 13:52:12 -07002703void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2704 bool isObject)
2705{
buzbee32412962012-06-26 16:27:56 -07002706 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002707 llvm::ConstantInt* typeIdxVal =
2708 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2709 uint32_t typeIdx = typeIdxVal->getZExtValue();
2710 RegLocation rlDest = getLoc(cUnit, callInst);
2711 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2712}
2713
buzbee8fa0fda2012-06-27 15:44:52 -07002714void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2715 bool isObject)
2716{
2717 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2718 llvm::ConstantInt* typeIdxVal =
2719 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2720 uint32_t typeIdx = typeIdxVal->getZExtValue();
2721 llvm::Value* src = callInst->getArgOperand(1);
2722 RegLocation rlSrc = getLoc(cUnit, src);
2723 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2724}
2725
2726void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2727 int scale)
2728{
2729 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2730 llvm::ConstantInt* optFlags =
2731 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2732 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2733 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2734 RegLocation rlDest = getLoc(cUnit, callInst);
2735 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2736 rlDest, scale);
2737}
2738
2739void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002740 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002741{
2742 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2743 llvm::ConstantInt* optFlags =
2744 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2745 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2746 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2747 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002748 if (isObject) {
2749 genArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
2750 rlSrc, scale);
2751 } else {
2752 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2753 rlSrc, scale);
2754 }
2755}
2756
2757void cvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
2758{
2759 cvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
2760}
2761
2762void cvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
2763 OpSize size, int scale)
2764{
2765 cvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002766}
2767
buzbee101305f2012-06-28 18:00:56 -07002768void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2769 bool isWide, bool isObj)
2770{
2771 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2772 llvm::ConstantInt* optFlags =
2773 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2774 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2775 llvm::ConstantInt* fieldIdx =
2776 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2777 RegLocation rlDest = getLoc(cUnit, callInst);
2778 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2779 size, rlDest, rlObj, isWide, isObj);
2780}
2781
2782void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2783 bool isWide, bool isObj)
2784{
2785 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2786 llvm::ConstantInt* optFlags =
2787 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2788 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2789 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2790 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002791 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002792 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2793 size, rlSrc, rlObj, isWide, isObj);
2794}
2795
2796void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2797{
2798 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2799 llvm::ConstantInt* typeIdx =
2800 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2801 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2802 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2803}
2804
buzbee76592632012-06-29 15:18:35 -07002805void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2806 Instruction::Code opcode)
2807{
2808 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2809 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2810 RegLocation rlDest = getLoc(cUnit, callInst);
2811 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2812}
2813
2814void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2815{
2816 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2817 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2818 RegLocation rlDest = getLoc(cUnit, callInst);
2819 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2820}
2821
buzbeef58c12c2012-07-03 15:06:29 -07002822void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2823{
2824 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2825 DCHECK(swInst != NULL);
2826 llvm::Value* testVal = swInst->getCondition();
2827 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2828 DCHECK(tableOffsetNode != NULL);
2829 llvm::ConstantInt* tableOffsetValue =
2830 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2831 int32_t tableOffset = tableOffsetValue->getSExtValue();
2832 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeea1da8a52012-07-09 14:00:21 -07002833 const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2834 u2 tableMagic = *table;
2835 if (tableMagic == 0x100) {
2836 genPackedSwitch(cUnit, tableOffset, rlSrc);
2837 } else {
2838 DCHECK_EQ(tableMagic, 0x200);
2839 genSparseSwitch(cUnit, tableOffset, rlSrc);
2840 }
buzbeef58c12c2012-07-03 15:06:29 -07002841}
2842
buzbee6969d502012-06-15 16:40:31 -07002843void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002844 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002845{
2846 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2847 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002848 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002849 info->result.location = kLocInvalid;
2850 } else {
2851 info->result = getLoc(cUnit, callInst);
2852 }
2853 llvm::ConstantInt* invokeTypeVal =
2854 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2855 llvm::ConstantInt* methodIndexVal =
2856 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2857 llvm::ConstantInt* optFlagsVal =
2858 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2859 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2860 info->index = methodIndexVal->getZExtValue();
2861 info->optFlags = optFlagsVal->getZExtValue();
2862 info->offset = cUnit->currentDalvikOffset;
2863
buzbee6969d502012-06-15 16:40:31 -07002864 // Count the argument words, and then build argument array.
2865 info->numArgWords = 0;
2866 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2867 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2868 info->numArgWords += tLoc.wide ? 2 : 1;
2869 }
2870 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2871 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2872 // Now, fill in the location records, synthesizing high loc of wide vals
2873 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002874 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002875 if (info->args[next].wide) {
2876 next++;
2877 // TODO: Might make sense to mark this as an invalid loc
2878 info->args[next].origSReg = info->args[next-1].origSReg+1;
2879 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2880 }
2881 next++;
2882 }
buzbee4f4dfc72012-07-02 14:54:44 -07002883 // TODO - rework such that we no longer need isRange
2884 info->isRange = (info->numArgWords > 5);
2885
buzbee76592632012-06-29 15:18:35 -07002886 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002887 genFilledNewArray(cUnit, info);
2888 } else {
2889 genInvoke(cUnit, info);
2890 }
buzbee6969d502012-06-15 16:40:31 -07002891}
2892
buzbeead8f15e2012-06-18 14:49:45 -07002893/* Look up the RegLocation associated with a Value. Must already be defined */
2894RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2895{
2896 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2897 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2898 return it->second;
2899}
2900
buzbee2cfc6392012-05-07 14:51:40 -07002901bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2902{
2903 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2904 // Define the starting label
2905 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2906 // Extract the starting offset from the block's name
2907 if (!isEntry) {
2908 const char* blockName = bb->getName().str().c_str();
2909 int dummy;
Elliott Hughes74847412012-06-20 18:10:21 -07002910 sscanf(blockName, kLabelFormat, &blockLabel->operands[0], &dummy);
buzbee2cfc6392012-05-07 14:51:40 -07002911 }
2912 // Set the label kind
2913 blockLabel->opcode = kPseudoNormalBlockLabel;
2914 // Insert the label
2915 oatAppendLIR(cUnit, blockLabel);
2916
2917 // Free temp registers and reset redundant store tracking */
2918 oatResetRegPool(cUnit);
2919 oatResetDefTracking(cUnit);
2920
2921 //TODO: restore oat incoming liveness optimization
2922 oatClobberAllRegs(cUnit);
2923
buzbee6969d502012-06-15 16:40:31 -07002924 LIR* headLIR = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07002925
2926 if (isEntry) {
2927 cUnit->currentDalvikOffset = 0;
buzbeead8f15e2012-06-18 14:49:45 -07002928 RegLocation* argLocs = (RegLocation*)
2929 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2930 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2931 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
buzbeeca7a5e42012-08-20 11:12:18 -07002932 // Skip past Method*
2933 it++;
buzbeead8f15e2012-06-18 14:49:45 -07002934 for (unsigned i = 0; it != it_end; ++it) {
2935 llvm::Value* val = it;
2936 argLocs[i++] = valToLoc(cUnit, val);
2937 llvm::Type* ty = val->getType();
2938 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
buzbeeca7a5e42012-08-20 11:12:18 -07002939 argLocs[i] = argLocs[i-1];
2940 argLocs[i].lowReg = argLocs[i].highReg;
2941 argLocs[i].origSReg++;
2942 argLocs[i].sRegLow = INVALID_SREG;
2943 argLocs[i].highWord = true;
2944 i++;
buzbeead8f15e2012-06-18 14:49:45 -07002945 }
2946 }
2947 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
buzbee2cfc6392012-05-07 14:51:40 -07002948 }
2949
2950 // Visit all of the instructions in the block
2951 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2952 llvm::Instruction* inst = it;
2953 llvm::BasicBlock::iterator nextIt = ++it;
2954 // Extract the Dalvik offset from the instruction
2955 uint32_t opcode = inst->getOpcode();
2956 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2957 if (dexOffsetNode != NULL) {
2958 llvm::ConstantInt* dexOffsetValue =
2959 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2960 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2961 }
2962
buzbee6969d502012-06-15 16:40:31 -07002963 oatResetRegPool(cUnit);
2964 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2965 oatClobberAllRegs(cUnit);
2966 }
2967
2968 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2969 oatResetDefTracking(cUnit);
2970 }
2971
2972#ifndef NDEBUG
2973 /* Reset temp tracking sanity check */
2974 cUnit->liveSReg = INVALID_SREG;
2975#endif
2976
2977 LIR* boundaryLIR;
2978 const char* instStr = "boundary";
2979 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
2980 (intptr_t) instStr);
2981 cUnit->boundaryMap.Overwrite(cUnit->currentDalvikOffset, boundaryLIR);
2982
2983 /* Remember the first LIR for thisl block*/
2984 if (headLIR == NULL) {
2985 headLIR = boundaryLIR;
2986 headLIR->defMask = ENCODE_ALL;
2987 }
2988
buzbee2cfc6392012-05-07 14:51:40 -07002989 switch(opcode) {
2990
2991 case llvm::Instruction::ICmp: {
2992 llvm::Instruction* nextInst = nextIt;
2993 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2994 if (brInst != NULL /* and... */) {
2995 cvtICmpBr(cUnit, inst, brInst);
2996 ++it;
2997 } else {
2998 cvtICmp(cUnit, inst);
2999 }
3000 }
3001 break;
3002
3003 case llvm::Instruction::Call: {
3004 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
3005 llvm::Function* callee = callInst->getCalledFunction();
3006 greenland::IntrinsicHelper::IntrinsicId id =
3007 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3008 switch (id) {
buzbeeb03f4872012-06-11 15:22:11 -07003009 case greenland::IntrinsicHelper::AllocaShadowFrame:
3010 case greenland::IntrinsicHelper::SetShadowFrameEntry:
buzbee6969d502012-06-15 16:40:31 -07003011 case greenland::IntrinsicHelper::PopShadowFrame:
buzbeeb03f4872012-06-11 15:22:11 -07003012 // Ignore shadow frame stuff for quick compiler
3013 break;
buzbee2cfc6392012-05-07 14:51:40 -07003014 case greenland::IntrinsicHelper::CopyInt:
3015 case greenland::IntrinsicHelper::CopyObj:
3016 case greenland::IntrinsicHelper::CopyFloat:
3017 case greenland::IntrinsicHelper::CopyLong:
3018 case greenland::IntrinsicHelper::CopyDouble:
3019 cvtCopy(cUnit, callInst);
3020 break;
3021 case greenland::IntrinsicHelper::ConstInt:
3022 case greenland::IntrinsicHelper::ConstObj:
3023 case greenland::IntrinsicHelper::ConstLong:
3024 case greenland::IntrinsicHelper::ConstFloat:
3025 case greenland::IntrinsicHelper::ConstDouble:
3026 cvtConst(cUnit, callInst);
3027 break;
buzbee4f1181f2012-06-22 13:52:12 -07003028 case greenland::IntrinsicHelper::DivInt:
3029 case greenland::IntrinsicHelper::DivLong:
3030 cvtBinOp(cUnit, kOpDiv, inst);
3031 break;
3032 case greenland::IntrinsicHelper::RemInt:
3033 case greenland::IntrinsicHelper::RemLong:
3034 cvtBinOp(cUnit, kOpRem, inst);
3035 break;
buzbee2cfc6392012-05-07 14:51:40 -07003036 case greenland::IntrinsicHelper::MethodInfo:
buzbeead8f15e2012-06-18 14:49:45 -07003037 // Already dealt with - just ignore it here.
buzbee2cfc6392012-05-07 14:51:40 -07003038 break;
3039 case greenland::IntrinsicHelper::CheckSuspend:
3040 genSuspendTest(cUnit, 0 /* optFlags already applied */);
3041 break;
buzbee4f1181f2012-06-22 13:52:12 -07003042 case greenland::IntrinsicHelper::HLInvokeObj:
buzbee8fa0fda2012-06-27 15:44:52 -07003043 case greenland::IntrinsicHelper::HLInvokeFloat:
3044 case greenland::IntrinsicHelper::HLInvokeDouble:
3045 case greenland::IntrinsicHelper::HLInvokeLong:
3046 case greenland::IntrinsicHelper::HLInvokeInt:
buzbee101305f2012-06-28 18:00:56 -07003047 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
buzbee4f1181f2012-06-22 13:52:12 -07003048 break;
buzbee6969d502012-06-15 16:40:31 -07003049 case greenland::IntrinsicHelper::HLInvokeVoid:
buzbee101305f2012-06-28 18:00:56 -07003050 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
3051 break;
3052 case greenland::IntrinsicHelper::FilledNewArray:
3053 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
3054 break;
3055 case greenland::IntrinsicHelper::FillArrayData:
3056 cvtFillArrayData(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07003057 break;
3058 case greenland::IntrinsicHelper::ConstString:
buzbee101305f2012-06-28 18:00:56 -07003059 cvtConstObject(cUnit, callInst, true /* isString */);
3060 break;
3061 case greenland::IntrinsicHelper::ConstClass:
3062 cvtConstObject(cUnit, callInst, false /* isString */);
3063 break;
3064 case greenland::IntrinsicHelper::CheckCast:
3065 cvtCheckCast(cUnit, callInst);
buzbee6969d502012-06-15 16:40:31 -07003066 break;
buzbee4f1181f2012-06-22 13:52:12 -07003067 case greenland::IntrinsicHelper::NewInstance:
3068 cvtNewInstance(cUnit, callInst);
3069 break;
buzbee8fa0fda2012-06-27 15:44:52 -07003070 case greenland::IntrinsicHelper::HLSgetObject:
buzbee4f1181f2012-06-22 13:52:12 -07003071 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
3072 break;
buzbee8fa0fda2012-06-27 15:44:52 -07003073 case greenland::IntrinsicHelper::HLSget:
3074 case greenland::IntrinsicHelper::HLSgetFloat:
3075 case greenland::IntrinsicHelper::HLSgetBoolean:
3076 case greenland::IntrinsicHelper::HLSgetByte:
3077 case greenland::IntrinsicHelper::HLSgetChar:
3078 case greenland::IntrinsicHelper::HLSgetShort:
3079 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
3080 break;
3081 case greenland::IntrinsicHelper::HLSgetWide:
3082 case greenland::IntrinsicHelper::HLSgetDouble:
3083 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
3084 break;
buzbee76592632012-06-29 15:18:35 -07003085 case greenland::IntrinsicHelper::HLSput:
3086 case greenland::IntrinsicHelper::HLSputFloat:
3087 case greenland::IntrinsicHelper::HLSputBoolean:
3088 case greenland::IntrinsicHelper::HLSputByte:
3089 case greenland::IntrinsicHelper::HLSputChar:
3090 case greenland::IntrinsicHelper::HLSputShort:
3091 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
3092 break;
3093 case greenland::IntrinsicHelper::HLSputWide:
3094 case greenland::IntrinsicHelper::HLSputDouble:
3095 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
3096 break;
buzbeea1da8a52012-07-09 14:00:21 -07003097 case greenland::IntrinsicHelper::HLSputObject:
3098 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
3099 break;
buzbee32412962012-06-26 16:27:56 -07003100 case greenland::IntrinsicHelper::GetException:
3101 cvtMoveException(cUnit, callInst);
3102 break;
3103 case greenland::IntrinsicHelper::Throw:
3104 cvtThrow(cUnit, callInst);
3105 break;
3106 case greenland::IntrinsicHelper::ThrowVerificationError:
buzbee8fa0fda2012-06-27 15:44:52 -07003107 cvtThrowVerificationError(cUnit, callInst);
buzbee32412962012-06-26 16:27:56 -07003108 break;
buzbee8fa0fda2012-06-27 15:44:52 -07003109 case greenland::IntrinsicHelper::MonitorEnter:
3110 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
3111 break;
3112 case greenland::IntrinsicHelper::MonitorExit:
3113 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
3114 break;
3115 case greenland::IntrinsicHelper::ArrayLength:
buzbee76592632012-06-29 15:18:35 -07003116 cvtArrayLength(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07003117 break;
3118 case greenland::IntrinsicHelper::NewArray:
3119 cvtNewArray(cUnit, callInst);
3120 break;
3121 case greenland::IntrinsicHelper::InstanceOf:
3122 cvtInstanceOf(cUnit, callInst);
3123 break;
3124
3125 case greenland::IntrinsicHelper::HLArrayGet:
3126 case greenland::IntrinsicHelper::HLArrayGetObject:
3127 case greenland::IntrinsicHelper::HLArrayGetFloat:
3128 cvtAget(cUnit, callInst, kWord, 2);
3129 break;
3130 case greenland::IntrinsicHelper::HLArrayGetWide:
3131 case greenland::IntrinsicHelper::HLArrayGetDouble:
3132 cvtAget(cUnit, callInst, kLong, 3);
3133 break;
3134 case greenland::IntrinsicHelper::HLArrayGetBoolean:
3135 cvtAget(cUnit, callInst, kUnsignedByte, 0);
3136 break;
3137 case greenland::IntrinsicHelper::HLArrayGetByte:
3138 cvtAget(cUnit, callInst, kSignedByte, 0);
3139 break;
3140 case greenland::IntrinsicHelper::HLArrayGetChar:
3141 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
3142 break;
3143 case greenland::IntrinsicHelper::HLArrayGetShort:
3144 cvtAget(cUnit, callInst, kSignedHalf, 1);
3145 break;
3146
3147 case greenland::IntrinsicHelper::HLArrayPut:
buzbee8fa0fda2012-06-27 15:44:52 -07003148 case greenland::IntrinsicHelper::HLArrayPutFloat:
buzbeef1f86362012-07-10 15:18:31 -07003149 cvtAputPrimitive(cUnit, callInst, kWord, 2);
3150 break;
3151 case greenland::IntrinsicHelper::HLArrayPutObject:
3152 cvtAputObj(cUnit, callInst);
buzbee8fa0fda2012-06-27 15:44:52 -07003153 break;
3154 case greenland::IntrinsicHelper::HLArrayPutWide:
3155 case greenland::IntrinsicHelper::HLArrayPutDouble:
buzbeef1f86362012-07-10 15:18:31 -07003156 cvtAputPrimitive(cUnit, callInst, kLong, 3);
buzbee8fa0fda2012-06-27 15:44:52 -07003157 break;
3158 case greenland::IntrinsicHelper::HLArrayPutBoolean:
buzbeef1f86362012-07-10 15:18:31 -07003159 cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
buzbee8fa0fda2012-06-27 15:44:52 -07003160 break;
3161 case greenland::IntrinsicHelper::HLArrayPutByte:
buzbeef1f86362012-07-10 15:18:31 -07003162 cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
buzbee8fa0fda2012-06-27 15:44:52 -07003163 break;
3164 case greenland::IntrinsicHelper::HLArrayPutChar:
buzbeef1f86362012-07-10 15:18:31 -07003165 cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
buzbee8fa0fda2012-06-27 15:44:52 -07003166 break;
3167 case greenland::IntrinsicHelper::HLArrayPutShort:
buzbeef1f86362012-07-10 15:18:31 -07003168 cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
buzbee8fa0fda2012-06-27 15:44:52 -07003169 break;
3170
buzbee101305f2012-06-28 18:00:56 -07003171 case greenland::IntrinsicHelper::HLIGet:
3172 case greenland::IntrinsicHelper::HLIGetFloat:
3173 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3174 break;
3175 case greenland::IntrinsicHelper::HLIGetObject:
3176 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3177 break;
3178 case greenland::IntrinsicHelper::HLIGetWide:
3179 case greenland::IntrinsicHelper::HLIGetDouble:
3180 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3181 break;
3182 case greenland::IntrinsicHelper::HLIGetBoolean:
3183 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
3184 false /* obj */);
3185 break;
3186 case greenland::IntrinsicHelper::HLIGetByte:
3187 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
3188 false /* obj */);
3189 break;
3190 case greenland::IntrinsicHelper::HLIGetChar:
3191 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3192 false /* obj */);
3193 break;
3194 case greenland::IntrinsicHelper::HLIGetShort:
3195 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
3196 false /* obj */);
3197 break;
3198
3199 case greenland::IntrinsicHelper::HLIPut:
3200 case greenland::IntrinsicHelper::HLIPutFloat:
3201 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3202 break;
3203 case greenland::IntrinsicHelper::HLIPutObject:
3204 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3205 break;
3206 case greenland::IntrinsicHelper::HLIPutWide:
3207 case greenland::IntrinsicHelper::HLIPutDouble:
3208 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3209 break;
3210 case greenland::IntrinsicHelper::HLIPutBoolean:
3211 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3212 false /* obj */);
3213 break;
3214 case greenland::IntrinsicHelper::HLIPutByte:
3215 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3216 false /* obj */);
3217 break;
3218 case greenland::IntrinsicHelper::HLIPutChar:
3219 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3220 false /* obj */);
3221 break;
3222 case greenland::IntrinsicHelper::HLIPutShort:
3223 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3224 false /* obj */);
3225 break;
3226
3227 case greenland::IntrinsicHelper::IntToChar:
3228 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3229 break;
3230 case greenland::IntrinsicHelper::IntToShort:
3231 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3232 break;
3233 case greenland::IntrinsicHelper::IntToByte:
3234 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3235 break;
3236
buzbee76592632012-06-29 15:18:35 -07003237 case greenland::IntrinsicHelper::CmplFloat:
3238 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3239 break;
3240 case greenland::IntrinsicHelper::CmpgFloat:
3241 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3242 break;
3243 case greenland::IntrinsicHelper::CmplDouble:
3244 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3245 break;
3246 case greenland::IntrinsicHelper::CmpgDouble:
3247 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3248 break;
3249
3250 case greenland::IntrinsicHelper::CmpLong:
3251 cvtLongCompare(cUnit, callInst);
3252 break;
3253
buzbee2a83e8f2012-07-13 16:42:30 -07003254 case greenland::IntrinsicHelper::SHLLong:
3255 cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
buzbee2cfc6392012-05-07 14:51:40 -07003256 break;
buzbee2a83e8f2012-07-13 16:42:30 -07003257 case greenland::IntrinsicHelper::SHRLong:
3258 cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
3259 break;
3260 case greenland::IntrinsicHelper::USHRLong:
3261 cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
3262 break;
3263 case greenland::IntrinsicHelper::SHLInt:
3264 cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
3265 break;
3266 case greenland::IntrinsicHelper::SHRInt:
3267 cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
3268 break;
3269 case greenland::IntrinsicHelper::USHRInt:
3270 cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
3271 break;
3272
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07003273 case greenland::IntrinsicHelper::CatchTargets: {
3274 llvm::SwitchInst* swInst =
3275 llvm::dyn_cast<llvm::SwitchInst>(nextIt);
3276 DCHECK(swInst != NULL);
3277 /*
3278 * Discard the edges and the following conditional branch.
3279 * Do a direct branch to the default target (which is the
3280 * "work" portion of the pair.
3281 * TODO: awful code layout - rework
3282 */
3283 llvm::BasicBlock* targetBB = swInst->getDefaultDest();
3284 DCHECK(targetBB != NULL);
3285 opUnconditionalBranch(cUnit,
3286 cUnit->blockToLabelMap.Get(targetBB));
3287 ++it;
3288 }
3289 break;
3290
buzbee2cfc6392012-05-07 14:51:40 -07003291 default:
3292 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
3293 << cUnit->intrinsic_helper->GetName(id);
3294 }
3295 }
3296 break;
3297
3298 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3299 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3300 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3301 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3302 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3303 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3304 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3305 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3306 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003307 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3308 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
buzbee4f1181f2012-06-22 13:52:12 -07003309 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3310 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3311 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3312 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3313 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
buzbee76592632012-06-29 15:18:35 -07003314 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
3315 case llvm::Instruction::FPToSI: cvtFPToInt(cUnit, inst); break;
3316 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3317 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3318 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
buzbee2cfc6392012-05-07 14:51:40 -07003319
buzbee101305f2012-06-28 18:00:56 -07003320 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3321 break;
3322 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3323 break;
3324
buzbeef58c12c2012-07-03 15:06:29 -07003325 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3326
buzbee32412962012-06-26 16:27:56 -07003327 case llvm::Instruction::Unreachable:
3328 break; // FIXME: can we really ignore these?
3329
buzbee2a83e8f2012-07-13 16:42:30 -07003330 case llvm::Instruction::Shl:
3331 case llvm::Instruction::LShr:
3332 case llvm::Instruction::AShr:
buzbee2cfc6392012-05-07 14:51:40 -07003333 case llvm::Instruction::Invoke:
buzbee2cfc6392012-05-07 14:51:40 -07003334 case llvm::Instruction::FPToUI:
buzbee2cfc6392012-05-07 14:51:40 -07003335 case llvm::Instruction::UIToFP:
buzbee2cfc6392012-05-07 14:51:40 -07003336 case llvm::Instruction::PtrToInt:
3337 case llvm::Instruction::IntToPtr:
buzbee2cfc6392012-05-07 14:51:40 -07003338 case llvm::Instruction::FCmp:
buzbee2cfc6392012-05-07 14:51:40 -07003339 case llvm::Instruction::URem:
3340 case llvm::Instruction::UDiv:
3341 case llvm::Instruction::Resume:
buzbee2cfc6392012-05-07 14:51:40 -07003342 case llvm::Instruction::Alloca:
3343 case llvm::Instruction::GetElementPtr:
3344 case llvm::Instruction::Fence:
3345 case llvm::Instruction::AtomicCmpXchg:
3346 case llvm::Instruction::AtomicRMW:
3347 case llvm::Instruction::BitCast:
3348 case llvm::Instruction::VAArg:
3349 case llvm::Instruction::Select:
3350 case llvm::Instruction::UserOp1:
3351 case llvm::Instruction::UserOp2:
3352 case llvm::Instruction::ExtractElement:
3353 case llvm::Instruction::InsertElement:
3354 case llvm::Instruction::ShuffleVector:
3355 case llvm::Instruction::ExtractValue:
3356 case llvm::Instruction::InsertValue:
3357 case llvm::Instruction::LandingPad:
3358 case llvm::Instruction::IndirectBr:
3359 case llvm::Instruction::Load:
3360 case llvm::Instruction::Store:
3361 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3362
3363 default:
buzbee2a83e8f2012-07-13 16:42:30 -07003364 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3365 break;
buzbee2cfc6392012-05-07 14:51:40 -07003366 }
3367 }
buzbee6969d502012-06-15 16:40:31 -07003368
3369 if (headLIR != NULL) {
3370 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
3371 }
buzbee2cfc6392012-05-07 14:51:40 -07003372 return false;
3373}
3374
3375/*
3376 * Convert LLVM_IR to MIR:
3377 * o Iterate through the LLVM_IR and construct a graph using
3378 * standard MIR building blocks.
3379 * o Perform a basic-block optimization pass to remove unnecessary
3380 * store/load sequences.
3381 * o Convert the LLVM Value operands into RegLocations where applicable.
3382 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3383 * o Perform register promotion
3384 * o Iterate through the graph a basic block at a time, generating
3385 * LIR.
3386 * o Assemble LIR as usual.
3387 * o Profit.
3388 */
3389void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3390{
buzbeead8f15e2012-06-18 14:49:45 -07003391 llvm::Function* func = cUnit->func;
3392 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003393 // Allocate a list for LIR basic block labels
3394 cUnit->blockLabelList =
buzbeea1da8a52012-07-09 14:00:21 -07003395 (LIR*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3396 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003397 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003398 for (llvm::Function::iterator i = func->begin(),
3399 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003400 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3401 &labelList[nextLabel++]);
3402 }
buzbeead8f15e2012-06-18 14:49:45 -07003403
3404 /*
3405 * Keep honest - clear regLocations, Value => RegLocation,
3406 * promotion map and VmapTables.
3407 */
3408 cUnit->locMap.clear(); // Start fresh
3409 cUnit->regLocation = NULL;
3410 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3411 i++) {
3412 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3413 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3414 }
3415 cUnit->coreSpillMask = 0;
3416 cUnit->numCoreSpills = 0;
3417 cUnit->fpSpillMask = 0;
3418 cUnit->numFPSpills = 0;
3419 cUnit->coreVmapTable.clear();
3420 cUnit->fpVmapTable.clear();
buzbeead8f15e2012-06-18 14:49:45 -07003421
3422 /*
3423 * At this point, we've lost all knowledge of register promotion.
3424 * Rebuild that info from the MethodInfo intrinsic (if it
buzbeeca7a5e42012-08-20 11:12:18 -07003425 * exists - not required for correctness). Normally, this will
3426 * be the first instruction we encounter, so we won't have to iterate
3427 * through everything.
buzbeead8f15e2012-06-18 14:49:45 -07003428 */
buzbeeca7a5e42012-08-20 11:12:18 -07003429 for (llvm::inst_iterator i = llvm::inst_begin(func),
3430 e = llvm::inst_end(func); i != e; ++i) {
3431 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(&*i);
3432 if (callInst != NULL) {
3433 llvm::Function* callee = callInst->getCalledFunction();
3434 greenland::IntrinsicHelper::IntrinsicId id =
3435 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3436 if (id == greenland::IntrinsicHelper::MethodInfo) {
3437 if (cUnit->printMe) {
3438 LOG(INFO) << "Found MethodInfo";
3439 }
3440 llvm::MDNode* regInfoNode = callInst->getMetadata("RegInfo");
3441 if (regInfoNode != NULL) {
3442 llvm::ConstantInt* numInsValue =
3443 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(0));
3444 llvm::ConstantInt* numRegsValue =
3445 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(1));
3446 llvm::ConstantInt* numOutsValue =
3447 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(2));
3448 llvm::ConstantInt* numCompilerTempsValue =
3449 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(3));
3450 llvm::ConstantInt* numSSARegsValue =
3451 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(4));
3452 if (cUnit->printMe) {
3453 LOG(INFO) << "RegInfo - Ins:" << numInsValue->getZExtValue()
3454 << ", Regs:" << numRegsValue->getZExtValue()
3455 << ", Outs:" << numOutsValue->getZExtValue()
3456 << ", CTemps:" << numCompilerTempsValue->getZExtValue()
3457 << ", SSARegs:" << numSSARegsValue->getZExtValue();
3458 }
3459 }
3460 llvm::MDNode* pmapInfoNode = callInst->getMetadata("PromotionMap");
3461 if (pmapInfoNode != NULL) {
3462 int elems = pmapInfoNode->getNumOperands();
3463 if (cUnit->printMe) {
3464 LOG(INFO) << "PMap size: " << elems;
3465 }
3466 for (int i = 0; i < elems; i++) {
3467 llvm::ConstantInt* rawMapData =
3468 static_cast<llvm::ConstantInt*>(pmapInfoNode->getOperand(i));
3469 uint32_t mapData = rawMapData->getZExtValue();
3470 PromotionMap* p = &cUnit->promotionMap[i];
3471 p->firstInPair = (mapData >> 24) & 0xff;
3472 p->fpReg = (mapData >> 16) & 0xff;
3473 p->coreReg = (mapData >> 8) & 0xff;
3474 p->fpLocation = static_cast<RegLocationType>((mapData >> 4) & 0xf);
3475 if (p->fpLocation == kLocPhysReg) {
3476 oatRecordFpPromotion(cUnit, p->fpReg, i);
3477 }
3478 p->coreLocation = static_cast<RegLocationType>(mapData & 0xf);
3479 if (p->coreLocation == kLocPhysReg) {
3480 oatRecordCorePromotion(cUnit, p->coreReg, i);
3481 }
3482 }
3483 if (cUnit->printMe) {
3484 oatDumpPromotionMap(cUnit);
3485 }
3486 }
3487 break;
3488 }
3489 }
3490 }
3491 oatAdjustSpillMask(cUnit);
3492 cUnit->frameSize = oatComputeFrameSize(cUnit);
buzbeead8f15e2012-06-18 14:49:45 -07003493
3494 // Create RegLocations for arguments
3495 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3496 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3497 for (; it != it_end; ++it) {
3498 llvm::Value* val = it;
3499 createLocFromValue(cUnit, val);
3500 }
3501 // Create RegLocations for all non-argument defintions
3502 for (llvm::inst_iterator i = llvm::inst_begin(func),
3503 e = llvm::inst_end(func); i != e; ++i) {
3504 llvm::Value* val = &*i;
3505 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3506 createLocFromValue(cUnit, val);
3507 }
3508 }
3509
buzbee2cfc6392012-05-07 14:51:40 -07003510 // Walk the blocks, generating code.
3511 for (llvm::Function::iterator i = cUnit->func->begin(),
3512 e = cUnit->func->end(); i != e; ++i) {
3513 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3514 }
3515
3516 handleSuspendLaunchpads(cUnit);
3517
3518 handleThrowLaunchpads(cUnit);
3519
3520 handleIntrinsicLaunchpads(cUnit);
3521
3522 freeIR(cUnit);
3523}
3524
3525
3526} // namespace art
3527
3528#endif // ART_USE_QUICK_COMPILER