blob: f3ebf09ab14be751a0a586f86b9bdea1763ba2fa [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
buzbee2cfc6392012-05-07 14:51:40 -070017#include "object_utils.h"
18
19#include <llvm/Support/ToolOutputFile.h>
20#include <llvm/Bitcode/ReaderWriter.h>
21#include <llvm/Analysis/Verifier.h>
22#include <llvm/Metadata.h>
23#include <llvm/ADT/DepthFirstIterator.h>
24#include <llvm/Instruction.h>
25#include <llvm/Type.h>
26#include <llvm/Instructions.h>
27#include <llvm/Support/Casting.h>
buzbeead8f15e2012-06-18 14:49:45 -070028#include <llvm/Support/InstIterator.h>
buzbee2cfc6392012-05-07 14:51:40 -070029
buzbee8320f382012-09-11 16:29:42 -070030static const char* kLabelFormat = "%c0x%x_%d";
buzbee951c0a12012-10-03 16:31:39 -070031static const char kInvalidBlock = 0xff;
buzbee8320f382012-09-11 16:29:42 -070032static const char kNormalBlock = 'L';
33static const char kCatchBlock = 'C';
buzbee2cfc6392012-05-07 14:51:40 -070034
35namespace art {
36extern const RegLocation badLoc;
buzbeeb03f4872012-06-11 15:22:11 -070037RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val);
buzbee2cfc6392012-05-07 14:51:40 -070038
39llvm::BasicBlock* getLLVMBlock(CompilationUnit* cUnit, int id)
40{
41 return cUnit->idToBlockMap.Get(id);
42}
43
44llvm::Value* getLLVMValue(CompilationUnit* cUnit, int sReg)
45{
46 return (llvm::Value*)oatGrowableListGetElement(&cUnit->llvmValues, sReg);
47}
48
49// Replace the placeholder value with the real definition
50void defineValue(CompilationUnit* cUnit, llvm::Value* val, int sReg)
51{
52 llvm::Value* placeholder = getLLVMValue(cUnit, sReg);
buzbee9a2487f2012-07-26 14:01:13 -070053 if (placeholder == NULL) {
54 // This can happen on instruction rewrite on verification failure
Bill Buzbeec9f40dd2012-08-15 11:35:25 -070055 LOG(WARNING) << "Null placeholder";
buzbee9a2487f2012-07-26 14:01:13 -070056 return;
57 }
buzbee2cfc6392012-05-07 14:51:40 -070058 placeholder->replaceAllUsesWith(val);
59 val->takeName(placeholder);
60 cUnit->llvmValues.elemList[sReg] = (intptr_t)val;
buzbee4be777b2012-07-12 14:38:18 -070061 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(placeholder);
62 DCHECK(inst != NULL);
63 inst->eraseFromParent();
buzbee2cfc6392012-05-07 14:51:40 -070064}
65
66llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
67{
68 llvm::Type* res = NULL;
69 if (loc.wide) {
70 if (loc.fp)
buzbee4f1181f2012-06-22 13:52:12 -070071 res = cUnit->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070072 else
buzbee4f1181f2012-06-22 13:52:12 -070073 res = cUnit->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070074 } else {
75 if (loc.fp) {
buzbee4f1181f2012-06-22 13:52:12 -070076 res = cUnit->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -070077 } else {
78 if (loc.ref)
79 res = cUnit->irb->GetJObjectTy();
80 else
buzbee4f1181f2012-06-22 13:52:12 -070081 res = cUnit->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -070082 }
83 }
84 return res;
85}
86
buzbeead8f15e2012-06-18 14:49:45 -070087/* Create an in-memory RegLocation from an llvm Value. */
88void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val)
89{
90 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
91 std::string s(val->getName().str());
92 const char* valName = s.c_str();
buzbeead8f15e2012-06-18 14:49:45 -070093 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
94 DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName;
95 int baseSReg = INVALID_SREG;
96 int subscript = -1;
97 sscanf(valName, "v%d_%d", &baseSReg, &subscript);
98 if ((baseSReg == INVALID_SREG) && (!strcmp(valName, "method"))) {
99 baseSReg = SSA_METHOD_BASEREG;
100 subscript = 0;
101 }
buzbeead8f15e2012-06-18 14:49:45 -0700102 DCHECK_NE(baseSReg, INVALID_SREG);
103 DCHECK_NE(subscript, -1);
104 // TODO: redo during C++'ification
105 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
106 INVALID_REG, INVALID_SREG, INVALID_SREG};
107 llvm::Type* ty = val->getType();
108 loc.wide = ((ty == cUnit->irb->getInt64Ty()) ||
109 (ty == cUnit->irb->getDoubleTy()));
110 loc.defined = true;
buzbeeca7a5e42012-08-20 11:12:18 -0700111 loc.home = false; // May change during promotion
buzbeead8f15e2012-06-18 14:49:45 -0700112 loc.sRegLow = baseSReg;
113 loc.origSReg = cUnit->locMap.size();
buzbeeca7a5e42012-08-20 11:12:18 -0700114 PromotionMap pMap = cUnit->promotionMap[baseSReg];
115 if (ty == cUnit->irb->getFloatTy()) {
116 loc.fp = true;
117 if (pMap.fpLocation == kLocPhysReg) {
118 loc.lowReg = pMap.fpReg;
119 loc.location = kLocPhysReg;
120 loc.home = true;
121 }
122 } else if (ty == cUnit->irb->getDoubleTy()) {
123 loc.fp = true;
124 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
125 if ((pMap.fpLocation == kLocPhysReg) &&
126 (pMapHigh.fpLocation == kLocPhysReg) &&
127 ((pMap.fpReg & 0x1) == 0) &&
128 (pMap.fpReg + 1 == pMapHigh.fpReg)) {
129 loc.lowReg = pMap.fpReg;
130 loc.highReg = pMapHigh.fpReg;
131 loc.location = kLocPhysReg;
132 loc.home = true;
133 }
134 } else if (ty == cUnit->irb->GetJObjectTy()) {
135 loc.ref = true;
136 if (pMap.coreLocation == kLocPhysReg) {
137 loc.lowReg = pMap.coreReg;
138 loc.location = kLocPhysReg;
139 loc.home = true;
140 }
141 } else if (ty == cUnit->irb->getInt64Ty()) {
142 loc.core = true;
143 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
144 if ((pMap.coreLocation == kLocPhysReg) &&
145 (pMapHigh.coreLocation == kLocPhysReg)) {
146 loc.lowReg = pMap.coreReg;
147 loc.highReg = pMapHigh.coreReg;
148 loc.location = kLocPhysReg;
149 loc.home = true;
150 }
151 } else {
152 loc.core = true;
153 if (pMap.coreLocation == kLocPhysReg) {
154 loc.lowReg = pMap.coreReg;
155 loc.location = kLocPhysReg;
156 loc.home = true;
157 }
158 }
159
160 if (cUnit->printMe && loc.home) {
161 if (loc.wide) {
buzbee0967a252012-09-14 10:43:54 -0700162 LOG(INFO) << "Promoted wide " << s << " to regs " << static_cast<int>(loc.lowReg)
buzbeeca7a5e42012-08-20 11:12:18 -0700163 << "/" << loc.highReg;
164 } else {
buzbee0967a252012-09-14 10:43:54 -0700165 LOG(INFO) << "Promoted " << s << " to reg " << static_cast<int>(loc.lowReg);
buzbeeca7a5e42012-08-20 11:12:18 -0700166 }
167 }
buzbeead8f15e2012-06-18 14:49:45 -0700168 cUnit->locMap.Put(val, loc);
169}
buzbee2cfc6392012-05-07 14:51:40 -0700170void initIR(CompilationUnit* cUnit)
171{
buzbee4df2bbd2012-10-11 14:46:06 -0700172 LLVMInfo* llvmInfo = cUnit->llvm_info;
173 if (llvmInfo == NULL) {
174 CompilerTls* tls = cUnit->compiler->GetTls();
175 CHECK(tls != NULL);
176 llvmInfo = static_cast<LLVMInfo*>(tls->GetLLVMInfo());
177 if (llvmInfo == NULL) {
178 llvmInfo = new LLVMInfo();
179 tls->SetLLVMInfo(llvmInfo);
180 }
181 }
182 cUnit->context = llvmInfo->GetLLVMContext();
183 cUnit->module = llvmInfo->GetLLVMModule();
184 cUnit->intrinsic_helper = llvmInfo->GetIntrinsicHelper();
185 cUnit->irb = llvmInfo->GetIRBuilder();
buzbee2cfc6392012-05-07 14:51:40 -0700186}
187
188const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
189 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
190}
191
buzbeef58c12c2012-07-03 15:06:29 -0700192llvm::BasicBlock* findCaseTarget(CompilationUnit* cUnit, uint32_t vaddr)
193{
194 BasicBlock* bb = oatFindBlock(cUnit, vaddr);
195 DCHECK(bb != NULL);
196 return getLLVMBlock(cUnit, bb->id);
197}
198
199void convertPackedSwitch(CompilationUnit* cUnit, BasicBlock* bb,
200 int32_t tableOffset, RegLocation rlSrc)
201{
202 const Instruction::PackedSwitchPayload* payload =
203 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
204 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
205
206 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
207
208 llvm::SwitchInst* sw =
209 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
210 payload->case_count);
211
212 for (uint16_t i = 0; i < payload->case_count; ++i) {
213 llvm::BasicBlock* llvmBB =
214 findCaseTarget(cUnit, cUnit->currentDalvikOffset + payload->targets[i]);
215 sw->addCase(cUnit->irb->getInt32(payload->first_key + i), llvmBB);
216 }
217 llvm::MDNode* switchNode =
218 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
219 sw->setMetadata("SwitchTable", switchNode);
220 bb->taken = NULL;
221 bb->fallThrough = NULL;
222}
223
buzbeea1da8a52012-07-09 14:00:21 -0700224void convertSparseSwitch(CompilationUnit* cUnit, BasicBlock* bb,
225 int32_t tableOffset, RegLocation rlSrc)
226{
227 const Instruction::SparseSwitchPayload* payload =
228 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
229 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
230
231 const int32_t* keys = payload->GetKeys();
232 const int32_t* targets = payload->GetTargets();
233
234 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
235
236 llvm::SwitchInst* sw =
237 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
238 payload->case_count);
239
240 for (size_t i = 0; i < payload->case_count; ++i) {
241 llvm::BasicBlock* llvmBB =
242 findCaseTarget(cUnit, cUnit->currentDalvikOffset + targets[i]);
243 sw->addCase(cUnit->irb->getInt32(keys[i]), llvmBB);
244 }
245 llvm::MDNode* switchNode =
246 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
247 sw->setMetadata("SwitchTable", switchNode);
248 bb->taken = NULL;
249 bb->fallThrough = NULL;
250}
251
buzbee8fa0fda2012-06-27 15:44:52 -0700252void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
253 greenland::IntrinsicHelper::IntrinsicId id,
254 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700255{
buzbee8fa0fda2012-06-27 15:44:52 -0700256 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700257 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700258 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
259 defineValue(cUnit, res, rlDest.origSReg);
260}
261
262void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
263 greenland::IntrinsicHelper::IntrinsicId id,
264 RegLocation rlSrc)
265{
266 llvm::SmallVector<llvm::Value*, 2> args;
267 args.push_back(cUnit->irb->getInt32(fieldIndex));
268 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
269 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
270 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700271}
272
buzbee101305f2012-06-28 18:00:56 -0700273void convertFillArrayData(CompilationUnit* cUnit, int32_t offset,
274 RegLocation rlArray)
275{
276 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700277 id = greenland::IntrinsicHelper::HLFillArrayData;
buzbee101305f2012-06-28 18:00:56 -0700278 llvm::SmallVector<llvm::Value*, 2> args;
279 args.push_back(cUnit->irb->getInt32(offset));
280 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
281 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
282 cUnit->irb->CreateCall(intr, args);
283}
284
buzbee2cfc6392012-05-07 14:51:40 -0700285llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
286 RegLocation loc)
287{
288 greenland::IntrinsicHelper::IntrinsicId id;
289 if (loc.wide) {
290 if (loc.fp) {
291 id = greenland::IntrinsicHelper::ConstDouble;
292 } else {
293 id = greenland::IntrinsicHelper::ConstLong;
294 }
295 } else {
296 if (loc.fp) {
297 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700298 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700299 id = greenland::IntrinsicHelper::ConstObj;
300 } else {
301 id = greenland::IntrinsicHelper::ConstInt;
302 }
303 }
304 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
305 return cUnit->irb->CreateCall(intr, src);
306}
buzbeeb03f4872012-06-11 15:22:11 -0700307
308void emitPopShadowFrame(CompilationUnit* cUnit)
309{
310 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
311 greenland::IntrinsicHelper::PopShadowFrame);
312 cUnit->irb->CreateCall(intr);
313}
314
buzbee2cfc6392012-05-07 14:51:40 -0700315llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
316 RegLocation loc)
317{
318 greenland::IntrinsicHelper::IntrinsicId id;
319 if (loc.wide) {
320 if (loc.fp) {
321 id = greenland::IntrinsicHelper::CopyDouble;
322 } else {
323 id = greenland::IntrinsicHelper::CopyLong;
324 }
325 } else {
326 if (loc.fp) {
327 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700328 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700329 id = greenland::IntrinsicHelper::CopyObj;
330 } else {
331 id = greenland::IntrinsicHelper::CopyInt;
332 }
333 }
334 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
335 return cUnit->irb->CreateCall(intr, src);
336}
337
buzbee32412962012-06-26 16:27:56 -0700338void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
339{
340 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
341 greenland::IntrinsicHelper::GetException);
342 llvm::Value* res = cUnit->irb->CreateCall(func);
343 defineValue(cUnit, res, rlDest.origSReg);
344}
345
346void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
347{
348 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
349 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
TDYa127f71bf5a2012-07-29 20:09:52 -0700350 greenland::IntrinsicHelper::HLThrowException);
buzbee32412962012-06-26 16:27:56 -0700351 cUnit->irb->CreateCall(func, src);
buzbee32412962012-06-26 16:27:56 -0700352}
353
buzbee8fa0fda2012-06-27 15:44:52 -0700354void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
355 greenland::IntrinsicHelper::IntrinsicId id,
356 RegLocation rlSrc)
357{
358 llvm::SmallVector<llvm::Value*, 2> args;
359 args.push_back(cUnit->irb->getInt32(optFlags));
360 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
361 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
362 cUnit->irb->CreateCall(func, args);
363}
364
buzbee76592632012-06-29 15:18:35 -0700365void convertArrayLength(CompilationUnit* cUnit, int optFlags,
366 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700367{
368 llvm::SmallVector<llvm::Value*, 2> args;
369 args.push_back(cUnit->irb->getInt32(optFlags));
370 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
371 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700372 greenland::IntrinsicHelper::OptArrayLength);
buzbee76592632012-06-29 15:18:35 -0700373 llvm::Value* res = cUnit->irb->CreateCall(func, args);
374 defineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700375}
376
buzbee2cfc6392012-05-07 14:51:40 -0700377void emitSuspendCheck(CompilationUnit* cUnit)
378{
379 greenland::IntrinsicHelper::IntrinsicId id =
380 greenland::IntrinsicHelper::CheckSuspend;
381 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
382 cUnit->irb->CreateCall(intr);
383}
384
385llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
386 llvm::Value* src1, llvm::Value* src2)
387{
388 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700389 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700390 switch(cc) {
391 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
392 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
393 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
394 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
395 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
396 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
397 default: LOG(FATAL) << "Unexpected cc value " << cc;
398 }
399 return res;
400}
401
402void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
403 ConditionCode cc, RegLocation rlSrc1,
404 RegLocation rlSrc2)
405{
406 if (bb->taken->startOffset <= mir->offset) {
407 emitSuspendCheck(cUnit);
408 }
409 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
410 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
411 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
412 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
413 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
414 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700415 // Don't redo the fallthrough branch in the BB driver
416 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700417}
418
419void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
420 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
421{
422 if (bb->taken->startOffset <= mir->offset) {
423 emitSuspendCheck(cUnit);
424 }
425 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
426 llvm::Value* src2;
427 if (rlSrc1.ref) {
428 src2 = cUnit->irb->GetJNull();
429 } else {
430 src2 = cUnit->irb->getInt32(0);
431 }
432 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
buzbee2cfc6392012-05-07 14:51:40 -0700433 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
434 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700435 // Don't redo the fallthrough branch in the BB driver
436 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700437}
438
439llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
440 llvm::Value* src1, llvm::Value* src2)
441{
442 greenland::IntrinsicHelper::IntrinsicId id;
443 if (isLong) {
444 if (isDiv) {
445 id = greenland::IntrinsicHelper::DivLong;
446 } else {
447 id = greenland::IntrinsicHelper::RemLong;
448 }
Logan Chien554e6072012-07-23 20:00:01 -0700449 } else {
450 if (isDiv) {
buzbee2cfc6392012-05-07 14:51:40 -0700451 id = greenland::IntrinsicHelper::DivInt;
452 } else {
453 id = greenland::IntrinsicHelper::RemInt;
Logan Chien554e6072012-07-23 20:00:01 -0700454 }
buzbee2cfc6392012-05-07 14:51:40 -0700455 }
456 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
457 llvm::SmallVector<llvm::Value*, 2>args;
458 args.push_back(src1);
459 args.push_back(src2);
460 return cUnit->irb->CreateCall(intr, args);
461}
462
463llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
464 llvm::Value* src1, llvm::Value* src2)
465{
466 llvm::Value* res = NULL;
467 switch(op) {
468 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
469 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700470 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700471 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
472 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
473 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
474 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
475 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
476 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700477 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
478 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
479 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700480 default:
481 LOG(FATAL) << "Invalid op " << op;
482 }
483 return res;
484}
485
486void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
487 RegLocation rlSrc1, RegLocation rlSrc2)
488{
489 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
490 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
491 llvm::Value* res = NULL;
492 switch(op) {
493 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
494 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
495 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
496 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
497 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
498 default:
499 LOG(FATAL) << "Invalid op " << op;
500 }
501 defineValue(cUnit, res, rlDest.origSReg);
502}
503
buzbee2a83e8f2012-07-13 16:42:30 -0700504void convertShift(CompilationUnit* cUnit,
505 greenland::IntrinsicHelper::IntrinsicId id,
506 RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2)
buzbee4f1181f2012-06-22 13:52:12 -0700507{
buzbee2a83e8f2012-07-13 16:42:30 -0700508 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
509 llvm::SmallVector<llvm::Value*, 2>args;
510 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
511 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
512 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
513 defineValue(cUnit, res, rlDest.origSReg);
514}
515
516void convertShiftLit(CompilationUnit* cUnit,
517 greenland::IntrinsicHelper::IntrinsicId id,
518 RegLocation rlDest, RegLocation rlSrc, int shiftAmount)
519{
520 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
521 llvm::SmallVector<llvm::Value*, 2>args;
522 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
523 args.push_back(cUnit->irb->getInt32(shiftAmount));
524 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700525 defineValue(cUnit, res, rlDest.origSReg);
526}
527
buzbee2cfc6392012-05-07 14:51:40 -0700528void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
529 RegLocation rlSrc1, RegLocation rlSrc2)
530{
531 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
532 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700533 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700534 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
535 defineValue(cUnit, res, rlDest.origSReg);
536}
537
buzbeeb03f4872012-06-11 15:22:11 -0700538void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
539{
540 int index = -1;
541 DCHECK(newVal != NULL);
542 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
543 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
544 if (cUnit->shadowMap[i] == vReg) {
545 index = i;
546 break;
547 }
548 }
TDYa127347166a2012-08-23 12:23:44 -0700549 if (index == -1) {
550 return;
551 }
buzbee6459e7c2012-10-02 14:42:41 -0700552 llvm::Type* ty = newVal->getType();
buzbeeb03f4872012-06-11 15:22:11 -0700553 greenland::IntrinsicHelper::IntrinsicId id =
554 greenland::IntrinsicHelper::SetShadowFrameEntry;
555 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
556 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
buzbee6459e7c2012-10-02 14:42:41 -0700557 // If newVal is a Null pointer, we'll see it here as a const int. Replace
558 if (!ty->isPointerTy()) {
559 // TODO: assert newVal created w/ dex_lang_const_int(0) or dex_lang_const_float(0)
560 newVal = cUnit->irb->GetJNull();
561 }
buzbeeb03f4872012-06-11 15:22:11 -0700562 llvm::Value* args[] = { newVal, tableSlot };
563 cUnit->irb->CreateCall(func, args);
564}
565
buzbee2cfc6392012-05-07 14:51:40 -0700566void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
567 RegLocation rlSrc1, int32_t imm)
568{
569 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
570 llvm::Value* src2 = cUnit->irb->getInt32(imm);
571 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
572 defineValue(cUnit, res, rlDest.origSReg);
573}
574
buzbee101305f2012-06-28 18:00:56 -0700575/*
576 * Process arguments for invoke. Note: this code is also used to
577 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
578 * The requirements are similar.
579 */
buzbee6969d502012-06-15 16:40:31 -0700580void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700581 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700582{
583 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
584 llvm::SmallVector<llvm::Value*, 10> args;
585 // Insert the invokeType
586 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
587 // Insert the method_idx
588 args.push_back(cUnit->irb->getInt32(info->index));
589 // Insert the optimization flags
590 args.push_back(cUnit->irb->getInt32(info->optFlags));
591 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700592 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700593 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
594 args.push_back(val);
595 i += info->args[i].wide ? 2 : 1;
596 }
597 /*
598 * Choose the invoke return type based on actual usage. Note: may
599 * be different than shorty. For example, if a function return value
600 * is not used, we'll treat this as a void invoke.
601 */
602 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700603 if (isFilledNewArray) {
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700604 id = greenland::IntrinsicHelper::HLFilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700605 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700606 id = greenland::IntrinsicHelper::HLInvokeVoid;
607 } else {
608 if (info->result.wide) {
609 if (info->result.fp) {
610 id = greenland::IntrinsicHelper::HLInvokeDouble;
611 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700612 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700613 }
614 } else if (info->result.ref) {
615 id = greenland::IntrinsicHelper::HLInvokeObj;
616 } else if (info->result.fp) {
617 id = greenland::IntrinsicHelper::HLInvokeFloat;
618 } else {
619 id = greenland::IntrinsicHelper::HLInvokeInt;
620 }
621 }
622 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
623 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
624 if (info->result.location != kLocInvalid) {
625 defineValue(cUnit, res, info->result.origSReg);
TDYa127890ea892012-08-22 10:49:42 -0700626 if (info->result.ref) {
627 setShadowFrameEntry(cUnit, (llvm::Value*)
628 cUnit->llvmValues.elemList[info->result.origSReg]);
629 }
buzbee6969d502012-06-15 16:40:31 -0700630 }
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;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700647 id = greenland::IntrinsicHelper::HLCheckCast;
buzbee101305f2012-06-28 18:00:56 -0700648 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
TDYa1274ec8ccd2012-08-11 07:04:57 -0700816void convertFPToInt(CompilationUnit* cUnit,
817 greenland::IntrinsicHelper::IntrinsicId id,
818 RegLocation rlDest,
buzbee76592632012-06-29 15:18:35 -0700819 RegLocation rlSrc)
820{
TDYa1274ec8ccd2012-08-11 07:04:57 -0700821 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
822 llvm::Value* res = cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
buzbee76592632012-06-29 15:18:35 -0700823 defineValue(cUnit, res, rlDest.origSReg);
824}
825
826
827void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
828 RegLocation rlSrc)
829{
830 llvm::Value* res =
831 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
832 defineValue(cUnit, res, rlDest.origSReg);
833}
834
835void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
836 RegLocation rlSrc)
837{
838 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
839 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700840 defineValue(cUnit, res, rlDest.origSReg);
841}
842
buzbee2cfc6392012-05-07 14:51:40 -0700843/*
844 * Target-independent code generation. Use only high-level
845 * load/store utilities here, or target-dependent genXX() handlers
846 * when necessary.
847 */
848bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
849 llvm::BasicBlock* llvmBB, LIR* labelList)
850{
851 bool res = false; // Assume success
852 RegLocation rlSrc[3];
853 RegLocation rlDest = badLoc;
buzbee2cfc6392012-05-07 14:51:40 -0700854 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee6969d502012-06-15 16:40:31 -0700855 uint32_t vB = mir->dalvikInsn.vB;
856 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700857 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700858
buzbeeb03f4872012-06-11 15:22:11 -0700859 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700860
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700861 if (cUnit->printMe) {
862 if ((int)opcode < kMirOpFirst) {
863 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x"
864 << std::hex << (int)opcode;
865 } else {
866 LOG(INFO) << ".. opcode 0x" << std::hex << (int)opcode;
867 }
868 }
869
buzbee2cfc6392012-05-07 14:51:40 -0700870 /* Prep Src and Dest locations */
871 int nextSreg = 0;
872 int nextLoc = 0;
873 int attrs = oatDataFlowAttributes[opcode];
874 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
875 if (attrs & DF_UA) {
876 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700877 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700878 nextSreg+= 2;
879 } else {
880 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
881 nextSreg++;
882 }
883 }
884 if (attrs & DF_UB) {
885 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700886 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700887 nextSreg+= 2;
888 } else {
889 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
890 nextSreg++;
891 }
892 }
893 if (attrs & DF_UC) {
894 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700895 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700896 } else {
897 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
898 }
899 }
900 if (attrs & DF_DA) {
901 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700902 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700903 } else {
buzbee15bf9802012-06-12 17:49:27 -0700904 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700905 if (rlDest.ref) {
906 objectDefinition = true;
907 }
buzbee2cfc6392012-05-07 14:51:40 -0700908 }
909 }
910
911 switch (opcode) {
912 case Instruction::NOP:
913 break;
914
915 case Instruction::MOVE:
916 case Instruction::MOVE_OBJECT:
917 case Instruction::MOVE_16:
918 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700919 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700920 case Instruction::MOVE_FROM16:
921 case Instruction::MOVE_WIDE:
922 case Instruction::MOVE_WIDE_16:
923 case Instruction::MOVE_WIDE_FROM16: {
924 /*
925 * Moves/copies are meaningless in pure SSA register form,
926 * but we need to preserve them for the conversion back into
927 * MIR (at least until we stop using the Dalvik register maps).
928 * Insert a dummy intrinsic copy call, which will be recognized
929 * by the quick path and removed by the portable path.
930 */
931 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
932 llvm::Value* res = emitCopy(cUnit, src, rlDest);
933 defineValue(cUnit, res, rlDest.origSReg);
934 }
935 break;
936
937 case Instruction::CONST:
938 case Instruction::CONST_4:
939 case Instruction::CONST_16: {
TDYa127347166a2012-08-23 12:23:44 -0700940 if (vB == 0) {
941 objectDefinition = true;
942 }
buzbee6969d502012-06-15 16:40:31 -0700943 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700944 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
945 defineValue(cUnit, res, rlDest.origSReg);
946 }
947 break;
948
949 case Instruction::CONST_WIDE_16:
950 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700951 // Sign extend to 64 bits
952 int64_t imm = static_cast<int32_t>(vB);
953 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700954 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
955 defineValue(cUnit, res, rlDest.origSReg);
956 }
957 break;
958
959 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700960 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700961 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
962 defineValue(cUnit, res, rlDest.origSReg);
963 }
964 break;
965
966 case Instruction::CONST_WIDE: {
967 llvm::Constant* immValue =
968 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
969 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
970 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700971 }
972 break;
buzbee2cfc6392012-05-07 14:51:40 -0700973 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700974 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700975 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
976 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
977 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700978 }
979 break;
980
buzbee8fa0fda2012-06-27 15:44:52 -0700981 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700982 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700983 rlSrc[0]);
984 break;
985 case Instruction::SPUT:
986 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700987 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700988 rlSrc[0]);
989 } else {
buzbee76592632012-06-29 15:18:35 -0700990 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700991 }
992 break;
993 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700994 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700995 rlSrc[0]);
996 break;
997 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700998 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700999 break;
1000 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -07001001 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001002 break;
1003 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -07001004 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001005 break;
1006 case Instruction::SPUT_WIDE:
1007 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -07001008 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -07001009 rlSrc[0]);
1010 } else {
buzbee76592632012-06-29 15:18:35 -07001011 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -07001012 rlSrc[0]);
1013 }
1014 break;
1015
1016 case Instruction::SGET_OBJECT:
1017 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
1018 break;
1019 case Instruction::SGET:
1020 if (rlDest.fp) {
1021 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
1022 } else {
1023 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
1024 }
1025 break;
1026 case Instruction::SGET_BOOLEAN:
1027 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
1028 break;
1029 case Instruction::SGET_BYTE:
1030 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
1031 break;
1032 case Instruction::SGET_CHAR:
1033 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
1034 break;
1035 case Instruction::SGET_SHORT:
1036 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
1037 break;
1038 case Instruction::SGET_WIDE:
1039 if (rlDest.fp) {
1040 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
1041 rlDest);
1042 } else {
1043 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001044 }
1045 break;
buzbee2cfc6392012-05-07 14:51:40 -07001046
1047 case Instruction::RETURN_WIDE:
1048 case Instruction::RETURN:
1049 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -07001050 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001051 emitSuspendCheck(cUnit);
1052 }
buzbeeb03f4872012-06-11 15:22:11 -07001053 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001054 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
1055 bb->hasReturn = true;
1056 }
1057 break;
1058
1059 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -07001060 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001061 emitSuspendCheck(cUnit);
1062 }
buzbeeb03f4872012-06-11 15:22:11 -07001063 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001064 cUnit->irb->CreateRetVoid();
1065 bb->hasReturn = true;
1066 }
1067 break;
1068
1069 case Instruction::IF_EQ:
1070 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1071 break;
1072 case Instruction::IF_NE:
1073 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1074 break;
1075 case Instruction::IF_LT:
1076 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1077 break;
1078 case Instruction::IF_GE:
1079 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1080 break;
1081 case Instruction::IF_GT:
1082 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1083 break;
1084 case Instruction::IF_LE:
1085 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1086 break;
1087 case Instruction::IF_EQZ:
1088 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1089 break;
1090 case Instruction::IF_NEZ:
1091 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1092 break;
1093 case Instruction::IF_LTZ:
1094 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1095 break;
1096 case Instruction::IF_GEZ:
1097 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1098 break;
1099 case Instruction::IF_GTZ:
1100 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1101 break;
1102 case Instruction::IF_LEZ:
1103 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1104 break;
1105
1106 case Instruction::GOTO:
1107 case Instruction::GOTO_16:
1108 case Instruction::GOTO_32: {
1109 if (bb->taken->startOffset <= bb->startOffset) {
1110 emitSuspendCheck(cUnit);
1111 }
1112 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1113 }
1114 break;
1115
1116 case Instruction::ADD_LONG:
1117 case Instruction::ADD_LONG_2ADDR:
1118 case Instruction::ADD_INT:
1119 case Instruction::ADD_INT_2ADDR:
1120 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1121 break;
1122 case Instruction::SUB_LONG:
1123 case Instruction::SUB_LONG_2ADDR:
1124 case Instruction::SUB_INT:
1125 case Instruction::SUB_INT_2ADDR:
1126 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1127 break;
1128 case Instruction::MUL_LONG:
1129 case Instruction::MUL_LONG_2ADDR:
1130 case Instruction::MUL_INT:
1131 case Instruction::MUL_INT_2ADDR:
1132 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1133 break;
1134 case Instruction::DIV_LONG:
1135 case Instruction::DIV_LONG_2ADDR:
1136 case Instruction::DIV_INT:
1137 case Instruction::DIV_INT_2ADDR:
1138 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1139 break;
1140 case Instruction::REM_LONG:
1141 case Instruction::REM_LONG_2ADDR:
1142 case Instruction::REM_INT:
1143 case Instruction::REM_INT_2ADDR:
1144 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1145 break;
1146 case Instruction::AND_LONG:
1147 case Instruction::AND_LONG_2ADDR:
1148 case Instruction::AND_INT:
1149 case Instruction::AND_INT_2ADDR:
1150 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1151 break;
1152 case Instruction::OR_LONG:
1153 case Instruction::OR_LONG_2ADDR:
1154 case Instruction::OR_INT:
1155 case Instruction::OR_INT_2ADDR:
1156 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1157 break;
1158 case Instruction::XOR_LONG:
1159 case Instruction::XOR_LONG_2ADDR:
1160 case Instruction::XOR_INT:
1161 case Instruction::XOR_INT_2ADDR:
1162 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1163 break;
1164 case Instruction::SHL_LONG:
1165 case Instruction::SHL_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001166 convertShift(cUnit, greenland::IntrinsicHelper::SHLLong,
1167 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001168 break;
buzbee2cfc6392012-05-07 14:51:40 -07001169 case Instruction::SHL_INT:
1170 case Instruction::SHL_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001171 convertShift(cUnit, greenland::IntrinsicHelper::SHLInt,
1172 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001173 break;
1174 case Instruction::SHR_LONG:
1175 case Instruction::SHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001176 convertShift(cUnit, greenland::IntrinsicHelper::SHRLong,
1177 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001178 break;
buzbee2cfc6392012-05-07 14:51:40 -07001179 case Instruction::SHR_INT:
1180 case Instruction::SHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001181 convertShift(cUnit, greenland::IntrinsicHelper::SHRInt,
1182 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001183 break;
1184 case Instruction::USHR_LONG:
1185 case Instruction::USHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001186 convertShift(cUnit, greenland::IntrinsicHelper::USHRLong,
1187 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001188 break;
buzbee2cfc6392012-05-07 14:51:40 -07001189 case Instruction::USHR_INT:
1190 case Instruction::USHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001191 convertShift(cUnit, greenland::IntrinsicHelper::USHRInt,
1192 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001193 break;
1194
1195 case Instruction::ADD_INT_LIT16:
1196 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001197 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001198 break;
1199 case Instruction::RSUB_INT:
1200 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001201 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001202 break;
1203 case Instruction::MUL_INT_LIT16:
1204 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001205 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001206 break;
1207 case Instruction::DIV_INT_LIT16:
1208 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001209 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001210 break;
1211 case Instruction::REM_INT_LIT16:
1212 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001213 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001214 break;
1215 case Instruction::AND_INT_LIT16:
1216 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001217 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001218 break;
1219 case Instruction::OR_INT_LIT16:
1220 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001221 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001222 break;
1223 case Instruction::XOR_INT_LIT16:
1224 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001225 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001226 break;
1227 case Instruction::SHL_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001228 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHLInt,
1229 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001230 break;
1231 case Instruction::SHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001232 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHRInt,
1233 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001234 break;
1235 case Instruction::USHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001236 convertShiftLit(cUnit, greenland::IntrinsicHelper::USHRInt,
1237 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001238 break;
1239
1240 case Instruction::ADD_FLOAT:
1241 case Instruction::ADD_FLOAT_2ADDR:
1242 case Instruction::ADD_DOUBLE:
1243 case Instruction::ADD_DOUBLE_2ADDR:
1244 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1245 break;
1246
1247 case Instruction::SUB_FLOAT:
1248 case Instruction::SUB_FLOAT_2ADDR:
1249 case Instruction::SUB_DOUBLE:
1250 case Instruction::SUB_DOUBLE_2ADDR:
1251 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1252 break;
1253
1254 case Instruction::MUL_FLOAT:
1255 case Instruction::MUL_FLOAT_2ADDR:
1256 case Instruction::MUL_DOUBLE:
1257 case Instruction::MUL_DOUBLE_2ADDR:
1258 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1259 break;
1260
1261 case Instruction::DIV_FLOAT:
1262 case Instruction::DIV_FLOAT_2ADDR:
1263 case Instruction::DIV_DOUBLE:
1264 case Instruction::DIV_DOUBLE_2ADDR:
1265 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1266 break;
1267
1268 case Instruction::REM_FLOAT:
1269 case Instruction::REM_FLOAT_2ADDR:
1270 case Instruction::REM_DOUBLE:
1271 case Instruction::REM_DOUBLE_2ADDR:
1272 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1273 break;
1274
buzbee6969d502012-06-15 16:40:31 -07001275 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001276 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1277 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001278 break;
1279 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001280 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1281 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001282 break;
1283
1284 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001285 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1286 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001287 break;
1288 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001289 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1290 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001291 break;
1292
1293 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001294 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1295 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001296 break;
1297 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001298 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1299 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001300 break;
1301
1302 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001303 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1304 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001305 break;
1306 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001307 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1308 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001309 break;
1310
1311 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001312 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1313 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001314 break;
1315 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001316 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1317 false /* NewFilledArray */);
1318 break;
1319 case Instruction::FILLED_NEW_ARRAY:
1320 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1321 true /* NewFilledArray */);
1322 break;
1323 case Instruction::FILLED_NEW_ARRAY_RANGE:
1324 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1325 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001326 break;
1327
1328 case Instruction::CONST_STRING:
1329 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001330 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1331 rlDest);
1332 break;
1333
1334 case Instruction::CONST_CLASS:
1335 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1336 rlDest);
1337 break;
1338
1339 case Instruction::CHECK_CAST:
1340 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001341 break;
1342
buzbee4f1181f2012-06-22 13:52:12 -07001343 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001344 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001345 break;
1346
buzbee32412962012-06-26 16:27:56 -07001347 case Instruction::MOVE_EXCEPTION:
1348 convertMoveException(cUnit, rlDest);
1349 break;
1350
1351 case Instruction::THROW:
1352 convertThrow(cUnit, rlSrc[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001353 /*
1354 * If this throw is standalone, terminate.
1355 * If it might rethrow, force termination
1356 * of the following block.
1357 */
1358 if (bb->fallThrough == NULL) {
1359 cUnit->irb->CreateUnreachable();
1360 } else {
1361 bb->fallThrough->fallThrough = NULL;
1362 bb->fallThrough->taken = NULL;
1363 }
buzbee32412962012-06-26 16:27:56 -07001364 break;
1365
buzbee2cfc6392012-05-07 14:51:40 -07001366 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001367 case Instruction::MOVE_RESULT:
1368 case Instruction::MOVE_RESULT_OBJECT:
buzbee9a2487f2012-07-26 14:01:13 -07001369 /*
jeffhao9a4f0032012-08-30 16:17:40 -07001370 * All move_results should have been folded into the preceeding invoke.
buzbee9a2487f2012-07-26 14:01:13 -07001371 */
jeffhao9a4f0032012-08-30 16:17:40 -07001372 LOG(FATAL) << "Unexpected move_result";
buzbee2cfc6392012-05-07 14:51:40 -07001373 break;
1374
1375 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001376 convertMonitorEnterExit(cUnit, optFlags,
1377 greenland::IntrinsicHelper::MonitorEnter,
1378 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001379 break;
1380
1381 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001382 convertMonitorEnterExit(cUnit, optFlags,
1383 greenland::IntrinsicHelper::MonitorExit,
1384 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001385 break;
1386
1387 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001388 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001389 break;
1390
1391 case Instruction::NEW_ARRAY:
1392 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1393 break;
1394
1395 case Instruction::INSTANCE_OF:
1396 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1397 break;
1398
1399 case Instruction::AGET:
1400 if (rlDest.fp) {
1401 convertAget(cUnit, optFlags,
1402 greenland::IntrinsicHelper::HLArrayGetFloat,
1403 rlDest, rlSrc[0], rlSrc[1]);
1404 } else {
1405 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1406 rlDest, rlSrc[0], rlSrc[1]);
1407 }
1408 break;
1409 case Instruction::AGET_OBJECT:
1410 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1411 rlDest, rlSrc[0], rlSrc[1]);
1412 break;
1413 case Instruction::AGET_BOOLEAN:
1414 convertAget(cUnit, optFlags,
1415 greenland::IntrinsicHelper::HLArrayGetBoolean,
1416 rlDest, rlSrc[0], rlSrc[1]);
1417 break;
1418 case Instruction::AGET_BYTE:
1419 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1420 rlDest, rlSrc[0], rlSrc[1]);
1421 break;
1422 case Instruction::AGET_CHAR:
1423 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1424 rlDest, rlSrc[0], rlSrc[1]);
1425 break;
1426 case Instruction::AGET_SHORT:
1427 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1428 rlDest, rlSrc[0], rlSrc[1]);
1429 break;
1430 case Instruction::AGET_WIDE:
1431 if (rlDest.fp) {
1432 convertAget(cUnit, optFlags,
1433 greenland::IntrinsicHelper::HLArrayGetDouble,
1434 rlDest, rlSrc[0], rlSrc[1]);
1435 } else {
1436 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1437 rlDest, rlSrc[0], rlSrc[1]);
1438 }
1439 break;
1440
1441 case Instruction::APUT:
1442 if (rlSrc[0].fp) {
1443 convertAput(cUnit, optFlags,
1444 greenland::IntrinsicHelper::HLArrayPutFloat,
1445 rlSrc[0], rlSrc[1], rlSrc[2]);
1446 } else {
1447 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1448 rlSrc[0], rlSrc[1], rlSrc[2]);
1449 }
1450 break;
1451 case Instruction::APUT_OBJECT:
1452 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1453 rlSrc[0], rlSrc[1], rlSrc[2]);
1454 break;
1455 case Instruction::APUT_BOOLEAN:
1456 convertAput(cUnit, optFlags,
1457 greenland::IntrinsicHelper::HLArrayPutBoolean,
1458 rlSrc[0], rlSrc[1], rlSrc[2]);
1459 break;
1460 case Instruction::APUT_BYTE:
1461 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1462 rlSrc[0], rlSrc[1], rlSrc[2]);
1463 break;
1464 case Instruction::APUT_CHAR:
1465 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1466 rlSrc[0], rlSrc[1], rlSrc[2]);
1467 break;
1468 case Instruction::APUT_SHORT:
1469 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1470 rlSrc[0], rlSrc[1], rlSrc[2]);
1471 break;
1472 case Instruction::APUT_WIDE:
1473 if (rlSrc[0].fp) {
1474 convertAput(cUnit, optFlags,
1475 greenland::IntrinsicHelper::HLArrayPutDouble,
1476 rlSrc[0], rlSrc[1], rlSrc[2]);
1477 } else {
1478 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1479 rlSrc[0], rlSrc[1], rlSrc[2]);
1480 }
1481 break;
1482
buzbee101305f2012-06-28 18:00:56 -07001483 case Instruction::IGET:
1484 if (rlDest.fp) {
1485 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001486 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001487 } else {
1488 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001489 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001490 }
buzbee2cfc6392012-05-07 14:51:40 -07001491 break;
buzbee101305f2012-06-28 18:00:56 -07001492 case Instruction::IGET_OBJECT:
1493 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001494 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001495 break;
1496 case Instruction::IGET_BOOLEAN:
1497 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001498 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001499 break;
1500 case Instruction::IGET_BYTE:
1501 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001502 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001503 break;
1504 case Instruction::IGET_CHAR:
1505 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001506 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001507 break;
1508 case Instruction::IGET_SHORT:
1509 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001510 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001511 break;
1512 case Instruction::IGET_WIDE:
1513 if (rlDest.fp) {
1514 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001515 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001516 } else {
1517 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001518 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001519 }
1520 break;
1521 case Instruction::IPUT:
buzbee85eee022012-07-16 22:12:38 -07001522 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001523 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1524 rlSrc[0], rlSrc[1], vC);
1525 } else {
1526 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1527 rlSrc[0], rlSrc[1], vC);
1528 }
1529 break;
1530 case Instruction::IPUT_OBJECT:
1531 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1532 rlSrc[0], rlSrc[1], vC);
1533 break;
1534 case Instruction::IPUT_BOOLEAN:
1535 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1536 rlSrc[0], rlSrc[1], vC);
1537 break;
1538 case Instruction::IPUT_BYTE:
1539 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1540 rlSrc[0], rlSrc[1], vC);
1541 break;
1542 case Instruction::IPUT_CHAR:
1543 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1544 rlSrc[0], rlSrc[1], vC);
1545 break;
1546 case Instruction::IPUT_SHORT:
1547 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1548 rlSrc[0], rlSrc[1], vC);
1549 break;
1550 case Instruction::IPUT_WIDE:
buzbee85eee022012-07-16 22:12:38 -07001551 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001552 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1553 rlSrc[0], rlSrc[1], vC);
1554 } else {
1555 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1556 rlSrc[0], rlSrc[1], vC);
1557 }
buzbee2cfc6392012-05-07 14:51:40 -07001558 break;
1559
1560 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001561 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001562 break;
1563
buzbee76592632012-06-29 15:18:35 -07001564 case Instruction::LONG_TO_INT:
1565 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1566 break;
1567
buzbee101305f2012-06-28 18:00:56 -07001568 case Instruction::INT_TO_LONG:
1569 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001570 break;
1571
buzbee101305f2012-06-28 18:00:56 -07001572 case Instruction::INT_TO_CHAR:
1573 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1574 greenland::IntrinsicHelper::IntToChar);
1575 break;
1576 case Instruction::INT_TO_BYTE:
1577 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1578 greenland::IntrinsicHelper::IntToByte);
1579 break;
1580 case Instruction::INT_TO_SHORT:
1581 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1582 greenland::IntrinsicHelper::IntToShort);
1583 break;
1584
buzbee76592632012-06-29 15:18:35 -07001585 case Instruction::INT_TO_FLOAT:
1586 case Instruction::LONG_TO_FLOAT:
1587 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001588 break;
1589
buzbee76592632012-06-29 15:18:35 -07001590 case Instruction::INT_TO_DOUBLE:
1591 case Instruction::LONG_TO_DOUBLE:
1592 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001593 break;
1594
buzbee76592632012-06-29 15:18:35 -07001595 case Instruction::FLOAT_TO_DOUBLE:
1596 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001597 break;
1598
buzbee76592632012-06-29 15:18:35 -07001599 case Instruction::DOUBLE_TO_FLOAT:
1600 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001601 break;
1602
1603 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001604 case Instruction::NEG_INT:
1605 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001606 break;
1607
1608 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001609 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001610 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001611 break;
1612
buzbee76592632012-06-29 15:18:35 -07001613 case Instruction::NOT_LONG:
1614 case Instruction::NOT_INT:
1615 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001616 break;
1617
buzbee2cfc6392012-05-07 14:51:40 -07001618 case Instruction::FLOAT_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001619 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2I, rlDest, rlSrc[0]);
1620 break;
1621
buzbee2cfc6392012-05-07 14:51:40 -07001622 case Instruction::DOUBLE_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001623 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2I, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001624 break;
1625
buzbee76592632012-06-29 15:18:35 -07001626 case Instruction::FLOAT_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001627 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2L, rlDest, rlSrc[0]);
1628 break;
1629
buzbee76592632012-06-29 15:18:35 -07001630 case Instruction::DOUBLE_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001631 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2L, rlDest, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001632 break;
1633
1634 case Instruction::CMPL_FLOAT:
1635 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1636 rlDest, rlSrc[0], rlSrc[1]);
1637 break;
1638 case Instruction::CMPG_FLOAT:
1639 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1640 rlDest, rlSrc[0], rlSrc[1]);
1641 break;
1642 case Instruction::CMPL_DOUBLE:
1643 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1644 rlDest, rlSrc[0], rlSrc[1]);
1645 break;
1646 case Instruction::CMPG_DOUBLE:
1647 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1648 rlDest, rlSrc[0], rlSrc[1]);
1649 break;
1650 case Instruction::CMP_LONG:
1651 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1652 rlDest, rlSrc[0], rlSrc[1]);
1653 break;
1654
buzbee76592632012-06-29 15:18:35 -07001655 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001656 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001657 break;
1658
1659 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001660 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001661 break;
buzbee2cfc6392012-05-07 14:51:40 -07001662
1663 default:
buzbee32412962012-06-26 16:27:56 -07001664 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001665 res = true;
1666 }
buzbeeb03f4872012-06-11 15:22:11 -07001667 if (objectDefinition) {
1668 setShadowFrameEntry(cUnit, (llvm::Value*)
1669 cUnit->llvmValues.elemList[rlDest.origSReg]);
1670 }
buzbee2cfc6392012-05-07 14:51:40 -07001671 return res;
1672}
1673
1674/* Extended MIR instructions like PHI */
1675void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1676 llvm::BasicBlock* llvmBB)
1677{
1678
1679 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1680 case kMirOpPhi: {
buzbee2cfc6392012-05-07 14:51:40 -07001681 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001682 /*
1683 * The Art compiler's Phi nodes only handle 32-bit operands,
1684 * representing wide values using a matched set of Phi nodes
1685 * for the lower and upper halves. In the llvm world, we only
1686 * want a single Phi for wides. Here we will simply discard
1687 * the Phi node representing the high word.
1688 */
1689 if (rlDest.highWord) {
1690 return; // No Phi node - handled via low word
1691 }
1692 int* incoming = (int*)mir->dalvikInsn.vB;
buzbee2cfc6392012-05-07 14:51:40 -07001693 llvm::Type* phiType =
1694 llvmTypeFromLocRec(cUnit, rlDest);
1695 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1696 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1697 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001698 // Don't check width here.
1699 loc = oatGetRawSrc(cUnit, mir, i);
1700 DCHECK_EQ(rlDest.wide, loc.wide);
1701 DCHECK_EQ(rlDest.wide & rlDest.highWord, loc.wide & loc.highWord);
1702 DCHECK_EQ(rlDest.fp, loc.fp);
1703 DCHECK_EQ(rlDest.core, loc.core);
1704 DCHECK_EQ(rlDest.ref, loc.ref);
buzbeed1643e42012-09-05 14:06:51 -07001705 SafeMap<unsigned int, unsigned int>::iterator it;
1706 it = cUnit->blockIdMap.find(incoming[i]);
1707 DCHECK(it != cUnit->blockIdMap.end());
buzbee2cfc6392012-05-07 14:51:40 -07001708 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
buzbeed1643e42012-09-05 14:06:51 -07001709 getLLVMBlock(cUnit, it->second));
buzbee2cfc6392012-05-07 14:51:40 -07001710 }
1711 defineValue(cUnit, phi, rlDest.origSReg);
1712 break;
1713 }
1714 case kMirOpCopy: {
1715 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1716 break;
1717 }
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001718 case kMirOpNop:
1719 if ((mir == bb->lastMIRInsn) && (bb->taken == NULL) &&
1720 (bb->fallThrough == NULL)) {
1721 cUnit->irb->CreateUnreachable();
1722 }
1723 break;
1724
buzbeeb046e162012-10-30 15:48:42 -07001725 // TODO: need GBC intrinsic to take advantage of fused operations
buzbee2cfc6392012-05-07 14:51:40 -07001726 case kMirOpFusedCmplFloat:
buzbeeb046e162012-10-30 15:48:42 -07001727 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpFloat unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001728 break;
1729 case kMirOpFusedCmpgFloat:
buzbeeb046e162012-10-30 15:48:42 -07001730 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmgFloat unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001731 break;
1732 case kMirOpFusedCmplDouble:
buzbeeb046e162012-10-30 15:48:42 -07001733 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmplDouble unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001734 break;
1735 case kMirOpFusedCmpgDouble:
buzbeeb046e162012-10-30 15:48:42 -07001736 UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpgDouble unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001737 break;
1738 case kMirOpFusedCmpLong:
buzbeeb046e162012-10-30 15:48:42 -07001739 UNIMPLEMENTED(FATAL) << "kMirOpLongCmpBranch unsupported";
buzbee2cfc6392012-05-07 14:51:40 -07001740 break;
buzbee2cfc6392012-05-07 14:51:40 -07001741 default:
1742 break;
1743 }
1744}
1745
1746void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1747{
1748 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001749 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001750 arrayRef.push_back(cUnit->irb->getInt32(offset));
1751 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1752 cUnit->irb->SetDexOffset(node);
1753}
1754
1755// Attach method info as metadata to special intrinsic
1756void setMethodInfo(CompilationUnit* cUnit)
1757{
1758 // We don't want dex offset on this
1759 cUnit->irb->SetDexOffset(NULL);
1760 greenland::IntrinsicHelper::IntrinsicId id;
1761 id = greenland::IntrinsicHelper::MethodInfo;
1762 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1763 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1764 llvm::SmallVector<llvm::Value*, 2> regInfo;
1765 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1766 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1767 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1768 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1769 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1770 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1771 inst->setMetadata("RegInfo", regInfoNode);
1772 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1773 llvm::SmallVector<llvm::Value*, 50> pmap;
1774 for (int i = 0; i < promoSize; i++) {
1775 PromotionMap* p = &cUnit->promotionMap[i];
1776 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1777 ((p->fpReg & 0xff) << 16) |
1778 ((p->coreReg & 0xff) << 8) |
1779 ((p->fpLocation & 0xf) << 4) |
1780 (p->coreLocation & 0xf);
1781 pmap.push_back(cUnit->irb->getInt32(mapData));
1782 }
1783 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1784 inst->setMetadata("PromotionMap", mapNode);
1785 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1786}
1787
1788/* Handle the content in each basic block */
1789bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1790{
buzbeed1643e42012-09-05 14:06:51 -07001791 if (bb->blockType == kDead) return false;
buzbee2cfc6392012-05-07 14:51:40 -07001792 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
buzbeef5f5a122012-09-21 13:57:36 -07001793 if (llvmBB == NULL) {
1794 CHECK(bb->blockType == kExitBlock);
1795 } else {
1796 cUnit->irb->SetInsertPoint(llvmBB);
1797 setDexOffset(cUnit, bb->startOffset);
1798 }
buzbee2cfc6392012-05-07 14:51:40 -07001799
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001800 if (cUnit->printMe) {
1801 LOG(INFO) << "................................";
1802 LOG(INFO) << "Block id " << bb->id;
1803 if (llvmBB != NULL) {
1804 LOG(INFO) << "label " << llvmBB->getName().str().c_str();
1805 } else {
1806 LOG(INFO) << "llvmBB is NULL";
1807 }
1808 }
1809
buzbee2cfc6392012-05-07 14:51:40 -07001810 if (bb->blockType == kEntryBlock) {
1811 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001812 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1813 cUnit->numDalvikRegisters, true,
1814 kAllocMisc);
1815 for (int i = 0; i < cUnit->numSSARegs; i++) {
buzbee6ec5e232012-09-20 15:50:03 -07001816 int vReg = SRegToVReg(cUnit, i);
1817 if (vReg > SSA_METHOD_BASEREG) {
1818 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1819 }
buzbeeb03f4872012-06-11 15:22:11 -07001820 }
1821 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1822 if (canBeRef[i]) {
1823 cUnit->numShadowFrameEntries++;
1824 }
1825 }
1826 if (cUnit->numShadowFrameEntries > 0) {
1827 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1828 cUnit->numShadowFrameEntries, true,
1829 kAllocMisc);
1830 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1831 if (canBeRef[i]) {
1832 cUnit->shadowMap[j++] = i;
1833 }
1834 }
buzbeeb03f4872012-06-11 15:22:11 -07001835 }
Shih-wei Liao569daf12012-08-10 23:22:33 -07001836 greenland::IntrinsicHelper::IntrinsicId id =
1837 greenland::IntrinsicHelper::AllocaShadowFrame;
1838 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1839 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1840 cUnit->irb->CreateCall(func, entries);
buzbee2cfc6392012-05-07 14:51:40 -07001841 } else if (bb->blockType == kExitBlock) {
1842 /*
1843 * Because of the differences between how MIR/LIR and llvm handle exit
1844 * blocks, we won't explicitly covert them. On the llvm-to-lir
1845 * path, it will need to be regenereated.
1846 */
1847 return false;
buzbee6969d502012-06-15 16:40:31 -07001848 } else if (bb->blockType == kExceptionHandling) {
1849 /*
1850 * Because we're deferring null checking, delete the associated empty
1851 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001852 */
1853 llvmBB->eraseFromParent();
1854 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001855 }
1856
1857 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1858
1859 setDexOffset(cUnit, mir->offset);
1860
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001861 int opcode = mir->dalvikInsn.opcode;
1862 Instruction::Format dalvikFormat =
1863 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001864
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001865 if (opcode == kMirOpCheck) {
1866 // Combine check and work halves of throwing instruction.
1867 MIR* workHalf = mir->meta.throwInsn;
1868 mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
1869 opcode = mir->dalvikInsn.opcode;
1870 SSARepresentation* ssaRep = workHalf->ssaRep;
1871 workHalf->ssaRep = mir->ssaRep;
1872 mir->ssaRep = ssaRep;
1873 workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1874 if (bb->successorBlockList.blockListType == kCatch) {
1875 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
1876 greenland::IntrinsicHelper::CatchTargets);
1877 llvm::Value* switchKey =
1878 cUnit->irb->CreateCall(intr, cUnit->irb->getInt32(mir->offset));
1879 GrowableListIterator iter;
1880 oatGrowableListIteratorInit(&bb->successorBlockList.blocks, &iter);
1881 // New basic block to use for work half
1882 llvm::BasicBlock* workBB =
1883 llvm::BasicBlock::Create(*cUnit->context, "", cUnit->func);
1884 llvm::SwitchInst* sw =
1885 cUnit->irb->CreateSwitch(switchKey, workBB,
1886 bb->successorBlockList.blocks.numUsed);
1887 while (true) {
1888 SuccessorBlockInfo *successorBlockInfo =
1889 (SuccessorBlockInfo *) oatGrowableListIteratorNext(&iter);
1890 if (successorBlockInfo == NULL) break;
1891 llvm::BasicBlock *target =
1892 getLLVMBlock(cUnit, successorBlockInfo->block->id);
1893 int typeIndex = successorBlockInfo->key;
1894 sw->addCase(cUnit->irb->getInt32(typeIndex), target);
1895 }
1896 llvmBB = workBB;
1897 cUnit->irb->SetInsertPoint(llvmBB);
1898 }
1899 }
1900
1901 if (opcode >= kMirOpFirst) {
buzbee2cfc6392012-05-07 14:51:40 -07001902 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1903 continue;
1904 }
1905
1906 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1907 NULL /* labelList */);
1908 if (notHandled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001909 Instruction::Code dalvikOpcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001910 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001911 mir->offset, opcode,
buzbee2cfc6392012-05-07 14:51:40 -07001912 Instruction::Name(dalvikOpcode),
1913 dalvikFormat);
1914 }
1915 }
1916
buzbee4be777b2012-07-12 14:38:18 -07001917 if (bb->blockType == kEntryBlock) {
1918 cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
1919 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001920 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1921 }
1922
1923 return false;
1924}
1925
buzbee4f4dfc72012-07-02 14:54:44 -07001926char remapShorty(char shortyType) {
1927 /*
1928 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1929 * and longs/doubles are represented as a pair of registers. When sub-word
1930 * arguments (and method results) are passed, they are extended to Dalvik
1931 * virtual register containers. Because llvm is picky about type consistency,
1932 * we must either cast the "real" type to 32-bit container multiple Dalvik
1933 * register types, or always use the expanded values.
1934 * Here, we're doing the latter. We map the shorty signature to container
1935 * types (which is valid so long as we always do a real expansion of passed
1936 * arguments and field loads).
1937 */
1938 switch(shortyType) {
1939 case 'Z' : shortyType = 'I'; break;
1940 case 'B' : shortyType = 'I'; break;
1941 case 'S' : shortyType = 'I'; break;
1942 case 'C' : shortyType = 'I'; break;
1943 default: break;
1944 }
1945 return shortyType;
1946}
1947
buzbee2cfc6392012-05-07 14:51:40 -07001948llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1949
1950 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001951 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001952 greenland::kAccurate);
1953
1954 // Get argument type
1955 std::vector<llvm::Type*> args_type;
1956
1957 // method object
1958 args_type.push_back(cUnit->irb->GetJMethodTy());
1959
1960 // Do we have a "this"?
1961 if ((cUnit->access_flags & kAccStatic) == 0) {
1962 args_type.push_back(cUnit->irb->GetJObjectTy());
1963 }
1964
1965 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001966 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001967 greenland::kAccurate));
1968 }
1969
1970 return llvm::FunctionType::get(ret_type, args_type, false);
1971}
1972
1973bool createFunction(CompilationUnit* cUnit) {
1974 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1975 /* with_signature */ false));
1976 llvm::FunctionType* func_type = getFunctionType(cUnit);
1977
1978 if (func_type == NULL) {
1979 return false;
1980 }
1981
1982 cUnit->func = llvm::Function::Create(func_type,
1983 llvm::Function::ExternalLinkage,
1984 func_name, cUnit->module);
1985
1986 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1987 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1988
1989 arg_iter->setName("method");
1990 ++arg_iter;
1991
1992 int startSReg = cUnit->numRegs;
1993
1994 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
1995 arg_iter->setName(StringPrintf("v%i_0", startSReg));
1996 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
1997 }
1998
1999 return true;
2000}
2001
2002bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
2003{
2004 // Skip the exit block
buzbeed1643e42012-09-05 14:06:51 -07002005 if ((bb->blockType == kDead) ||(bb->blockType == kExitBlock)) {
buzbee2cfc6392012-05-07 14:51:40 -07002006 cUnit->idToBlockMap.Put(bb->id, NULL);
2007 } else {
2008 int offset = bb->startOffset;
2009 bool entryBlock = (bb->blockType == kEntryBlock);
2010 llvm::BasicBlock* llvmBB =
2011 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
buzbee8320f382012-09-11 16:29:42 -07002012 StringPrintf(kLabelFormat, bb->catchEntry ? kCatchBlock :
2013 kNormalBlock, offset, bb->id), cUnit->func);
buzbee2cfc6392012-05-07 14:51:40 -07002014 if (entryBlock) {
2015 cUnit->entryBB = llvmBB;
2016 cUnit->placeholderBB =
2017 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
2018 cUnit->func);
2019 }
2020 cUnit->idToBlockMap.Put(bb->id, llvmBB);
2021 }
2022 return false;
2023}
2024
2025
2026/*
2027 * Convert MIR to LLVM_IR
2028 * o For each ssa name, create LLVM named value. Type these
2029 * appropriately, and ignore high half of wide and double operands.
2030 * o For each MIR basic block, create an LLVM basic block.
2031 * o Iterate through the MIR a basic block at a time, setting arguments
2032 * to recovered ssa name.
2033 */
2034void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
2035{
2036 initIR(cUnit);
2037 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
2038
2039 // Create the function
2040 createFunction(cUnit);
2041
2042 // Create an LLVM basic block for each MIR block in dfs preorder
2043 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
2044 kPreOrderDFSTraversal, false /* isIterative */);
2045 /*
2046 * Create an llvm named value for each MIR SSA name. Note: we'll use
2047 * placeholders for all non-argument values (because we haven't seen
2048 * the definition yet).
2049 */
2050 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2051 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2052 arg_iter++; /* Skip path method */
2053 for (int i = 0; i < cUnit->numSSARegs; i++) {
2054 llvm::Value* val;
buzbee85eee022012-07-16 22:12:38 -07002055 RegLocation rlTemp = cUnit->regLocation[i];
2056 if ((SRegToVReg(cUnit, i) < 0) || rlTemp.highWord) {
buzbee2a83e8f2012-07-13 16:42:30 -07002057 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
2058 } else if ((i < cUnit->numRegs) ||
2059 (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee85eee022012-07-16 22:12:38 -07002060 llvm::Constant* immValue = cUnit->regLocation[i].wide ?
2061 cUnit->irb->GetJLong(0) : cUnit->irb->GetJInt(0);
buzbee2a83e8f2012-07-13 16:42:30 -07002062 val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
2063 val->setName(llvmSSAName(cUnit, i));
buzbee2cfc6392012-05-07 14:51:40 -07002064 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
buzbee2cfc6392012-05-07 14:51:40 -07002065 } else {
2066 // Recover previously-created argument values
2067 llvm::Value* argVal = arg_iter++;
2068 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
2069 }
2070 }
buzbee2cfc6392012-05-07 14:51:40 -07002071
2072 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
2073 kPreOrderDFSTraversal, false /* Iterative */);
2074
buzbee4be777b2012-07-12 14:38:18 -07002075 /*
2076 * In a few rare cases of verification failure, the verifier will
2077 * replace one or more Dalvik opcodes with the special
2078 * throw-verification-failure opcode. This can leave the SSA graph
2079 * in an invalid state, as definitions may be lost, while uses retained.
2080 * To work around this problem, we insert placeholder definitions for
2081 * all Dalvik SSA regs in the "placeholder" block. Here, after
2082 * bitcode conversion is complete, we examine those placeholder definitions
2083 * and delete any with no references (which normally is all of them).
2084 *
2085 * If any definitions remain, we link the placeholder block into the
2086 * CFG. Otherwise, it is deleted.
2087 */
2088 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
2089 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
2090 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2091 DCHECK(inst != NULL);
2092 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2093 DCHECK(val != NULL);
2094 if (val->getNumUses() == 0) {
2095 inst->eraseFromParent();
2096 }
2097 }
2098 setDexOffset(cUnit, 0);
2099 if (cUnit->placeholderBB->empty()) {
2100 cUnit->placeholderBB->eraseFromParent();
2101 } else {
2102 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2103 cUnit->irb->CreateBr(cUnit->entryTargetBB);
2104 cUnit->entryTargetBB = cUnit->placeholderBB;
2105 }
2106 cUnit->irb->SetInsertPoint(cUnit->entryBB);
2107 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07002108
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002109 if (cUnit->enableDebug & (1 << kDebugVerifyBitcode)) {
2110 if (llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction)) {
2111 LOG(INFO) << "Bitcode verification FAILED for "
2112 << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
2113 << " of size " << cUnit->insnsSize;
2114 cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
2115 }
2116 }
buzbee2cfc6392012-05-07 14:51:40 -07002117
buzbeead8f15e2012-06-18 14:49:45 -07002118 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
2119 // Write bitcode to file
2120 std::string errmsg;
2121 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
2122 oatReplaceSpecialChars(fname);
buzbee6459e7c2012-10-02 14:42:41 -07002123 // TODO: make configurable change naming mechanism to avoid fname length issues.
buzbee4f1181f2012-06-22 13:52:12 -07002124 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002125
buzbee6459e7c2012-10-02 14:42:41 -07002126 if (fname.size() > 240) {
2127 LOG(INFO) << "Warning: bitcode filename too long. Truncated.";
2128 fname.resize(240);
2129 }
2130
buzbeead8f15e2012-06-18 14:49:45 -07002131 llvm::OwningPtr<llvm::tool_output_file> out_file(
2132 new llvm::tool_output_file(fname.c_str(), errmsg,
2133 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002134
buzbeead8f15e2012-06-18 14:49:45 -07002135 if (!errmsg.empty()) {
2136 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2137 }
2138
2139 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
2140 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002141 }
buzbee2cfc6392012-05-07 14:51:40 -07002142}
2143
2144RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
2145 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002146 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002147 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2148 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07002149 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07002150 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002151 // FIXME: need to be more robust, handle FP and be in a position to
2152 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002153 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2154 memset(&res, 0, sizeof(res));
2155 res.location = kLocPhysReg;
2156 res.lowReg = oatAllocTemp(cUnit);
2157 res.home = true;
2158 res.sRegLow = INVALID_SREG;
2159 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002160 llvm::Type* ty = val->getType();
2161 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2162 (ty == cUnit->irb->getDoubleTy()));
2163 if (res.wide) {
2164 res.highReg = oatAllocTemp(cUnit);
2165 }
buzbee4f1181f2012-06-22 13:52:12 -07002166 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002167 } else {
2168 DCHECK_EQ(valName[0], 'v');
2169 int baseSReg = INVALID_SREG;
2170 sscanf(valName.c_str(), "v%d_", &baseSReg);
2171 res = cUnit->regLocation[baseSReg];
2172 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002173 }
2174 } else {
2175 res = it->second;
2176 }
2177 return res;
2178}
2179
2180Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
2181{
2182 Instruction::Code res = Instruction::NOP;
2183 if (isWide) {
2184 switch(op) {
2185 case kOpAdd: res = Instruction::ADD_LONG; break;
2186 case kOpSub: res = Instruction::SUB_LONG; break;
2187 case kOpMul: res = Instruction::MUL_LONG; break;
2188 case kOpDiv: res = Instruction::DIV_LONG; break;
2189 case kOpRem: res = Instruction::REM_LONG; break;
2190 case kOpAnd: res = Instruction::AND_LONG; break;
2191 case kOpOr: res = Instruction::OR_LONG; break;
2192 case kOpXor: res = Instruction::XOR_LONG; break;
2193 case kOpLsl: res = Instruction::SHL_LONG; break;
2194 case kOpLsr: res = Instruction::USHR_LONG; break;
2195 case kOpAsr: res = Instruction::SHR_LONG; break;
2196 default: LOG(FATAL) << "Unexpected OpKind " << op;
2197 }
2198 } else if (isConst){
2199 switch(op) {
2200 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2201 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2202 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2203 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2204 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2205 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2206 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2207 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2208 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2209 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2210 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2211 default: LOG(FATAL) << "Unexpected OpKind " << op;
2212 }
2213 } else {
2214 switch(op) {
2215 case kOpAdd: res = Instruction::ADD_INT; break;
2216 case kOpSub: res = Instruction::SUB_INT; break;
2217 case kOpMul: res = Instruction::MUL_INT; break;
2218 case kOpDiv: res = Instruction::DIV_INT; break;
2219 case kOpRem: res = Instruction::REM_INT; break;
2220 case kOpAnd: res = Instruction::AND_INT; break;
2221 case kOpOr: res = Instruction::OR_INT; break;
2222 case kOpXor: res = Instruction::XOR_INT; break;
2223 case kOpLsl: res = Instruction::SHL_INT; break;
2224 case kOpLsr: res = Instruction::USHR_INT; break;
2225 case kOpAsr: res = Instruction::SHR_INT; break;
2226 default: LOG(FATAL) << "Unexpected OpKind " << op;
2227 }
2228 }
2229 return res;
2230}
2231
buzbee4f1181f2012-06-22 13:52:12 -07002232Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2233{
2234 Instruction::Code res = Instruction::NOP;
2235 if (isWide) {
2236 switch(op) {
2237 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2238 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2239 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2240 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2241 case kOpRem: res = Instruction::REM_DOUBLE; break;
2242 default: LOG(FATAL) << "Unexpected OpKind " << op;
2243 }
2244 } else {
2245 switch(op) {
2246 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2247 case kOpSub: res = Instruction::SUB_FLOAT; break;
2248 case kOpMul: res = Instruction::MUL_FLOAT; break;
2249 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2250 case kOpRem: res = Instruction::REM_FLOAT; break;
2251 default: LOG(FATAL) << "Unexpected OpKind " << op;
2252 }
2253 }
2254 return res;
2255}
2256
2257void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2258{
2259 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002260 /*
2261 * Normally, we won't ever generate an FP operation with an immediate
2262 * operand (not supported in Dex instruction set). However, the IR builder
2263 * may insert them - in particular for createNegFP. Recognize this case
2264 * and deal with it.
2265 */
2266 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2267 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2268 DCHECK(op2C == NULL);
2269 if ((op1C != NULL) && (op == kOpSub)) {
2270 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2271 if (rlDest.wide) {
2272 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2273 } else {
2274 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2275 }
buzbee4f1181f2012-06-22 13:52:12 -07002276 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002277 DCHECK(op1C == NULL);
2278 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2279 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2280 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2281 if (rlDest.wide) {
2282 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2283 } else {
2284 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2285 }
buzbee4f1181f2012-06-22 13:52:12 -07002286 }
2287}
2288
buzbee101305f2012-06-28 18:00:56 -07002289void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2290 Instruction::Code opcode)
2291{
2292 RegLocation rlDest = getLoc(cUnit, inst);
2293 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2294 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2295}
2296
buzbee76592632012-06-29 15:18:35 -07002297void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2298{
2299 RegLocation rlDest = getLoc(cUnit, inst);
2300 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2301 Instruction::Code opcode;
2302 if (rlDest.wide) {
2303 if (rlSrc.wide) {
2304 opcode = Instruction::LONG_TO_DOUBLE;
2305 } else {
2306 opcode = Instruction::INT_TO_DOUBLE;
2307 }
2308 } else {
2309 if (rlSrc.wide) {
2310 opcode = Instruction::LONG_TO_FLOAT;
2311 } else {
2312 opcode = Instruction::INT_TO_FLOAT;
2313 }
2314 }
2315 genConversion(cUnit, opcode, rlDest, rlSrc);
2316}
2317
TDYa1274ec8ccd2012-08-11 07:04:57 -07002318void cvtFPToInt(CompilationUnit* cUnit, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002319{
TDYa1274ec8ccd2012-08-11 07:04:57 -07002320 RegLocation rlDest = getLoc(cUnit, call_inst);
2321 RegLocation rlSrc = getLoc(cUnit, call_inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002322 Instruction::Code opcode;
2323 if (rlDest.wide) {
2324 if (rlSrc.wide) {
2325 opcode = Instruction::DOUBLE_TO_LONG;
2326 } else {
2327 opcode = Instruction::FLOAT_TO_LONG;
2328 }
2329 } else {
2330 if (rlSrc.wide) {
2331 opcode = Instruction::DOUBLE_TO_INT;
2332 } else {
2333 opcode = Instruction::FLOAT_TO_INT;
2334 }
2335 }
2336 genConversion(cUnit, opcode, rlDest, rlSrc);
2337}
2338
2339void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2340{
2341 RegLocation rlDest = getLoc(cUnit, inst);
2342 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2343 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2344}
2345
2346void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2347{
2348 RegLocation rlDest = getLoc(cUnit, inst);
2349 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2350 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2351 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2352 storeValue(cUnit, rlDest, rlSrc);
2353}
2354
2355void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2356{
2357 RegLocation rlDest = getLoc(cUnit, inst);
2358 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2359 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2360}
2361
2362
buzbee101305f2012-06-28 18:00:56 -07002363void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2364{
2365 // TODO: evaluate src/tgt types and add general support for more than int to long
2366 RegLocation rlDest = getLoc(cUnit, inst);
2367 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2368 DCHECK(rlDest.wide);
2369 DCHECK(!rlSrc.wide);
2370 DCHECK(!rlDest.fp);
2371 DCHECK(!rlSrc.fp);
2372 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2373 if (rlSrc.location == kLocPhysReg) {
2374 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2375 } else {
2376 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2377 }
2378 if (isSigned) {
2379 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2380 } else {
2381 loadConstant(cUnit, rlResult.highReg, 0);
2382 }
2383 storeValueWide(cUnit, rlDest, rlResult);
2384}
2385
buzbee2cfc6392012-05-07 14:51:40 -07002386void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2387{
2388 RegLocation rlDest = getLoc(cUnit, inst);
2389 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002390 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002391 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2392 if ((op == kOpSub) && (lhsImm != NULL)) {
2393 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002394 if (rlSrc1.wide) {
2395 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2396 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2397 } else {
2398 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2399 lhsImm->getSExtValue());
2400 }
buzbee4f1181f2012-06-22 13:52:12 -07002401 return;
2402 }
2403 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002404 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2405 llvm::Value* rhs = inst->getOperand(1);
buzbee9a2487f2012-07-26 14:01:13 -07002406 llvm::ConstantInt* constRhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2407 if (!rlDest.wide && (constRhs != NULL)) {
buzbee2cfc6392012-05-07 14:51:40 -07002408 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
buzbee9a2487f2012-07-26 14:01:13 -07002409 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, constRhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002410 } else {
2411 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
buzbee9a2487f2012-07-26 14:01:13 -07002412 RegLocation rlSrc2;
2413 if (constRhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002414 // ir_builder converts NOT_LONG to xor src, -1. Restore
2415 DCHECK_EQ(dalvikOp, Instruction::XOR_LONG);
2416 DCHECK_EQ(-1L, constRhs->getSExtValue());
2417 dalvikOp = Instruction::NOT_LONG;
buzbee9a2487f2012-07-26 14:01:13 -07002418 rlSrc2 = rlSrc1;
2419 } else {
2420 rlSrc2 = getLoc(cUnit, rhs);
2421 }
buzbee2cfc6392012-05-07 14:51:40 -07002422 if (rlDest.wide) {
2423 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2424 } else {
2425 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2426 }
2427 }
2428}
2429
buzbee2a83e8f2012-07-13 16:42:30 -07002430void cvtShiftOp(CompilationUnit* cUnit, Instruction::Code opcode,
2431 llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002432{
buzbee2a83e8f2012-07-13 16:42:30 -07002433 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2434 RegLocation rlDest = getLoc(cUnit, callInst);
2435 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2436 llvm::Value* rhs = callInst->getArgOperand(1);
2437 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2438 DCHECK(!rlDest.wide);
2439 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002440 } else {
buzbee2a83e8f2012-07-13 16:42:30 -07002441 RegLocation rlShift = getLoc(cUnit, rhs);
2442 if (callInst->getType() == cUnit->irb->getInt64Ty()) {
2443 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2444 } else {
2445 genArithOpInt(cUnit, opcode, rlDest, rlSrc, rlShift);
2446 }
buzbee101305f2012-06-28 18:00:56 -07002447 }
2448}
2449
buzbee2cfc6392012-05-07 14:51:40 -07002450void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2451{
2452 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2453 DCHECK(brInst != NULL);
2454 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2455 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2456 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2457}
2458
2459void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2460{
2461 // Nop - these have already been processed
2462}
2463
2464void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2465{
2466 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2467 llvm::Value* retVal = retInst->getReturnValue();
2468 if (retVal != NULL) {
2469 RegLocation rlSrc = getLoc(cUnit, retVal);
2470 if (rlSrc.wide) {
2471 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2472 } else {
2473 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2474 }
2475 }
2476 genExitSequence(cUnit);
2477}
2478
2479ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2480{
2481 ConditionCode res = kCondAl;
2482 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002483 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002484 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2485 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2486 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002487 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002488 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002489 default: LOG(FATAL) << "Unexpected llvm condition";
2490 }
2491 return res;
2492}
2493
2494void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2495{
2496 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2497 UNIMPLEMENTED(FATAL);
2498}
2499
2500void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2501 llvm::BranchInst* brInst)
2502{
2503 // Get targets
2504 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2505 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2506 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2507 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2508 // Get comparison operands
2509 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2510 ConditionCode cond = getCond(iCmpInst->getPredicate());
2511 llvm::Value* lhs = iCmpInst->getOperand(0);
2512 // Not expecting a constant as 1st operand
2513 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2514 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2515 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2516 llvm::Value* rhs = inst->getOperand(1);
buzbeeb046e162012-10-30 15:48:42 -07002517 if (cUnit->instructionSet == kMips) {
2518 // Compare and branch in one shot
2519 UNIMPLEMENTED(FATAL);
2520 }
buzbee2cfc6392012-05-07 14:51:40 -07002521 //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);
buzbee2cfc6392012-05-07 14:51:40 -07002533 // Fallthrough
2534 opUnconditionalBranch(cUnit, fallThrough);
2535}
2536
2537void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2538 llvm::Function* callee)
2539{
2540 UNIMPLEMENTED(FATAL);
2541}
2542
buzbee2cfc6392012-05-07 14:51:40 -07002543void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2544{
buzbee4f1181f2012-06-22 13:52:12 -07002545 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002546 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2547 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002548 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2549 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002550 if (rlSrc.wide) {
2551 storeValueWide(cUnit, rlDest, rlSrc);
2552 } else {
2553 storeValue(cUnit, rlDest, rlSrc);
2554 }
2555}
2556
2557// Note: Immediate arg is a ConstantInt regardless of result type
2558void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2559{
buzbee4f1181f2012-06-22 13:52:12 -07002560 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002561 llvm::ConstantInt* src =
2562 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2563 uint64_t immval = src->getZExtValue();
2564 RegLocation rlDest = getLoc(cUnit, callInst);
2565 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2566 if (rlDest.wide) {
2567 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2568 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2569 storeValueWide(cUnit, rlDest, rlResult);
2570 } else {
2571 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2572 storeValue(cUnit, rlDest, rlResult);
2573 }
2574}
2575
buzbee101305f2012-06-28 18:00:56 -07002576void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2577 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002578{
buzbee4f1181f2012-06-22 13:52:12 -07002579 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002580 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002581 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002582 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002583 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002584 if (isString) {
2585 genConstString(cUnit, index, rlDest);
2586 } else {
2587 genConstClass(cUnit, index, rlDest);
2588 }
2589}
2590
2591void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2592{
2593 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2594 llvm::ConstantInt* offsetVal =
2595 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2596 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2597 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002598}
2599
buzbee4f1181f2012-06-22 13:52:12 -07002600void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2601{
buzbee32412962012-06-26 16:27:56 -07002602 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002603 llvm::ConstantInt* typeIdxVal =
2604 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2605 uint32_t typeIdx = typeIdxVal->getZExtValue();
2606 RegLocation rlDest = getLoc(cUnit, callInst);
2607 genNewInstance(cUnit, typeIdx, rlDest);
2608}
2609
buzbee8fa0fda2012-06-27 15:44:52 -07002610void cvtNewArray(CompilationUnit* cUnit, llvm::CallInst* callInst)
2611{
2612 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2613 llvm::ConstantInt* typeIdxVal =
2614 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2615 uint32_t typeIdx = typeIdxVal->getZExtValue();
2616 llvm::Value* len = callInst->getArgOperand(1);
2617 RegLocation rlLen = getLoc(cUnit, len);
2618 RegLocation rlDest = getLoc(cUnit, callInst);
2619 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2620}
2621
2622void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2623{
2624 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2625 llvm::ConstantInt* typeIdxVal =
2626 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2627 uint32_t typeIdx = typeIdxVal->getZExtValue();
2628 llvm::Value* src = callInst->getArgOperand(1);
2629 RegLocation rlSrc = getLoc(cUnit, src);
2630 RegLocation rlDest = getLoc(cUnit, callInst);
2631 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2632}
2633
buzbee32412962012-06-26 16:27:56 -07002634void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2635{
2636 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2637 llvm::Value* src = callInst->getArgOperand(0);
2638 RegLocation rlSrc = getLoc(cUnit, src);
2639 genThrow(cUnit, rlSrc);
2640}
2641
buzbee8fa0fda2012-06-27 15:44:52 -07002642void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2643 llvm::CallInst* callInst)
2644{
2645 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2646 llvm::ConstantInt* optFlags =
2647 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2648 llvm::Value* src = callInst->getArgOperand(1);
2649 RegLocation rlSrc = getLoc(cUnit, src);
2650 if (isEnter) {
2651 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2652 } else {
2653 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2654 }
2655}
2656
buzbee76592632012-06-29 15:18:35 -07002657void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002658{
2659 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2660 llvm::ConstantInt* optFlags =
2661 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2662 llvm::Value* src = callInst->getArgOperand(1);
2663 RegLocation rlSrc = getLoc(cUnit, src);
2664 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2665 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2666 RegLocation rlDest = getLoc(cUnit, callInst);
2667 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2668 int lenOffset = Array::LengthOffset().Int32Value();
2669 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2670 storeValue(cUnit, rlDest, rlResult);
2671}
2672
buzbee32412962012-06-26 16:27:56 -07002673void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2674{
buzbee32412962012-06-26 16:27:56 -07002675 RegLocation rlDest = getLoc(cUnit, callInst);
Ian Rogers474b6da2012-09-25 00:20:38 -07002676 genMoveException(cUnit, rlDest);
buzbee32412962012-06-26 16:27:56 -07002677}
2678
buzbee4f1181f2012-06-22 13:52:12 -07002679void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2680 bool isObject)
2681{
buzbee32412962012-06-26 16:27:56 -07002682 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002683 llvm::ConstantInt* typeIdxVal =
2684 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2685 uint32_t typeIdx = typeIdxVal->getZExtValue();
2686 RegLocation rlDest = getLoc(cUnit, callInst);
2687 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2688}
2689
buzbee8fa0fda2012-06-27 15:44:52 -07002690void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2691 bool isObject)
2692{
2693 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2694 llvm::ConstantInt* typeIdxVal =
2695 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2696 uint32_t typeIdx = typeIdxVal->getZExtValue();
2697 llvm::Value* src = callInst->getArgOperand(1);
2698 RegLocation rlSrc = getLoc(cUnit, src);
2699 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2700}
2701
2702void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2703 int scale)
2704{
2705 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2706 llvm::ConstantInt* optFlags =
2707 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2708 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2709 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2710 RegLocation rlDest = getLoc(cUnit, callInst);
2711 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2712 rlDest, scale);
2713}
2714
2715void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002716 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002717{
2718 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2719 llvm::ConstantInt* optFlags =
2720 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2721 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2722 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2723 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002724 if (isObject) {
2725 genArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
2726 rlSrc, scale);
2727 } else {
2728 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2729 rlSrc, scale);
2730 }
2731}
2732
2733void cvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
2734{
2735 cvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
2736}
2737
2738void cvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
2739 OpSize size, int scale)
2740{
2741 cvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002742}
2743
buzbee101305f2012-06-28 18:00:56 -07002744void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2745 bool isWide, bool isObj)
2746{
2747 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2748 llvm::ConstantInt* optFlags =
2749 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2750 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2751 llvm::ConstantInt* fieldIdx =
2752 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2753 RegLocation rlDest = getLoc(cUnit, callInst);
2754 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2755 size, rlDest, rlObj, isWide, isObj);
2756}
2757
2758void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2759 bool isWide, bool isObj)
2760{
2761 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2762 llvm::ConstantInt* optFlags =
2763 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2764 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2765 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2766 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002767 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002768 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2769 size, rlSrc, rlObj, isWide, isObj);
2770}
2771
2772void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2773{
2774 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2775 llvm::ConstantInt* typeIdx =
2776 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2777 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2778 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2779}
2780
buzbee76592632012-06-29 15:18:35 -07002781void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2782 Instruction::Code opcode)
2783{
2784 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2785 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2786 RegLocation rlDest = getLoc(cUnit, callInst);
2787 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2788}
2789
2790void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2791{
2792 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2793 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2794 RegLocation rlDest = getLoc(cUnit, callInst);
2795 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2796}
2797
buzbeef58c12c2012-07-03 15:06:29 -07002798void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2799{
2800 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2801 DCHECK(swInst != NULL);
2802 llvm::Value* testVal = swInst->getCondition();
2803 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2804 DCHECK(tableOffsetNode != NULL);
2805 llvm::ConstantInt* tableOffsetValue =
2806 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2807 int32_t tableOffset = tableOffsetValue->getSExtValue();
2808 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeea1da8a52012-07-09 14:00:21 -07002809 const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2810 u2 tableMagic = *table;
2811 if (tableMagic == 0x100) {
2812 genPackedSwitch(cUnit, tableOffset, rlSrc);
2813 } else {
2814 DCHECK_EQ(tableMagic, 0x200);
2815 genSparseSwitch(cUnit, tableOffset, rlSrc);
2816 }
buzbeef58c12c2012-07-03 15:06:29 -07002817}
2818
buzbee6969d502012-06-15 16:40:31 -07002819void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002820 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002821{
2822 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2823 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002824 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002825 info->result.location = kLocInvalid;
2826 } else {
2827 info->result = getLoc(cUnit, callInst);
2828 }
2829 llvm::ConstantInt* invokeTypeVal =
2830 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2831 llvm::ConstantInt* methodIndexVal =
2832 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2833 llvm::ConstantInt* optFlagsVal =
2834 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2835 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2836 info->index = methodIndexVal->getZExtValue();
2837 info->optFlags = optFlagsVal->getZExtValue();
2838 info->offset = cUnit->currentDalvikOffset;
2839
buzbee6969d502012-06-15 16:40:31 -07002840 // Count the argument words, and then build argument array.
2841 info->numArgWords = 0;
2842 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2843 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2844 info->numArgWords += tLoc.wide ? 2 : 1;
2845 }
2846 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2847 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2848 // Now, fill in the location records, synthesizing high loc of wide vals
2849 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002850 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002851 if (info->args[next].wide) {
2852 next++;
2853 // TODO: Might make sense to mark this as an invalid loc
2854 info->args[next].origSReg = info->args[next-1].origSReg+1;
2855 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2856 }
2857 next++;
2858 }
buzbee4f4dfc72012-07-02 14:54:44 -07002859 // TODO - rework such that we no longer need isRange
2860 info->isRange = (info->numArgWords > 5);
2861
buzbee76592632012-06-29 15:18:35 -07002862 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002863 genFilledNewArray(cUnit, info);
2864 } else {
2865 genInvoke(cUnit, info);
2866 }
buzbee6969d502012-06-15 16:40:31 -07002867}
2868
buzbeead8f15e2012-06-18 14:49:45 -07002869/* Look up the RegLocation associated with a Value. Must already be defined */
2870RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2871{
2872 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2873 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2874 return it->second;
2875}
2876
buzbee2cfc6392012-05-07 14:51:40 -07002877bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2878{
buzbee0967a252012-09-14 10:43:54 -07002879 while (cUnit->llvmBlocks.find(bb) == cUnit->llvmBlocks.end()) {
2880 llvm::BasicBlock* nextBB = NULL;
2881 cUnit->llvmBlocks.insert(bb);
2882 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2883 // Define the starting label
2884 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2885 // Extract the type and starting offset from the block's name
buzbee951c0a12012-10-03 16:31:39 -07002886 char blockType = kInvalidBlock;
2887 if (isEntry) {
2888 blockType = kNormalBlock;
2889 blockLabel->operands[0] = 0;
2890 } else if (!bb->hasName()) {
2891 blockType = kNormalBlock;
2892 blockLabel->operands[0] = DexFile::kDexNoIndex;
buzbee0967a252012-09-14 10:43:54 -07002893 } else {
buzbee951c0a12012-10-03 16:31:39 -07002894 std::string blockName = bb->getName().str();
2895 int dummy;
2896 sscanf(blockName.c_str(), kLabelFormat, &blockType, &blockLabel->operands[0], &dummy);
2897 cUnit->currentDalvikOffset = blockLabel->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002898 }
buzbee951c0a12012-10-03 16:31:39 -07002899 DCHECK((blockType == kNormalBlock) || (blockType == kCatchBlock));
2900 cUnit->currentDalvikOffset = blockLabel->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002901 // Set the label kind
2902 blockLabel->opcode = kPseudoNormalBlockLabel;
2903 // Insert the label
2904 oatAppendLIR(cUnit, blockLabel);
buzbee2cfc6392012-05-07 14:51:40 -07002905
buzbee0967a252012-09-14 10:43:54 -07002906 LIR* headLIR = NULL;
buzbee8320f382012-09-11 16:29:42 -07002907
buzbee0967a252012-09-14 10:43:54 -07002908 if (blockType == kCatchBlock) {
Bill Buzbeea5b30242012-09-28 07:19:44 -07002909 headLIR = newLIR0(cUnit, kPseudoExportedPC);
buzbee0967a252012-09-14 10:43:54 -07002910 }
buzbee8320f382012-09-11 16:29:42 -07002911
buzbee0967a252012-09-14 10:43:54 -07002912 // Free temp registers and reset redundant store tracking */
2913 oatResetRegPool(cUnit);
2914 oatResetDefTracking(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002915
buzbee0967a252012-09-14 10:43:54 -07002916 //TODO: restore oat incoming liveness optimization
2917 oatClobberAllRegs(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002918
buzbee0967a252012-09-14 10:43:54 -07002919 if (isEntry) {
2920 RegLocation* argLocs = (RegLocation*)
2921 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2922 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2923 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2924 // Skip past Method*
2925 it++;
2926 for (unsigned i = 0; it != it_end; ++it) {
2927 llvm::Value* val = it;
2928 argLocs[i++] = valToLoc(cUnit, val);
2929 llvm::Type* ty = val->getType();
2930 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2931 argLocs[i] = argLocs[i-1];
2932 argLocs[i].lowReg = argLocs[i].highReg;
2933 argLocs[i].origSReg++;
2934 argLocs[i].sRegLow = INVALID_SREG;
2935 argLocs[i].highWord = true;
2936 i++;
2937 }
2938 }
2939 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
2940 }
2941
2942 // Visit all of the instructions in the block
2943 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2944 llvm::Instruction* inst = it;
2945 llvm::BasicBlock::iterator nextIt = ++it;
2946 // Extract the Dalvik offset from the instruction
2947 uint32_t opcode = inst->getOpcode();
2948 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2949 if (dexOffsetNode != NULL) {
2950 llvm::ConstantInt* dexOffsetValue =
2951 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2952 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2953 }
2954
2955 oatResetRegPool(cUnit);
2956 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2957 oatClobberAllRegs(cUnit);
2958 }
2959
2960 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2961 oatResetDefTracking(cUnit);
2962 }
2963
2964 #ifndef NDEBUG
2965 /* Reset temp tracking sanity check */
2966 cUnit->liveSReg = INVALID_SREG;
2967 #endif
2968
2969 // TODO: use llvm opcode name here instead of "boundary" if verbose
2970 LIR* boundaryLIR = markBoundary(cUnit, cUnit->currentDalvikOffset, "boundary");
2971
2972 /* Remember the first LIR for thisl block*/
2973 if (headLIR == NULL) {
2974 headLIR = boundaryLIR;
2975 headLIR->defMask = ENCODE_ALL;
2976 }
2977
2978 switch(opcode) {
2979
2980 case llvm::Instruction::ICmp: {
2981 llvm::Instruction* nextInst = nextIt;
2982 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2983 if (brInst != NULL /* and... */) {
2984 cvtICmpBr(cUnit, inst, brInst);
2985 ++it;
2986 } else {
2987 cvtICmp(cUnit, inst);
2988 }
2989 }
2990 break;
2991
2992 case llvm::Instruction::Call: {
2993 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
2994 llvm::Function* callee = callInst->getCalledFunction();
2995 greenland::IntrinsicHelper::IntrinsicId id =
2996 cUnit->intrinsic_helper->GetIntrinsicId(callee);
2997 switch (id) {
2998 case greenland::IntrinsicHelper::AllocaShadowFrame:
2999 case greenland::IntrinsicHelper::SetShadowFrameEntry:
3000 case greenland::IntrinsicHelper::PopShadowFrame:
3001 // Ignore shadow frame stuff for quick compiler
3002 break;
3003 case greenland::IntrinsicHelper::CopyInt:
3004 case greenland::IntrinsicHelper::CopyObj:
3005 case greenland::IntrinsicHelper::CopyFloat:
3006 case greenland::IntrinsicHelper::CopyLong:
3007 case greenland::IntrinsicHelper::CopyDouble:
3008 cvtCopy(cUnit, callInst);
3009 break;
3010 case greenland::IntrinsicHelper::ConstInt:
3011 case greenland::IntrinsicHelper::ConstObj:
3012 case greenland::IntrinsicHelper::ConstLong:
3013 case greenland::IntrinsicHelper::ConstFloat:
3014 case greenland::IntrinsicHelper::ConstDouble:
3015 cvtConst(cUnit, callInst);
3016 break;
3017 case greenland::IntrinsicHelper::DivInt:
3018 case greenland::IntrinsicHelper::DivLong:
3019 cvtBinOp(cUnit, kOpDiv, inst);
3020 break;
3021 case greenland::IntrinsicHelper::RemInt:
3022 case greenland::IntrinsicHelper::RemLong:
3023 cvtBinOp(cUnit, kOpRem, inst);
3024 break;
3025 case greenland::IntrinsicHelper::MethodInfo:
3026 // Already dealt with - just ignore it here.
3027 break;
3028 case greenland::IntrinsicHelper::CheckSuspend:
3029 genSuspendTest(cUnit, 0 /* optFlags already applied */);
3030 break;
3031 case greenland::IntrinsicHelper::HLInvokeObj:
3032 case greenland::IntrinsicHelper::HLInvokeFloat:
3033 case greenland::IntrinsicHelper::HLInvokeDouble:
3034 case greenland::IntrinsicHelper::HLInvokeLong:
3035 case greenland::IntrinsicHelper::HLInvokeInt:
3036 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
3037 break;
3038 case greenland::IntrinsicHelper::HLInvokeVoid:
3039 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
3040 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003041 case greenland::IntrinsicHelper::HLFilledNewArray:
buzbee0967a252012-09-14 10:43:54 -07003042 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
3043 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003044 case greenland::IntrinsicHelper::HLFillArrayData:
buzbee0967a252012-09-14 10:43:54 -07003045 cvtFillArrayData(cUnit, callInst);
3046 break;
3047 case greenland::IntrinsicHelper::ConstString:
3048 cvtConstObject(cUnit, callInst, true /* isString */);
3049 break;
3050 case greenland::IntrinsicHelper::ConstClass:
3051 cvtConstObject(cUnit, callInst, false /* isString */);
3052 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003053 case greenland::IntrinsicHelper::HLCheckCast:
buzbee0967a252012-09-14 10:43:54 -07003054 cvtCheckCast(cUnit, callInst);
3055 break;
3056 case greenland::IntrinsicHelper::NewInstance:
3057 cvtNewInstance(cUnit, callInst);
3058 break;
3059 case greenland::IntrinsicHelper::HLSgetObject:
3060 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
3061 break;
3062 case greenland::IntrinsicHelper::HLSget:
3063 case greenland::IntrinsicHelper::HLSgetFloat:
3064 case greenland::IntrinsicHelper::HLSgetBoolean:
3065 case greenland::IntrinsicHelper::HLSgetByte:
3066 case greenland::IntrinsicHelper::HLSgetChar:
3067 case greenland::IntrinsicHelper::HLSgetShort:
3068 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
3069 break;
3070 case greenland::IntrinsicHelper::HLSgetWide:
3071 case greenland::IntrinsicHelper::HLSgetDouble:
3072 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
3073 break;
3074 case greenland::IntrinsicHelper::HLSput:
3075 case greenland::IntrinsicHelper::HLSputFloat:
3076 case greenland::IntrinsicHelper::HLSputBoolean:
3077 case greenland::IntrinsicHelper::HLSputByte:
3078 case greenland::IntrinsicHelper::HLSputChar:
3079 case greenland::IntrinsicHelper::HLSputShort:
3080 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
3081 break;
3082 case greenland::IntrinsicHelper::HLSputWide:
3083 case greenland::IntrinsicHelper::HLSputDouble:
3084 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
3085 break;
3086 case greenland::IntrinsicHelper::HLSputObject:
3087 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
3088 break;
3089 case greenland::IntrinsicHelper::GetException:
3090 cvtMoveException(cUnit, callInst);
3091 break;
TDYa127f71bf5a2012-07-29 20:09:52 -07003092 case greenland::IntrinsicHelper::HLThrowException:
buzbee0967a252012-09-14 10:43:54 -07003093 cvtThrow(cUnit, callInst);
3094 break;
3095 case greenland::IntrinsicHelper::MonitorEnter:
3096 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
3097 break;
3098 case greenland::IntrinsicHelper::MonitorExit:
3099 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
3100 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003101 case greenland::IntrinsicHelper::OptArrayLength:
buzbee0967a252012-09-14 10:43:54 -07003102 cvtArrayLength(cUnit, callInst);
3103 break;
3104 case greenland::IntrinsicHelper::NewArray:
3105 cvtNewArray(cUnit, callInst);
3106 break;
3107 case greenland::IntrinsicHelper::InstanceOf:
3108 cvtInstanceOf(cUnit, callInst);
3109 break;
3110
3111 case greenland::IntrinsicHelper::HLArrayGet:
3112 case greenland::IntrinsicHelper::HLArrayGetObject:
3113 case greenland::IntrinsicHelper::HLArrayGetFloat:
3114 cvtAget(cUnit, callInst, kWord, 2);
3115 break;
3116 case greenland::IntrinsicHelper::HLArrayGetWide:
3117 case greenland::IntrinsicHelper::HLArrayGetDouble:
3118 cvtAget(cUnit, callInst, kLong, 3);
3119 break;
3120 case greenland::IntrinsicHelper::HLArrayGetBoolean:
3121 cvtAget(cUnit, callInst, kUnsignedByte, 0);
3122 break;
3123 case greenland::IntrinsicHelper::HLArrayGetByte:
3124 cvtAget(cUnit, callInst, kSignedByte, 0);
3125 break;
3126 case greenland::IntrinsicHelper::HLArrayGetChar:
3127 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
3128 break;
3129 case greenland::IntrinsicHelper::HLArrayGetShort:
3130 cvtAget(cUnit, callInst, kSignedHalf, 1);
3131 break;
3132
3133 case greenland::IntrinsicHelper::HLArrayPut:
3134 case greenland::IntrinsicHelper::HLArrayPutFloat:
3135 cvtAputPrimitive(cUnit, callInst, kWord, 2);
3136 break;
3137 case greenland::IntrinsicHelper::HLArrayPutObject:
3138 cvtAputObj(cUnit, callInst);
3139 break;
3140 case greenland::IntrinsicHelper::HLArrayPutWide:
3141 case greenland::IntrinsicHelper::HLArrayPutDouble:
3142 cvtAputPrimitive(cUnit, callInst, kLong, 3);
3143 break;
3144 case greenland::IntrinsicHelper::HLArrayPutBoolean:
3145 cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
3146 break;
3147 case greenland::IntrinsicHelper::HLArrayPutByte:
3148 cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
3149 break;
3150 case greenland::IntrinsicHelper::HLArrayPutChar:
3151 cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
3152 break;
3153 case greenland::IntrinsicHelper::HLArrayPutShort:
3154 cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
3155 break;
3156
3157 case greenland::IntrinsicHelper::HLIGet:
3158 case greenland::IntrinsicHelper::HLIGetFloat:
3159 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3160 break;
3161 case greenland::IntrinsicHelper::HLIGetObject:
3162 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3163 break;
3164 case greenland::IntrinsicHelper::HLIGetWide:
3165 case greenland::IntrinsicHelper::HLIGetDouble:
3166 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3167 break;
3168 case greenland::IntrinsicHelper::HLIGetBoolean:
3169 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
3170 false /* obj */);
3171 break;
3172 case greenland::IntrinsicHelper::HLIGetByte:
3173 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
3174 false /* obj */);
3175 break;
3176 case greenland::IntrinsicHelper::HLIGetChar:
3177 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3178 false /* obj */);
3179 break;
3180 case greenland::IntrinsicHelper::HLIGetShort:
3181 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
3182 false /* obj */);
3183 break;
3184
3185 case greenland::IntrinsicHelper::HLIPut:
3186 case greenland::IntrinsicHelper::HLIPutFloat:
3187 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3188 break;
3189 case greenland::IntrinsicHelper::HLIPutObject:
3190 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3191 break;
3192 case greenland::IntrinsicHelper::HLIPutWide:
3193 case greenland::IntrinsicHelper::HLIPutDouble:
3194 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3195 break;
3196 case greenland::IntrinsicHelper::HLIPutBoolean:
3197 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3198 false /* obj */);
3199 break;
3200 case greenland::IntrinsicHelper::HLIPutByte:
3201 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3202 false /* obj */);
3203 break;
3204 case greenland::IntrinsicHelper::HLIPutChar:
3205 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3206 false /* obj */);
3207 break;
3208 case greenland::IntrinsicHelper::HLIPutShort:
3209 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3210 false /* obj */);
3211 break;
3212
3213 case greenland::IntrinsicHelper::IntToChar:
3214 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3215 break;
3216 case greenland::IntrinsicHelper::IntToShort:
3217 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3218 break;
3219 case greenland::IntrinsicHelper::IntToByte:
3220 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3221 break;
3222
TDYa1274ec8ccd2012-08-11 07:04:57 -07003223 case greenland::IntrinsicHelper::F2I:
3224 case greenland::IntrinsicHelper::D2I:
3225 case greenland::IntrinsicHelper::F2L:
3226 case greenland::IntrinsicHelper::D2L:
3227 cvtFPToInt(cUnit, callInst);
3228 break;
3229
buzbee0967a252012-09-14 10:43:54 -07003230 case greenland::IntrinsicHelper::CmplFloat:
3231 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3232 break;
3233 case greenland::IntrinsicHelper::CmpgFloat:
3234 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3235 break;
3236 case greenland::IntrinsicHelper::CmplDouble:
3237 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3238 break;
3239 case greenland::IntrinsicHelper::CmpgDouble:
3240 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3241 break;
3242
3243 case greenland::IntrinsicHelper::CmpLong:
3244 cvtLongCompare(cUnit, callInst);
3245 break;
3246
3247 case greenland::IntrinsicHelper::SHLLong:
3248 cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
3249 break;
3250 case greenland::IntrinsicHelper::SHRLong:
3251 cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
3252 break;
3253 case greenland::IntrinsicHelper::USHRLong:
3254 cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
3255 break;
3256 case greenland::IntrinsicHelper::SHLInt:
3257 cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
3258 break;
3259 case greenland::IntrinsicHelper::SHRInt:
3260 cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
3261 break;
3262 case greenland::IntrinsicHelper::USHRInt:
3263 cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
3264 break;
3265
3266 case greenland::IntrinsicHelper::CatchTargets: {
3267 llvm::SwitchInst* swInst =
3268 llvm::dyn_cast<llvm::SwitchInst>(nextIt);
3269 DCHECK(swInst != NULL);
3270 /*
3271 * Discard the edges and the following conditional branch.
3272 * Do a direct branch to the default target (which is the
3273 * "work" portion of the pair.
3274 * TODO: awful code layout - rework
3275 */
3276 llvm::BasicBlock* targetBB = swInst->getDefaultDest();
3277 DCHECK(targetBB != NULL);
3278 opUnconditionalBranch(cUnit,
3279 cUnit->blockToLabelMap.Get(targetBB));
3280 ++it;
3281 // Set next bb to default target - improves code layout
3282 nextBB = targetBB;
3283 }
3284 break;
3285
3286 default:
3287 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
3288 << cUnit->intrinsic_helper->GetName(id);
3289 }
3290 }
3291 break;
3292
3293 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3294 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3295 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3296 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3297 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3298 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3299 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3300 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3301 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
3302 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3303 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
3304 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3305 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3306 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3307 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3308 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
3309 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003310 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3311 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3312 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
3313
3314 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3315 break;
3316 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3317 break;
3318
3319 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3320
3321 case llvm::Instruction::Unreachable:
3322 break; // FIXME: can we really ignore these?
3323
3324 case llvm::Instruction::Shl:
3325 case llvm::Instruction::LShr:
3326 case llvm::Instruction::AShr:
3327 case llvm::Instruction::Invoke:
3328 case llvm::Instruction::FPToUI:
TDYa1274ec8ccd2012-08-11 07:04:57 -07003329 case llvm::Instruction::FPToSI:
buzbee0967a252012-09-14 10:43:54 -07003330 case llvm::Instruction::UIToFP:
3331 case llvm::Instruction::PtrToInt:
3332 case llvm::Instruction::IntToPtr:
3333 case llvm::Instruction::FCmp:
3334 case llvm::Instruction::URem:
3335 case llvm::Instruction::UDiv:
3336 case llvm::Instruction::Resume:
3337 case llvm::Instruction::Alloca:
3338 case llvm::Instruction::GetElementPtr:
3339 case llvm::Instruction::Fence:
3340 case llvm::Instruction::AtomicCmpXchg:
3341 case llvm::Instruction::AtomicRMW:
3342 case llvm::Instruction::BitCast:
3343 case llvm::Instruction::VAArg:
3344 case llvm::Instruction::Select:
3345 case llvm::Instruction::UserOp1:
3346 case llvm::Instruction::UserOp2:
3347 case llvm::Instruction::ExtractElement:
3348 case llvm::Instruction::InsertElement:
3349 case llvm::Instruction::ShuffleVector:
3350 case llvm::Instruction::ExtractValue:
3351 case llvm::Instruction::InsertValue:
3352 case llvm::Instruction::LandingPad:
3353 case llvm::Instruction::IndirectBr:
3354 case llvm::Instruction::Load:
3355 case llvm::Instruction::Store:
3356 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3357
3358 default:
3359 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3360 break;
buzbeead8f15e2012-06-18 14:49:45 -07003361 }
3362 }
buzbee2cfc6392012-05-07 14:51:40 -07003363
buzbee0967a252012-09-14 10:43:54 -07003364 if (headLIR != NULL) {
3365 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
buzbee2cfc6392012-05-07 14:51:40 -07003366 }
buzbee0967a252012-09-14 10:43:54 -07003367 if (nextBB != NULL) {
3368 bb = nextBB;
3369 nextBB = NULL;
buzbee6969d502012-06-15 16:40:31 -07003370 }
buzbee6969d502012-06-15 16:40:31 -07003371 }
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
buzbee692be802012-08-29 15:52:59 -07003522 cUnit->func->eraseFromParent();
3523 cUnit->func = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07003524}
3525
3526
3527} // namespace art