blob: cf07ea45c3a62c2173672e8c02c0ef14877e2239 [file] [log] [blame]
buzbee2cfc6392012-05-07 14:51:40 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#if defined(ART_USE_QUICK_COMPILER)
buzbee2cfc6392012-05-07 14:51:40 -070018#include "object_utils.h"
19
20#include <llvm/Support/ToolOutputFile.h>
21#include <llvm/Bitcode/ReaderWriter.h>
22#include <llvm/Analysis/Verifier.h>
23#include <llvm/Metadata.h>
24#include <llvm/ADT/DepthFirstIterator.h>
25#include <llvm/Instruction.h>
26#include <llvm/Type.h>
27#include <llvm/Instructions.h>
28#include <llvm/Support/Casting.h>
buzbeead8f15e2012-06-18 14:49:45 -070029#include <llvm/Support/InstIterator.h>
buzbee2cfc6392012-05-07 14:51:40 -070030
buzbee8320f382012-09-11 16:29:42 -070031static const char* kLabelFormat = "%c0x%x_%d";
buzbee951c0a12012-10-03 16:31:39 -070032static const char kInvalidBlock = 0xff;
buzbee8320f382012-09-11 16:29:42 -070033static const char kNormalBlock = 'L';
34static const char kCatchBlock = 'C';
buzbee2cfc6392012-05-07 14:51:40 -070035
36namespace art {
37extern const RegLocation badLoc;
buzbeeb03f4872012-06-11 15:22:11 -070038RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val);
buzbee2cfc6392012-05-07 14:51:40 -070039
40llvm::BasicBlock* getLLVMBlock(CompilationUnit* cUnit, int id)
41{
42 return cUnit->idToBlockMap.Get(id);
43}
44
45llvm::Value* getLLVMValue(CompilationUnit* cUnit, int sReg)
46{
47 return (llvm::Value*)oatGrowableListGetElement(&cUnit->llvmValues, sReg);
48}
49
50// Replace the placeholder value with the real definition
51void defineValue(CompilationUnit* cUnit, llvm::Value* val, int sReg)
52{
53 llvm::Value* placeholder = getLLVMValue(cUnit, sReg);
buzbee9a2487f2012-07-26 14:01:13 -070054 if (placeholder == NULL) {
55 // This can happen on instruction rewrite on verification failure
Bill Buzbeec9f40dd2012-08-15 11:35:25 -070056 LOG(WARNING) << "Null placeholder";
buzbee9a2487f2012-07-26 14:01:13 -070057 return;
58 }
buzbee2cfc6392012-05-07 14:51:40 -070059 placeholder->replaceAllUsesWith(val);
60 val->takeName(placeholder);
61 cUnit->llvmValues.elemList[sReg] = (intptr_t)val;
buzbee4be777b2012-07-12 14:38:18 -070062 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(placeholder);
63 DCHECK(inst != NULL);
64 inst->eraseFromParent();
buzbee2cfc6392012-05-07 14:51:40 -070065}
66
67llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc)
68{
69 llvm::Type* res = NULL;
70 if (loc.wide) {
71 if (loc.fp)
buzbee4f1181f2012-06-22 13:52:12 -070072 res = cUnit->irb->getDoubleTy();
buzbee2cfc6392012-05-07 14:51:40 -070073 else
buzbee4f1181f2012-06-22 13:52:12 -070074 res = cUnit->irb->getInt64Ty();
buzbee2cfc6392012-05-07 14:51:40 -070075 } else {
76 if (loc.fp) {
buzbee4f1181f2012-06-22 13:52:12 -070077 res = cUnit->irb->getFloatTy();
buzbee2cfc6392012-05-07 14:51:40 -070078 } else {
79 if (loc.ref)
80 res = cUnit->irb->GetJObjectTy();
81 else
buzbee4f1181f2012-06-22 13:52:12 -070082 res = cUnit->irb->getInt32Ty();
buzbee2cfc6392012-05-07 14:51:40 -070083 }
84 }
85 return res;
86}
87
buzbeead8f15e2012-06-18 14:49:45 -070088/* Create an in-memory RegLocation from an llvm Value. */
89void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val)
90{
91 // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
92 std::string s(val->getName().str());
93 const char* valName = s.c_str();
buzbeead8f15e2012-06-18 14:49:45 -070094 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
95 DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName;
96 int baseSReg = INVALID_SREG;
97 int subscript = -1;
98 sscanf(valName, "v%d_%d", &baseSReg, &subscript);
99 if ((baseSReg == INVALID_SREG) && (!strcmp(valName, "method"))) {
100 baseSReg = SSA_METHOD_BASEREG;
101 subscript = 0;
102 }
buzbeead8f15e2012-06-18 14:49:45 -0700103 DCHECK_NE(baseSReg, INVALID_SREG);
104 DCHECK_NE(subscript, -1);
105 // TODO: redo during C++'ification
106 RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
107 INVALID_REG, INVALID_SREG, INVALID_SREG};
108 llvm::Type* ty = val->getType();
109 loc.wide = ((ty == cUnit->irb->getInt64Ty()) ||
110 (ty == cUnit->irb->getDoubleTy()));
111 loc.defined = true;
buzbeeca7a5e42012-08-20 11:12:18 -0700112 loc.home = false; // May change during promotion
buzbeead8f15e2012-06-18 14:49:45 -0700113 loc.sRegLow = baseSReg;
114 loc.origSReg = cUnit->locMap.size();
buzbeeca7a5e42012-08-20 11:12:18 -0700115 PromotionMap pMap = cUnit->promotionMap[baseSReg];
116 if (ty == cUnit->irb->getFloatTy()) {
117 loc.fp = true;
118 if (pMap.fpLocation == kLocPhysReg) {
119 loc.lowReg = pMap.fpReg;
120 loc.location = kLocPhysReg;
121 loc.home = true;
122 }
123 } else if (ty == cUnit->irb->getDoubleTy()) {
124 loc.fp = true;
125 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
126 if ((pMap.fpLocation == kLocPhysReg) &&
127 (pMapHigh.fpLocation == kLocPhysReg) &&
128 ((pMap.fpReg & 0x1) == 0) &&
129 (pMap.fpReg + 1 == pMapHigh.fpReg)) {
130 loc.lowReg = pMap.fpReg;
131 loc.highReg = pMapHigh.fpReg;
132 loc.location = kLocPhysReg;
133 loc.home = true;
134 }
135 } else if (ty == cUnit->irb->GetJObjectTy()) {
136 loc.ref = true;
137 if (pMap.coreLocation == kLocPhysReg) {
138 loc.lowReg = pMap.coreReg;
139 loc.location = kLocPhysReg;
140 loc.home = true;
141 }
142 } else if (ty == cUnit->irb->getInt64Ty()) {
143 loc.core = true;
144 PromotionMap pMapHigh = cUnit->promotionMap[baseSReg + 1];
145 if ((pMap.coreLocation == kLocPhysReg) &&
146 (pMapHigh.coreLocation == kLocPhysReg)) {
147 loc.lowReg = pMap.coreReg;
148 loc.highReg = pMapHigh.coreReg;
149 loc.location = kLocPhysReg;
150 loc.home = true;
151 }
152 } else {
153 loc.core = true;
154 if (pMap.coreLocation == kLocPhysReg) {
155 loc.lowReg = pMap.coreReg;
156 loc.location = kLocPhysReg;
157 loc.home = true;
158 }
159 }
160
161 if (cUnit->printMe && loc.home) {
162 if (loc.wide) {
buzbee0967a252012-09-14 10:43:54 -0700163 LOG(INFO) << "Promoted wide " << s << " to regs " << static_cast<int>(loc.lowReg)
buzbeeca7a5e42012-08-20 11:12:18 -0700164 << "/" << loc.highReg;
165 } else {
buzbee0967a252012-09-14 10:43:54 -0700166 LOG(INFO) << "Promoted " << s << " to reg " << static_cast<int>(loc.lowReg);
buzbeeca7a5e42012-08-20 11:12:18 -0700167 }
168 }
buzbeead8f15e2012-06-18 14:49:45 -0700169 cUnit->locMap.Put(val, loc);
170}
buzbee2cfc6392012-05-07 14:51:40 -0700171void initIR(CompilationUnit* cUnit)
172{
buzbee4df2bbd2012-10-11 14:46:06 -0700173 LLVMInfo* llvmInfo = cUnit->llvm_info;
174 if (llvmInfo == NULL) {
175 CompilerTls* tls = cUnit->compiler->GetTls();
176 CHECK(tls != NULL);
177 llvmInfo = static_cast<LLVMInfo*>(tls->GetLLVMInfo());
178 if (llvmInfo == NULL) {
179 llvmInfo = new LLVMInfo();
180 tls->SetLLVMInfo(llvmInfo);
181 }
182 }
183 cUnit->context = llvmInfo->GetLLVMContext();
184 cUnit->module = llvmInfo->GetLLVMModule();
185 cUnit->intrinsic_helper = llvmInfo->GetIntrinsicHelper();
186 cUnit->irb = llvmInfo->GetIRBuilder();
buzbee2cfc6392012-05-07 14:51:40 -0700187}
188
189const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
190 return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
191}
192
buzbeef58c12c2012-07-03 15:06:29 -0700193llvm::BasicBlock* findCaseTarget(CompilationUnit* cUnit, uint32_t vaddr)
194{
195 BasicBlock* bb = oatFindBlock(cUnit, vaddr);
196 DCHECK(bb != NULL);
197 return getLLVMBlock(cUnit, bb->id);
198}
199
200void convertPackedSwitch(CompilationUnit* cUnit, BasicBlock* bb,
201 int32_t tableOffset, RegLocation rlSrc)
202{
203 const Instruction::PackedSwitchPayload* payload =
204 reinterpret_cast<const Instruction::PackedSwitchPayload*>(
205 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
206
207 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
208
209 llvm::SwitchInst* sw =
210 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
211 payload->case_count);
212
213 for (uint16_t i = 0; i < payload->case_count; ++i) {
214 llvm::BasicBlock* llvmBB =
215 findCaseTarget(cUnit, cUnit->currentDalvikOffset + payload->targets[i]);
216 sw->addCase(cUnit->irb->getInt32(payload->first_key + i), llvmBB);
217 }
218 llvm::MDNode* switchNode =
219 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
220 sw->setMetadata("SwitchTable", switchNode);
221 bb->taken = NULL;
222 bb->fallThrough = NULL;
223}
224
buzbeea1da8a52012-07-09 14:00:21 -0700225void convertSparseSwitch(CompilationUnit* cUnit, BasicBlock* bb,
226 int32_t tableOffset, RegLocation rlSrc)
227{
228 const Instruction::SparseSwitchPayload* payload =
229 reinterpret_cast<const Instruction::SparseSwitchPayload*>(
230 cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
231
232 const int32_t* keys = payload->GetKeys();
233 const int32_t* targets = payload->GetTargets();
234
235 llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
236
237 llvm::SwitchInst* sw =
238 cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
239 payload->case_count);
240
241 for (size_t i = 0; i < payload->case_count; ++i) {
242 llvm::BasicBlock* llvmBB =
243 findCaseTarget(cUnit, cUnit->currentDalvikOffset + targets[i]);
244 sw->addCase(cUnit->irb->getInt32(keys[i]), llvmBB);
245 }
246 llvm::MDNode* switchNode =
247 llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
248 sw->setMetadata("SwitchTable", switchNode);
249 bb->taken = NULL;
250 bb->fallThrough = NULL;
251}
252
buzbee8fa0fda2012-06-27 15:44:52 -0700253void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
254 greenland::IntrinsicHelper::IntrinsicId id,
255 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700256{
buzbee8fa0fda2012-06-27 15:44:52 -0700257 llvm::Constant* fieldIdx = cUnit->irb->getInt32(fieldIndex);
buzbee4f1181f2012-06-22 13:52:12 -0700258 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee8fa0fda2012-06-27 15:44:52 -0700259 llvm::Value* res = cUnit->irb->CreateCall(intr, fieldIdx);
260 defineValue(cUnit, res, rlDest.origSReg);
261}
262
263void convertSput(CompilationUnit* cUnit, int32_t fieldIndex,
264 greenland::IntrinsicHelper::IntrinsicId id,
265 RegLocation rlSrc)
266{
267 llvm::SmallVector<llvm::Value*, 2> args;
268 args.push_back(cUnit->irb->getInt32(fieldIndex));
269 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
270 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
271 cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700272}
273
buzbee101305f2012-06-28 18:00:56 -0700274void convertFillArrayData(CompilationUnit* cUnit, int32_t offset,
275 RegLocation rlArray)
276{
277 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700278 id = greenland::IntrinsicHelper::HLFillArrayData;
buzbee101305f2012-06-28 18:00:56 -0700279 llvm::SmallVector<llvm::Value*, 2> args;
280 args.push_back(cUnit->irb->getInt32(offset));
281 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
282 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
283 cUnit->irb->CreateCall(intr, args);
284}
285
buzbee2cfc6392012-05-07 14:51:40 -0700286llvm::Value* emitConst(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
287 RegLocation loc)
288{
289 greenland::IntrinsicHelper::IntrinsicId id;
290 if (loc.wide) {
291 if (loc.fp) {
292 id = greenland::IntrinsicHelper::ConstDouble;
293 } else {
294 id = greenland::IntrinsicHelper::ConstLong;
295 }
296 } else {
297 if (loc.fp) {
298 id = greenland::IntrinsicHelper::ConstFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700299 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700300 id = greenland::IntrinsicHelper::ConstObj;
301 } else {
302 id = greenland::IntrinsicHelper::ConstInt;
303 }
304 }
305 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
306 return cUnit->irb->CreateCall(intr, src);
307}
buzbeeb03f4872012-06-11 15:22:11 -0700308
309void emitPopShadowFrame(CompilationUnit* cUnit)
310{
311 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
312 greenland::IntrinsicHelper::PopShadowFrame);
313 cUnit->irb->CreateCall(intr);
314}
315
buzbee2cfc6392012-05-07 14:51:40 -0700316llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
317 RegLocation loc)
318{
319 greenland::IntrinsicHelper::IntrinsicId id;
320 if (loc.wide) {
321 if (loc.fp) {
322 id = greenland::IntrinsicHelper::CopyDouble;
323 } else {
324 id = greenland::IntrinsicHelper::CopyLong;
325 }
326 } else {
327 if (loc.fp) {
328 id = greenland::IntrinsicHelper::CopyFloat;
buzbee4f1181f2012-06-22 13:52:12 -0700329 } else if (loc.ref) {
buzbee2cfc6392012-05-07 14:51:40 -0700330 id = greenland::IntrinsicHelper::CopyObj;
331 } else {
332 id = greenland::IntrinsicHelper::CopyInt;
333 }
334 }
335 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
336 return cUnit->irb->CreateCall(intr, src);
337}
338
buzbee32412962012-06-26 16:27:56 -0700339void convertMoveException(CompilationUnit* cUnit, RegLocation rlDest)
340{
341 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
342 greenland::IntrinsicHelper::GetException);
343 llvm::Value* res = cUnit->irb->CreateCall(func);
344 defineValue(cUnit, res, rlDest.origSReg);
345}
346
347void convertThrow(CompilationUnit* cUnit, RegLocation rlSrc)
348{
349 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
350 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
TDYa127f71bf5a2012-07-29 20:09:52 -0700351 greenland::IntrinsicHelper::HLThrowException);
buzbee32412962012-06-26 16:27:56 -0700352 cUnit->irb->CreateCall(func, src);
buzbee32412962012-06-26 16:27:56 -0700353}
354
buzbee8fa0fda2012-06-27 15:44:52 -0700355void convertMonitorEnterExit(CompilationUnit* cUnit, int optFlags,
356 greenland::IntrinsicHelper::IntrinsicId id,
357 RegLocation rlSrc)
358{
359 llvm::SmallVector<llvm::Value*, 2> args;
360 args.push_back(cUnit->irb->getInt32(optFlags));
361 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
362 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
363 cUnit->irb->CreateCall(func, args);
364}
365
buzbee76592632012-06-29 15:18:35 -0700366void convertArrayLength(CompilationUnit* cUnit, int optFlags,
367 RegLocation rlDest, RegLocation rlSrc)
buzbee8fa0fda2012-06-27 15:44:52 -0700368{
369 llvm::SmallVector<llvm::Value*, 2> args;
370 args.push_back(cUnit->irb->getInt32(optFlags));
371 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
372 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700373 greenland::IntrinsicHelper::OptArrayLength);
buzbee76592632012-06-29 15:18:35 -0700374 llvm::Value* res = cUnit->irb->CreateCall(func, args);
375 defineValue(cUnit, res, rlDest.origSReg);
buzbee8fa0fda2012-06-27 15:44:52 -0700376}
377
buzbee2cfc6392012-05-07 14:51:40 -0700378void emitSuspendCheck(CompilationUnit* cUnit)
379{
380 greenland::IntrinsicHelper::IntrinsicId id =
381 greenland::IntrinsicHelper::CheckSuspend;
382 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
383 cUnit->irb->CreateCall(intr);
384}
385
386llvm::Value* convertCompare(CompilationUnit* cUnit, ConditionCode cc,
387 llvm::Value* src1, llvm::Value* src2)
388{
389 llvm::Value* res = NULL;
buzbee76592632012-06-29 15:18:35 -0700390 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700391 switch(cc) {
392 case kCondEq: res = cUnit->irb->CreateICmpEQ(src1, src2); break;
393 case kCondNe: res = cUnit->irb->CreateICmpNE(src1, src2); break;
394 case kCondLt: res = cUnit->irb->CreateICmpSLT(src1, src2); break;
395 case kCondGe: res = cUnit->irb->CreateICmpSGE(src1, src2); break;
396 case kCondGt: res = cUnit->irb->CreateICmpSGT(src1, src2); break;
397 case kCondLe: res = cUnit->irb->CreateICmpSLE(src1, src2); break;
398 default: LOG(FATAL) << "Unexpected cc value " << cc;
399 }
400 return res;
401}
402
403void convertCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
404 ConditionCode cc, RegLocation rlSrc1,
405 RegLocation rlSrc2)
406{
407 if (bb->taken->startOffset <= mir->offset) {
408 emitSuspendCheck(cUnit);
409 }
410 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
411 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
412 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
413 condValue->setName(StringPrintf("t%d", cUnit->tempName++));
414 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
415 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700416 // Don't redo the fallthrough branch in the BB driver
417 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700418}
419
420void convertCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
421 MIR* mir, ConditionCode cc, RegLocation rlSrc1)
422{
423 if (bb->taken->startOffset <= mir->offset) {
424 emitSuspendCheck(cUnit);
425 }
426 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
427 llvm::Value* src2;
428 if (rlSrc1.ref) {
429 src2 = cUnit->irb->GetJNull();
430 } else {
431 src2 = cUnit->irb->getInt32(0);
432 }
433 llvm::Value* condValue = convertCompare(cUnit, cc, src1, src2);
buzbee2cfc6392012-05-07 14:51:40 -0700434 cUnit->irb->CreateCondBr(condValue, getLLVMBlock(cUnit, bb->taken->id),
435 getLLVMBlock(cUnit, bb->fallThrough->id));
buzbee6969d502012-06-15 16:40:31 -0700436 // Don't redo the fallthrough branch in the BB driver
437 bb->fallThrough = NULL;
buzbee2cfc6392012-05-07 14:51:40 -0700438}
439
440llvm::Value* genDivModOp(CompilationUnit* cUnit, bool isDiv, bool isLong,
441 llvm::Value* src1, llvm::Value* src2)
442{
443 greenland::IntrinsicHelper::IntrinsicId id;
444 if (isLong) {
445 if (isDiv) {
446 id = greenland::IntrinsicHelper::DivLong;
447 } else {
448 id = greenland::IntrinsicHelper::RemLong;
449 }
Logan Chien554e6072012-07-23 20:00:01 -0700450 } else {
451 if (isDiv) {
buzbee2cfc6392012-05-07 14:51:40 -0700452 id = greenland::IntrinsicHelper::DivInt;
453 } else {
454 id = greenland::IntrinsicHelper::RemInt;
Logan Chien554e6072012-07-23 20:00:01 -0700455 }
buzbee2cfc6392012-05-07 14:51:40 -0700456 }
457 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
458 llvm::SmallVector<llvm::Value*, 2>args;
459 args.push_back(src1);
460 args.push_back(src2);
461 return cUnit->irb->CreateCall(intr, args);
462}
463
464llvm::Value* genArithOp(CompilationUnit* cUnit, OpKind op, bool isLong,
465 llvm::Value* src1, llvm::Value* src2)
466{
467 llvm::Value* res = NULL;
468 switch(op) {
469 case kOpAdd: res = cUnit->irb->CreateAdd(src1, src2); break;
470 case kOpSub: res = cUnit->irb->CreateSub(src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700471 case kOpRsub: res = cUnit->irb->CreateSub(src2, src1); break;
buzbee2cfc6392012-05-07 14:51:40 -0700472 case kOpMul: res = cUnit->irb->CreateMul(src1, src2); break;
473 case kOpOr: res = cUnit->irb->CreateOr(src1, src2); break;
474 case kOpAnd: res = cUnit->irb->CreateAnd(src1, src2); break;
475 case kOpXor: res = cUnit->irb->CreateXor(src1, src2); break;
476 case kOpDiv: res = genDivModOp(cUnit, true, isLong, src1, src2); break;
477 case kOpRem: res = genDivModOp(cUnit, false, isLong, src1, src2); break;
buzbee4f1181f2012-06-22 13:52:12 -0700478 case kOpLsl: res = cUnit->irb->CreateShl(src1, src2); break;
479 case kOpLsr: res = cUnit->irb->CreateLShr(src1, src2); break;
480 case kOpAsr: res = cUnit->irb->CreateAShr(src1, src2); break;
buzbee2cfc6392012-05-07 14:51:40 -0700481 default:
482 LOG(FATAL) << "Invalid op " << op;
483 }
484 return res;
485}
486
487void convertFPArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
488 RegLocation rlSrc1, RegLocation rlSrc2)
489{
490 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
491 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
492 llvm::Value* res = NULL;
493 switch(op) {
494 case kOpAdd: res = cUnit->irb->CreateFAdd(src1, src2); break;
495 case kOpSub: res = cUnit->irb->CreateFSub(src1, src2); break;
496 case kOpMul: res = cUnit->irb->CreateFMul(src1, src2); break;
497 case kOpDiv: res = cUnit->irb->CreateFDiv(src1, src2); break;
498 case kOpRem: res = cUnit->irb->CreateFRem(src1, src2); break;
499 default:
500 LOG(FATAL) << "Invalid op " << op;
501 }
502 defineValue(cUnit, res, rlDest.origSReg);
503}
504
buzbee2a83e8f2012-07-13 16:42:30 -0700505void convertShift(CompilationUnit* cUnit,
506 greenland::IntrinsicHelper::IntrinsicId id,
507 RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2)
buzbee4f1181f2012-06-22 13:52:12 -0700508{
buzbee2a83e8f2012-07-13 16:42:30 -0700509 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
510 llvm::SmallVector<llvm::Value*, 2>args;
511 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
512 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
513 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
514 defineValue(cUnit, res, rlDest.origSReg);
515}
516
517void convertShiftLit(CompilationUnit* cUnit,
518 greenland::IntrinsicHelper::IntrinsicId id,
519 RegLocation rlDest, RegLocation rlSrc, int shiftAmount)
520{
521 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
522 llvm::SmallVector<llvm::Value*, 2>args;
523 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
524 args.push_back(cUnit->irb->getInt32(shiftAmount));
525 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
buzbee4f1181f2012-06-22 13:52:12 -0700526 defineValue(cUnit, res, rlDest.origSReg);
527}
528
buzbee2cfc6392012-05-07 14:51:40 -0700529void convertArithOp(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
530 RegLocation rlSrc1, RegLocation rlSrc2)
531{
532 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
533 llvm::Value* src2 = getLLVMValue(cUnit, rlSrc2.origSReg);
buzbee4f4dfc72012-07-02 14:54:44 -0700534 DCHECK_EQ(src1->getType(), src2->getType());
buzbee2cfc6392012-05-07 14:51:40 -0700535 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
536 defineValue(cUnit, res, rlDest.origSReg);
537}
538
buzbeeb03f4872012-06-11 15:22:11 -0700539void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
540{
541 int index = -1;
542 DCHECK(newVal != NULL);
543 int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
544 for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
545 if (cUnit->shadowMap[i] == vReg) {
546 index = i;
547 break;
548 }
549 }
TDYa127347166a2012-08-23 12:23:44 -0700550 if (index == -1) {
551 return;
552 }
buzbee6459e7c2012-10-02 14:42:41 -0700553 llvm::Type* ty = newVal->getType();
buzbeeb03f4872012-06-11 15:22:11 -0700554 greenland::IntrinsicHelper::IntrinsicId id =
555 greenland::IntrinsicHelper::SetShadowFrameEntry;
556 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
557 llvm::Value* tableSlot = cUnit->irb->getInt32(index);
buzbee6459e7c2012-10-02 14:42:41 -0700558 // If newVal is a Null pointer, we'll see it here as a const int. Replace
559 if (!ty->isPointerTy()) {
560 // TODO: assert newVal created w/ dex_lang_const_int(0) or dex_lang_const_float(0)
561 newVal = cUnit->irb->GetJNull();
562 }
buzbeeb03f4872012-06-11 15:22:11 -0700563 llvm::Value* args[] = { newVal, tableSlot };
564 cUnit->irb->CreateCall(func, args);
565}
566
buzbee2cfc6392012-05-07 14:51:40 -0700567void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
568 RegLocation rlSrc1, int32_t imm)
569{
570 llvm::Value* src1 = getLLVMValue(cUnit, rlSrc1.origSReg);
571 llvm::Value* src2 = cUnit->irb->getInt32(imm);
572 llvm::Value* res = genArithOp(cUnit, op, rlDest.wide, src1, src2);
573 defineValue(cUnit, res, rlDest.origSReg);
574}
575
buzbee101305f2012-06-28 18:00:56 -0700576/*
577 * Process arguments for invoke. Note: this code is also used to
578 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
579 * The requirements are similar.
580 */
buzbee6969d502012-06-15 16:40:31 -0700581void convertInvoke(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
buzbee76592632012-06-29 15:18:35 -0700582 InvokeType invokeType, bool isRange, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -0700583{
584 CallInfo* info = oatNewCallInfo(cUnit, bb, mir, invokeType, isRange);
585 llvm::SmallVector<llvm::Value*, 10> args;
586 // Insert the invokeType
587 args.push_back(cUnit->irb->getInt32(static_cast<int>(invokeType)));
588 // Insert the method_idx
589 args.push_back(cUnit->irb->getInt32(info->index));
590 // Insert the optimization flags
591 args.push_back(cUnit->irb->getInt32(info->optFlags));
592 // Now, insert the actual arguments
buzbee6969d502012-06-15 16:40:31 -0700593 for (int i = 0; i < info->numArgWords;) {
buzbee6969d502012-06-15 16:40:31 -0700594 llvm::Value* val = getLLVMValue(cUnit, info->args[i].origSReg);
595 args.push_back(val);
596 i += info->args[i].wide ? 2 : 1;
597 }
598 /*
599 * Choose the invoke return type based on actual usage. Note: may
600 * be different than shorty. For example, if a function return value
601 * is not used, we'll treat this as a void invoke.
602 */
603 greenland::IntrinsicHelper::IntrinsicId id;
buzbee76592632012-06-29 15:18:35 -0700604 if (isFilledNewArray) {
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700605 id = greenland::IntrinsicHelper::HLFilledNewArray;
buzbee101305f2012-06-28 18:00:56 -0700606 } else if (info->result.location == kLocInvalid) {
buzbee6969d502012-06-15 16:40:31 -0700607 id = greenland::IntrinsicHelper::HLInvokeVoid;
608 } else {
609 if (info->result.wide) {
610 if (info->result.fp) {
611 id = greenland::IntrinsicHelper::HLInvokeDouble;
612 } else {
buzbee8fa0fda2012-06-27 15:44:52 -0700613 id = greenland::IntrinsicHelper::HLInvokeLong;
buzbee6969d502012-06-15 16:40:31 -0700614 }
615 } else if (info->result.ref) {
616 id = greenland::IntrinsicHelper::HLInvokeObj;
617 } else if (info->result.fp) {
618 id = greenland::IntrinsicHelper::HLInvokeFloat;
619 } else {
620 id = greenland::IntrinsicHelper::HLInvokeInt;
621 }
622 }
623 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
624 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
625 if (info->result.location != kLocInvalid) {
626 defineValue(cUnit, res, info->result.origSReg);
TDYa127890ea892012-08-22 10:49:42 -0700627 if (info->result.ref) {
628 setShadowFrameEntry(cUnit, (llvm::Value*)
629 cUnit->llvmValues.elemList[info->result.origSReg]);
630 }
buzbee6969d502012-06-15 16:40:31 -0700631 }
632}
633
buzbee101305f2012-06-28 18:00:56 -0700634void convertConstObject(CompilationUnit* cUnit, uint32_t idx,
635 greenland::IntrinsicHelper::IntrinsicId id,
636 RegLocation rlDest)
buzbee6969d502012-06-15 16:40:31 -0700637{
buzbee6969d502012-06-15 16:40:31 -0700638 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee101305f2012-06-28 18:00:56 -0700639 llvm::Value* index = cUnit->irb->getInt32(idx);
buzbee6969d502012-06-15 16:40:31 -0700640 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
641 defineValue(cUnit, res, rlDest.origSReg);
642}
643
buzbee101305f2012-06-28 18:00:56 -0700644void convertCheckCast(CompilationUnit* cUnit, uint32_t type_idx,
645 RegLocation rlSrc)
646{
647 greenland::IntrinsicHelper::IntrinsicId id;
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700648 id = greenland::IntrinsicHelper::HLCheckCast;
buzbee101305f2012-06-28 18:00:56 -0700649 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
650 llvm::SmallVector<llvm::Value*, 2> args;
651 args.push_back(cUnit->irb->getInt32(type_idx));
652 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
653 cUnit->irb->CreateCall(intr, args);
654}
655
buzbee8fa0fda2012-06-27 15:44:52 -0700656void convertNewInstance(CompilationUnit* cUnit, uint32_t type_idx,
657 RegLocation rlDest)
buzbee4f1181f2012-06-22 13:52:12 -0700658{
659 greenland::IntrinsicHelper::IntrinsicId id;
660 id = greenland::IntrinsicHelper::NewInstance;
661 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
662 llvm::Value* index = cUnit->irb->getInt32(type_idx);
663 llvm::Value* res = cUnit->irb->CreateCall(intr, index);
664 defineValue(cUnit, res, rlDest.origSReg);
665}
666
buzbee8fa0fda2012-06-27 15:44:52 -0700667void convertNewArray(CompilationUnit* cUnit, uint32_t type_idx,
668 RegLocation rlDest, RegLocation rlSrc)
669{
670 greenland::IntrinsicHelper::IntrinsicId id;
671 id = greenland::IntrinsicHelper::NewArray;
672 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
673 llvm::SmallVector<llvm::Value*, 2> args;
674 args.push_back(cUnit->irb->getInt32(type_idx));
675 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
676 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
677 defineValue(cUnit, res, rlDest.origSReg);
678}
679
680void convertAget(CompilationUnit* cUnit, int optFlags,
681 greenland::IntrinsicHelper::IntrinsicId id,
682 RegLocation rlDest, RegLocation rlArray, RegLocation rlIndex)
683{
684 llvm::SmallVector<llvm::Value*, 3> args;
685 args.push_back(cUnit->irb->getInt32(optFlags));
686 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
687 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
688 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
689 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
690 defineValue(cUnit, res, rlDest.origSReg);
691}
692
693void convertAput(CompilationUnit* cUnit, int optFlags,
694 greenland::IntrinsicHelper::IntrinsicId id,
695 RegLocation rlSrc, RegLocation rlArray, RegLocation rlIndex)
696{
697 llvm::SmallVector<llvm::Value*, 4> args;
698 args.push_back(cUnit->irb->getInt32(optFlags));
699 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
700 args.push_back(getLLVMValue(cUnit, rlArray.origSReg));
701 args.push_back(getLLVMValue(cUnit, rlIndex.origSReg));
702 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
703 cUnit->irb->CreateCall(intr, args);
704}
705
buzbee101305f2012-06-28 18:00:56 -0700706void convertIget(CompilationUnit* cUnit, int optFlags,
707 greenland::IntrinsicHelper::IntrinsicId id,
708 RegLocation rlDest, RegLocation rlObj, int fieldIndex)
709{
710 llvm::SmallVector<llvm::Value*, 3> args;
711 args.push_back(cUnit->irb->getInt32(optFlags));
712 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
713 args.push_back(cUnit->irb->getInt32(fieldIndex));
714 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
715 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
716 defineValue(cUnit, res, rlDest.origSReg);
717}
718
719void convertIput(CompilationUnit* cUnit, int optFlags,
720 greenland::IntrinsicHelper::IntrinsicId id,
721 RegLocation rlSrc, RegLocation rlObj, int fieldIndex)
722{
723 llvm::SmallVector<llvm::Value*, 4> args;
724 args.push_back(cUnit->irb->getInt32(optFlags));
725 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
726 args.push_back(getLLVMValue(cUnit, rlObj.origSReg));
727 args.push_back(cUnit->irb->getInt32(fieldIndex));
728 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
729 cUnit->irb->CreateCall(intr, args);
730}
731
buzbee8fa0fda2012-06-27 15:44:52 -0700732void convertInstanceOf(CompilationUnit* cUnit, uint32_t type_idx,
733 RegLocation rlDest, RegLocation rlSrc)
734{
735 greenland::IntrinsicHelper::IntrinsicId id;
736 id = greenland::IntrinsicHelper::InstanceOf;
737 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
738 llvm::SmallVector<llvm::Value*, 2> args;
739 args.push_back(cUnit->irb->getInt32(type_idx));
740 args.push_back(getLLVMValue(cUnit, rlSrc.origSReg));
741 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
742 defineValue(cUnit, res, rlDest.origSReg);
743}
744
buzbee101305f2012-06-28 18:00:56 -0700745void convertIntToLong(CompilationUnit* cUnit, RegLocation rlDest,
746 RegLocation rlSrc)
747{
748 llvm::Value* res = cUnit->irb->CreateSExt(getLLVMValue(cUnit, rlSrc.origSReg),
749 cUnit->irb->getInt64Ty());
750 defineValue(cUnit, res, rlDest.origSReg);
751}
752
buzbee76592632012-06-29 15:18:35 -0700753void convertLongToInt(CompilationUnit* cUnit, RegLocation rlDest,
754 RegLocation rlSrc)
755{
756 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
757 llvm::Value* res = cUnit->irb->CreateTrunc(src, cUnit->irb->getInt32Ty());
758 defineValue(cUnit, res, rlDest.origSReg);
759}
760
761void convertFloatToDouble(CompilationUnit* cUnit, RegLocation rlDest,
762 RegLocation rlSrc)
763{
764 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
765 llvm::Value* res = cUnit->irb->CreateFPExt(src, cUnit->irb->getDoubleTy());
766 defineValue(cUnit, res, rlDest.origSReg);
767}
768
769void convertDoubleToFloat(CompilationUnit* cUnit, RegLocation rlDest,
770 RegLocation rlSrc)
771{
772 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
773 llvm::Value* res = cUnit->irb->CreateFPTrunc(src, cUnit->irb->getFloatTy());
774 defineValue(cUnit, res, rlDest.origSReg);
775}
776
777void convertWideComparison(CompilationUnit* cUnit,
778 greenland::IntrinsicHelper::IntrinsicId id,
779 RegLocation rlDest, RegLocation rlSrc1,
780 RegLocation rlSrc2)
781{
782 DCHECK_EQ(rlSrc1.fp, rlSrc2.fp);
783 DCHECK_EQ(rlSrc1.wide, rlSrc2.wide);
784 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
785 llvm::SmallVector<llvm::Value*, 2> args;
786 args.push_back(getLLVMValue(cUnit, rlSrc1.origSReg));
787 args.push_back(getLLVMValue(cUnit, rlSrc2.origSReg));
788 llvm::Value* res = cUnit->irb->CreateCall(intr, args);
789 defineValue(cUnit, res, rlDest.origSReg);
790}
791
buzbee101305f2012-06-28 18:00:56 -0700792void convertIntNarrowing(CompilationUnit* cUnit, RegLocation rlDest,
793 RegLocation rlSrc,
794 greenland::IntrinsicHelper::IntrinsicId id)
795{
796 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
buzbee76592632012-06-29 15:18:35 -0700797 llvm::Value* res =
798 cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
799 defineValue(cUnit, res, rlDest.origSReg);
800}
801
802void convertNeg(CompilationUnit* cUnit, RegLocation rlDest,
803 RegLocation rlSrc)
804{
805 llvm::Value* res = cUnit->irb->CreateNeg(getLLVMValue(cUnit, rlSrc.origSReg));
806 defineValue(cUnit, res, rlDest.origSReg);
807}
808
809void convertIntToFP(CompilationUnit* cUnit, llvm::Type* ty, RegLocation rlDest,
810 RegLocation rlSrc)
811{
812 llvm::Value* res =
813 cUnit->irb->CreateSIToFP(getLLVMValue(cUnit, rlSrc.origSReg), ty);
814 defineValue(cUnit, res, rlDest.origSReg);
815}
816
TDYa1274ec8ccd2012-08-11 07:04:57 -0700817void convertFPToInt(CompilationUnit* cUnit,
818 greenland::IntrinsicHelper::IntrinsicId id,
819 RegLocation rlDest,
buzbee76592632012-06-29 15:18:35 -0700820 RegLocation rlSrc)
821{
TDYa1274ec8ccd2012-08-11 07:04:57 -0700822 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
823 llvm::Value* res = cUnit->irb->CreateCall(intr, getLLVMValue(cUnit, rlSrc.origSReg));
buzbee76592632012-06-29 15:18:35 -0700824 defineValue(cUnit, res, rlDest.origSReg);
825}
826
827
828void convertNegFP(CompilationUnit* cUnit, RegLocation rlDest,
829 RegLocation rlSrc)
830{
831 llvm::Value* res =
832 cUnit->irb->CreateFNeg(getLLVMValue(cUnit, rlSrc.origSReg));
833 defineValue(cUnit, res, rlDest.origSReg);
834}
835
836void convertNot(CompilationUnit* cUnit, RegLocation rlDest,
837 RegLocation rlSrc)
838{
839 llvm::Value* src = getLLVMValue(cUnit, rlSrc.origSReg);
840 llvm::Value* res = cUnit->irb->CreateXor(src, static_cast<uint64_t>(-1));
buzbee101305f2012-06-28 18:00:56 -0700841 defineValue(cUnit, res, rlDest.origSReg);
842}
843
buzbee2cfc6392012-05-07 14:51:40 -0700844/*
845 * Target-independent code generation. Use only high-level
846 * load/store utilities here, or target-dependent genXX() handlers
847 * when necessary.
848 */
849bool convertMIRNode(CompilationUnit* cUnit, MIR* mir, BasicBlock* bb,
850 llvm::BasicBlock* llvmBB, LIR* labelList)
851{
852 bool res = false; // Assume success
853 RegLocation rlSrc[3];
854 RegLocation rlDest = badLoc;
buzbee2cfc6392012-05-07 14:51:40 -0700855 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee6969d502012-06-15 16:40:31 -0700856 uint32_t vB = mir->dalvikInsn.vB;
857 uint32_t vC = mir->dalvikInsn.vC;
buzbee8fa0fda2012-06-27 15:44:52 -0700858 int optFlags = mir->optimizationFlags;
buzbee6969d502012-06-15 16:40:31 -0700859
buzbeeb03f4872012-06-11 15:22:11 -0700860 bool objectDefinition = false;
buzbee2cfc6392012-05-07 14:51:40 -0700861
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700862 if (cUnit->printMe) {
863 if ((int)opcode < kMirOpFirst) {
864 LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x"
865 << std::hex << (int)opcode;
866 } else {
867 LOG(INFO) << ".. opcode 0x" << std::hex << (int)opcode;
868 }
869 }
870
buzbee2cfc6392012-05-07 14:51:40 -0700871 /* Prep Src and Dest locations */
872 int nextSreg = 0;
873 int nextLoc = 0;
874 int attrs = oatDataFlowAttributes[opcode];
875 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
876 if (attrs & DF_UA) {
877 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700878 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700879 nextSreg+= 2;
880 } else {
881 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
882 nextSreg++;
883 }
884 }
885 if (attrs & DF_UB) {
886 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700887 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700888 nextSreg+= 2;
889 } else {
890 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
891 nextSreg++;
892 }
893 }
894 if (attrs & DF_UC) {
895 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700896 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbee2cfc6392012-05-07 14:51:40 -0700897 } else {
898 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
899 }
900 }
901 if (attrs & DF_DA) {
902 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700903 rlDest = oatGetDestWide(cUnit, mir);
buzbee2cfc6392012-05-07 14:51:40 -0700904 } else {
buzbee15bf9802012-06-12 17:49:27 -0700905 rlDest = oatGetDest(cUnit, mir);
buzbeeb03f4872012-06-11 15:22:11 -0700906 if (rlDest.ref) {
907 objectDefinition = true;
908 }
buzbee2cfc6392012-05-07 14:51:40 -0700909 }
910 }
911
912 switch (opcode) {
913 case Instruction::NOP:
914 break;
915
916 case Instruction::MOVE:
917 case Instruction::MOVE_OBJECT:
918 case Instruction::MOVE_16:
919 case Instruction::MOVE_OBJECT_16:
buzbee76592632012-06-29 15:18:35 -0700920 case Instruction::MOVE_OBJECT_FROM16:
buzbee2cfc6392012-05-07 14:51:40 -0700921 case Instruction::MOVE_FROM16:
922 case Instruction::MOVE_WIDE:
923 case Instruction::MOVE_WIDE_16:
924 case Instruction::MOVE_WIDE_FROM16: {
925 /*
926 * Moves/copies are meaningless in pure SSA register form,
927 * but we need to preserve them for the conversion back into
928 * MIR (at least until we stop using the Dalvik register maps).
929 * Insert a dummy intrinsic copy call, which will be recognized
930 * by the quick path and removed by the portable path.
931 */
932 llvm::Value* src = getLLVMValue(cUnit, rlSrc[0].origSReg);
933 llvm::Value* res = emitCopy(cUnit, src, rlDest);
934 defineValue(cUnit, res, rlDest.origSReg);
935 }
936 break;
937
938 case Instruction::CONST:
939 case Instruction::CONST_4:
940 case Instruction::CONST_16: {
TDYa127347166a2012-08-23 12:23:44 -0700941 if (vB == 0) {
942 objectDefinition = true;
943 }
buzbee6969d502012-06-15 16:40:31 -0700944 llvm::Constant* immValue = cUnit->irb->GetJInt(vB);
buzbee2cfc6392012-05-07 14:51:40 -0700945 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
946 defineValue(cUnit, res, rlDest.origSReg);
947 }
948 break;
949
950 case Instruction::CONST_WIDE_16:
951 case Instruction::CONST_WIDE_32: {
buzbee76592632012-06-29 15:18:35 -0700952 // Sign extend to 64 bits
953 int64_t imm = static_cast<int32_t>(vB);
954 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
buzbee2cfc6392012-05-07 14:51:40 -0700955 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
956 defineValue(cUnit, res, rlDest.origSReg);
957 }
958 break;
959
960 case Instruction::CONST_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700961 llvm::Constant* immValue = cUnit->irb->GetJInt(vB << 16);
buzbee2cfc6392012-05-07 14:51:40 -0700962 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
963 defineValue(cUnit, res, rlDest.origSReg);
964 }
965 break;
966
967 case Instruction::CONST_WIDE: {
968 llvm::Constant* immValue =
969 cUnit->irb->GetJLong(mir->dalvikInsn.vB_wide);
970 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
971 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700972 }
973 break;
buzbee2cfc6392012-05-07 14:51:40 -0700974 case Instruction::CONST_WIDE_HIGH16: {
buzbee6969d502012-06-15 16:40:31 -0700975 int64_t imm = static_cast<int64_t>(vB) << 48;
buzbee2cfc6392012-05-07 14:51:40 -0700976 llvm::Constant* immValue = cUnit->irb->GetJLong(imm);
977 llvm::Value* res = emitConst(cUnit, immValue, rlDest);
978 defineValue(cUnit, res, rlDest.origSReg);
buzbee4f1181f2012-06-22 13:52:12 -0700979 }
980 break;
981
buzbee8fa0fda2012-06-27 15:44:52 -0700982 case Instruction::SPUT_OBJECT:
buzbee76592632012-06-29 15:18:35 -0700983 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputObject,
buzbee8fa0fda2012-06-27 15:44:52 -0700984 rlSrc[0]);
985 break;
986 case Instruction::SPUT:
987 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -0700988 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputFloat,
buzbee8fa0fda2012-06-27 15:44:52 -0700989 rlSrc[0]);
990 } else {
buzbee76592632012-06-29 15:18:35 -0700991 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSput, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -0700992 }
993 break;
994 case Instruction::SPUT_BOOLEAN:
buzbee76592632012-06-29 15:18:35 -0700995 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputBoolean,
buzbee8fa0fda2012-06-27 15:44:52 -0700996 rlSrc[0]);
997 break;
998 case Instruction::SPUT_BYTE:
buzbee76592632012-06-29 15:18:35 -0700999 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputByte, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001000 break;
1001 case Instruction::SPUT_CHAR:
buzbee76592632012-06-29 15:18:35 -07001002 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputChar, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001003 break;
1004 case Instruction::SPUT_SHORT:
buzbee76592632012-06-29 15:18:35 -07001005 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputShort, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001006 break;
1007 case Instruction::SPUT_WIDE:
1008 if (rlSrc[0].fp) {
buzbee76592632012-06-29 15:18:35 -07001009 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputDouble,
buzbee8fa0fda2012-06-27 15:44:52 -07001010 rlSrc[0]);
1011 } else {
buzbee76592632012-06-29 15:18:35 -07001012 convertSput(cUnit, vB, greenland::IntrinsicHelper::HLSputWide,
buzbee8fa0fda2012-06-27 15:44:52 -07001013 rlSrc[0]);
1014 }
1015 break;
1016
1017 case Instruction::SGET_OBJECT:
1018 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetObject, rlDest);
1019 break;
1020 case Instruction::SGET:
1021 if (rlDest.fp) {
1022 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetFloat, rlDest);
1023 } else {
1024 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSget, rlDest);
1025 }
1026 break;
1027 case Instruction::SGET_BOOLEAN:
1028 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetBoolean, rlDest);
1029 break;
1030 case Instruction::SGET_BYTE:
1031 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetByte, rlDest);
1032 break;
1033 case Instruction::SGET_CHAR:
1034 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetChar, rlDest);
1035 break;
1036 case Instruction::SGET_SHORT:
1037 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetShort, rlDest);
1038 break;
1039 case Instruction::SGET_WIDE:
1040 if (rlDest.fp) {
1041 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetDouble,
1042 rlDest);
1043 } else {
1044 convertSget(cUnit, vB, greenland::IntrinsicHelper::HLSgetWide, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001045 }
1046 break;
buzbee2cfc6392012-05-07 14:51:40 -07001047
1048 case Instruction::RETURN_WIDE:
1049 case Instruction::RETURN:
1050 case Instruction::RETURN_OBJECT: {
TDYa1274f2935e2012-06-22 06:25:03 -07001051 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001052 emitSuspendCheck(cUnit);
1053 }
buzbeeb03f4872012-06-11 15:22:11 -07001054 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001055 cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
1056 bb->hasReturn = true;
1057 }
1058 break;
1059
1060 case Instruction::RETURN_VOID: {
TDYa1274f2935e2012-06-22 06:25:03 -07001061 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee2cfc6392012-05-07 14:51:40 -07001062 emitSuspendCheck(cUnit);
1063 }
buzbeeb03f4872012-06-11 15:22:11 -07001064 emitPopShadowFrame(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07001065 cUnit->irb->CreateRetVoid();
1066 bb->hasReturn = true;
1067 }
1068 break;
1069
1070 case Instruction::IF_EQ:
1071 convertCompareAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0], rlSrc[1]);
1072 break;
1073 case Instruction::IF_NE:
1074 convertCompareAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0], rlSrc[1]);
1075 break;
1076 case Instruction::IF_LT:
1077 convertCompareAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0], rlSrc[1]);
1078 break;
1079 case Instruction::IF_GE:
1080 convertCompareAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0], rlSrc[1]);
1081 break;
1082 case Instruction::IF_GT:
1083 convertCompareAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0], rlSrc[1]);
1084 break;
1085 case Instruction::IF_LE:
1086 convertCompareAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0], rlSrc[1]);
1087 break;
1088 case Instruction::IF_EQZ:
1089 convertCompareZeroAndBranch(cUnit, bb, mir, kCondEq, rlSrc[0]);
1090 break;
1091 case Instruction::IF_NEZ:
1092 convertCompareZeroAndBranch(cUnit, bb, mir, kCondNe, rlSrc[0]);
1093 break;
1094 case Instruction::IF_LTZ:
1095 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLt, rlSrc[0]);
1096 break;
1097 case Instruction::IF_GEZ:
1098 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGe, rlSrc[0]);
1099 break;
1100 case Instruction::IF_GTZ:
1101 convertCompareZeroAndBranch(cUnit, bb, mir, kCondGt, rlSrc[0]);
1102 break;
1103 case Instruction::IF_LEZ:
1104 convertCompareZeroAndBranch(cUnit, bb, mir, kCondLe, rlSrc[0]);
1105 break;
1106
1107 case Instruction::GOTO:
1108 case Instruction::GOTO_16:
1109 case Instruction::GOTO_32: {
1110 if (bb->taken->startOffset <= bb->startOffset) {
1111 emitSuspendCheck(cUnit);
1112 }
1113 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->taken->id));
1114 }
1115 break;
1116
1117 case Instruction::ADD_LONG:
1118 case Instruction::ADD_LONG_2ADDR:
1119 case Instruction::ADD_INT:
1120 case Instruction::ADD_INT_2ADDR:
1121 convertArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1122 break;
1123 case Instruction::SUB_LONG:
1124 case Instruction::SUB_LONG_2ADDR:
1125 case Instruction::SUB_INT:
1126 case Instruction::SUB_INT_2ADDR:
1127 convertArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1128 break;
1129 case Instruction::MUL_LONG:
1130 case Instruction::MUL_LONG_2ADDR:
1131 case Instruction::MUL_INT:
1132 case Instruction::MUL_INT_2ADDR:
1133 convertArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1134 break;
1135 case Instruction::DIV_LONG:
1136 case Instruction::DIV_LONG_2ADDR:
1137 case Instruction::DIV_INT:
1138 case Instruction::DIV_INT_2ADDR:
1139 convertArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1140 break;
1141 case Instruction::REM_LONG:
1142 case Instruction::REM_LONG_2ADDR:
1143 case Instruction::REM_INT:
1144 case Instruction::REM_INT_2ADDR:
1145 convertArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1146 break;
1147 case Instruction::AND_LONG:
1148 case Instruction::AND_LONG_2ADDR:
1149 case Instruction::AND_INT:
1150 case Instruction::AND_INT_2ADDR:
1151 convertArithOp(cUnit, kOpAnd, rlDest, rlSrc[0], rlSrc[1]);
1152 break;
1153 case Instruction::OR_LONG:
1154 case Instruction::OR_LONG_2ADDR:
1155 case Instruction::OR_INT:
1156 case Instruction::OR_INT_2ADDR:
1157 convertArithOp(cUnit, kOpOr, rlDest, rlSrc[0], rlSrc[1]);
1158 break;
1159 case Instruction::XOR_LONG:
1160 case Instruction::XOR_LONG_2ADDR:
1161 case Instruction::XOR_INT:
1162 case Instruction::XOR_INT_2ADDR:
1163 convertArithOp(cUnit, kOpXor, rlDest, rlSrc[0], rlSrc[1]);
1164 break;
1165 case Instruction::SHL_LONG:
1166 case Instruction::SHL_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001167 convertShift(cUnit, greenland::IntrinsicHelper::SHLLong,
1168 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001169 break;
buzbee2cfc6392012-05-07 14:51:40 -07001170 case Instruction::SHL_INT:
1171 case Instruction::SHL_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001172 convertShift(cUnit, greenland::IntrinsicHelper::SHLInt,
1173 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001174 break;
1175 case Instruction::SHR_LONG:
1176 case Instruction::SHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001177 convertShift(cUnit, greenland::IntrinsicHelper::SHRLong,
1178 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001179 break;
buzbee2cfc6392012-05-07 14:51:40 -07001180 case Instruction::SHR_INT:
1181 case Instruction::SHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001182 convertShift(cUnit, greenland::IntrinsicHelper::SHRInt,
1183 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001184 break;
1185 case Instruction::USHR_LONG:
1186 case Instruction::USHR_LONG_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001187 convertShift(cUnit, greenland::IntrinsicHelper::USHRLong,
1188 rlDest, rlSrc[0], rlSrc[1]);
buzbee4f1181f2012-06-22 13:52:12 -07001189 break;
buzbee2cfc6392012-05-07 14:51:40 -07001190 case Instruction::USHR_INT:
1191 case Instruction::USHR_INT_2ADDR:
buzbee2a83e8f2012-07-13 16:42:30 -07001192 convertShift(cUnit, greenland::IntrinsicHelper::USHRInt,
1193 rlDest, rlSrc[0], rlSrc[1]);
buzbee2cfc6392012-05-07 14:51:40 -07001194 break;
1195
1196 case Instruction::ADD_INT_LIT16:
1197 case Instruction::ADD_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001198 convertArithOpLit(cUnit, kOpAdd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001199 break;
1200 case Instruction::RSUB_INT:
1201 case Instruction::RSUB_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001202 convertArithOpLit(cUnit, kOpRsub, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001203 break;
1204 case Instruction::MUL_INT_LIT16:
1205 case Instruction::MUL_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001206 convertArithOpLit(cUnit, kOpMul, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001207 break;
1208 case Instruction::DIV_INT_LIT16:
1209 case Instruction::DIV_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001210 convertArithOpLit(cUnit, kOpDiv, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001211 break;
1212 case Instruction::REM_INT_LIT16:
1213 case Instruction::REM_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001214 convertArithOpLit(cUnit, kOpRem, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001215 break;
1216 case Instruction::AND_INT_LIT16:
1217 case Instruction::AND_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001218 convertArithOpLit(cUnit, kOpAnd, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001219 break;
1220 case Instruction::OR_INT_LIT16:
1221 case Instruction::OR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001222 convertArithOpLit(cUnit, kOpOr, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001223 break;
1224 case Instruction::XOR_INT_LIT16:
1225 case Instruction::XOR_INT_LIT8:
buzbee6969d502012-06-15 16:40:31 -07001226 convertArithOpLit(cUnit, kOpXor, rlDest, rlSrc[0], vC);
buzbee2cfc6392012-05-07 14:51:40 -07001227 break;
1228 case Instruction::SHL_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001229 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHLInt,
1230 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001231 break;
1232 case Instruction::SHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001233 convertShiftLit(cUnit, greenland::IntrinsicHelper::SHRInt,
1234 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001235 break;
1236 case Instruction::USHR_INT_LIT8:
buzbee2a83e8f2012-07-13 16:42:30 -07001237 convertShiftLit(cUnit, greenland::IntrinsicHelper::USHRInt,
1238 rlDest, rlSrc[0], vC & 0x1f);
buzbee2cfc6392012-05-07 14:51:40 -07001239 break;
1240
1241 case Instruction::ADD_FLOAT:
1242 case Instruction::ADD_FLOAT_2ADDR:
1243 case Instruction::ADD_DOUBLE:
1244 case Instruction::ADD_DOUBLE_2ADDR:
1245 convertFPArithOp(cUnit, kOpAdd, rlDest, rlSrc[0], rlSrc[1]);
1246 break;
1247
1248 case Instruction::SUB_FLOAT:
1249 case Instruction::SUB_FLOAT_2ADDR:
1250 case Instruction::SUB_DOUBLE:
1251 case Instruction::SUB_DOUBLE_2ADDR:
1252 convertFPArithOp(cUnit, kOpSub, rlDest, rlSrc[0], rlSrc[1]);
1253 break;
1254
1255 case Instruction::MUL_FLOAT:
1256 case Instruction::MUL_FLOAT_2ADDR:
1257 case Instruction::MUL_DOUBLE:
1258 case Instruction::MUL_DOUBLE_2ADDR:
1259 convertFPArithOp(cUnit, kOpMul, rlDest, rlSrc[0], rlSrc[1]);
1260 break;
1261
1262 case Instruction::DIV_FLOAT:
1263 case Instruction::DIV_FLOAT_2ADDR:
1264 case Instruction::DIV_DOUBLE:
1265 case Instruction::DIV_DOUBLE_2ADDR:
1266 convertFPArithOp(cUnit, kOpDiv, rlDest, rlSrc[0], rlSrc[1]);
1267 break;
1268
1269 case Instruction::REM_FLOAT:
1270 case Instruction::REM_FLOAT_2ADDR:
1271 case Instruction::REM_DOUBLE:
1272 case Instruction::REM_DOUBLE_2ADDR:
1273 convertFPArithOp(cUnit, kOpRem, rlDest, rlSrc[0], rlSrc[1]);
1274 break;
1275
buzbee6969d502012-06-15 16:40:31 -07001276 case Instruction::INVOKE_STATIC:
buzbee101305f2012-06-28 18:00:56 -07001277 convertInvoke(cUnit, bb, mir, kStatic, false /*range*/,
1278 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001279 break;
1280 case Instruction::INVOKE_STATIC_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001281 convertInvoke(cUnit, bb, mir, kStatic, true /*range*/,
1282 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001283 break;
1284
1285 case Instruction::INVOKE_DIRECT:
buzbee101305f2012-06-28 18:00:56 -07001286 convertInvoke(cUnit, bb, mir, kDirect, false /*range*/,
1287 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001288 break;
1289 case Instruction::INVOKE_DIRECT_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001290 convertInvoke(cUnit, bb, mir, kDirect, true /*range*/,
1291 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001292 break;
1293
1294 case Instruction::INVOKE_VIRTUAL:
buzbee101305f2012-06-28 18:00:56 -07001295 convertInvoke(cUnit, bb, mir, kVirtual, false /*range*/,
1296 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001297 break;
1298 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001299 convertInvoke(cUnit, bb, mir, kVirtual, true /*range*/,
1300 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001301 break;
1302
1303 case Instruction::INVOKE_SUPER:
buzbee101305f2012-06-28 18:00:56 -07001304 convertInvoke(cUnit, bb, mir, kSuper, false /*range*/,
1305 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001306 break;
1307 case Instruction::INVOKE_SUPER_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001308 convertInvoke(cUnit, bb, mir, kSuper, true /*range*/,
1309 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001310 break;
1311
1312 case Instruction::INVOKE_INTERFACE:
buzbee101305f2012-06-28 18:00:56 -07001313 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1314 false /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001315 break;
1316 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee101305f2012-06-28 18:00:56 -07001317 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1318 false /* NewFilledArray */);
1319 break;
1320 case Instruction::FILLED_NEW_ARRAY:
1321 convertInvoke(cUnit, bb, mir, kInterface, false /*range*/,
1322 true /* NewFilledArray */);
1323 break;
1324 case Instruction::FILLED_NEW_ARRAY_RANGE:
1325 convertInvoke(cUnit, bb, mir, kInterface, true /*range*/,
1326 true /* NewFilledArray */);
buzbee6969d502012-06-15 16:40:31 -07001327 break;
1328
1329 case Instruction::CONST_STRING:
1330 case Instruction::CONST_STRING_JUMBO:
buzbee101305f2012-06-28 18:00:56 -07001331 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstString,
1332 rlDest);
1333 break;
1334
1335 case Instruction::CONST_CLASS:
1336 convertConstObject(cUnit, vB, greenland::IntrinsicHelper::ConstClass,
1337 rlDest);
1338 break;
1339
1340 case Instruction::CHECK_CAST:
1341 convertCheckCast(cUnit, vB, rlSrc[0]);
buzbee6969d502012-06-15 16:40:31 -07001342 break;
1343
buzbee4f1181f2012-06-22 13:52:12 -07001344 case Instruction::NEW_INSTANCE:
buzbee8fa0fda2012-06-27 15:44:52 -07001345 convertNewInstance(cUnit, vB, rlDest);
buzbee4f1181f2012-06-22 13:52:12 -07001346 break;
1347
buzbee32412962012-06-26 16:27:56 -07001348 case Instruction::MOVE_EXCEPTION:
1349 convertMoveException(cUnit, rlDest);
1350 break;
1351
1352 case Instruction::THROW:
1353 convertThrow(cUnit, rlSrc[0]);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001354 /*
1355 * If this throw is standalone, terminate.
1356 * If it might rethrow, force termination
1357 * of the following block.
1358 */
1359 if (bb->fallThrough == NULL) {
1360 cUnit->irb->CreateUnreachable();
1361 } else {
1362 bb->fallThrough->fallThrough = NULL;
1363 bb->fallThrough->taken = NULL;
1364 }
buzbee32412962012-06-26 16:27:56 -07001365 break;
1366
buzbee2cfc6392012-05-07 14:51:40 -07001367 case Instruction::MOVE_RESULT_WIDE:
buzbee2cfc6392012-05-07 14:51:40 -07001368 case Instruction::MOVE_RESULT:
1369 case Instruction::MOVE_RESULT_OBJECT:
buzbee9a2487f2012-07-26 14:01:13 -07001370 /*
jeffhao9a4f0032012-08-30 16:17:40 -07001371 * All move_results should have been folded into the preceeding invoke.
buzbee9a2487f2012-07-26 14:01:13 -07001372 */
jeffhao9a4f0032012-08-30 16:17:40 -07001373 LOG(FATAL) << "Unexpected move_result";
buzbee2cfc6392012-05-07 14:51:40 -07001374 break;
1375
1376 case Instruction::MONITOR_ENTER:
buzbee8fa0fda2012-06-27 15:44:52 -07001377 convertMonitorEnterExit(cUnit, optFlags,
1378 greenland::IntrinsicHelper::MonitorEnter,
1379 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001380 break;
1381
1382 case Instruction::MONITOR_EXIT:
buzbee8fa0fda2012-06-27 15:44:52 -07001383 convertMonitorEnterExit(cUnit, optFlags,
1384 greenland::IntrinsicHelper::MonitorExit,
1385 rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001386 break;
1387
1388 case Instruction::ARRAY_LENGTH:
buzbee76592632012-06-29 15:18:35 -07001389 convertArrayLength(cUnit, optFlags, rlDest, rlSrc[0]);
buzbee8fa0fda2012-06-27 15:44:52 -07001390 break;
1391
1392 case Instruction::NEW_ARRAY:
1393 convertNewArray(cUnit, vC, rlDest, rlSrc[0]);
1394 break;
1395
1396 case Instruction::INSTANCE_OF:
1397 convertInstanceOf(cUnit, vC, rlDest, rlSrc[0]);
1398 break;
1399
1400 case Instruction::AGET:
1401 if (rlDest.fp) {
1402 convertAget(cUnit, optFlags,
1403 greenland::IntrinsicHelper::HLArrayGetFloat,
1404 rlDest, rlSrc[0], rlSrc[1]);
1405 } else {
1406 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGet,
1407 rlDest, rlSrc[0], rlSrc[1]);
1408 }
1409 break;
1410 case Instruction::AGET_OBJECT:
1411 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetObject,
1412 rlDest, rlSrc[0], rlSrc[1]);
1413 break;
1414 case Instruction::AGET_BOOLEAN:
1415 convertAget(cUnit, optFlags,
1416 greenland::IntrinsicHelper::HLArrayGetBoolean,
1417 rlDest, rlSrc[0], rlSrc[1]);
1418 break;
1419 case Instruction::AGET_BYTE:
1420 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetByte,
1421 rlDest, rlSrc[0], rlSrc[1]);
1422 break;
1423 case Instruction::AGET_CHAR:
1424 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetChar,
1425 rlDest, rlSrc[0], rlSrc[1]);
1426 break;
1427 case Instruction::AGET_SHORT:
1428 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetShort,
1429 rlDest, rlSrc[0], rlSrc[1]);
1430 break;
1431 case Instruction::AGET_WIDE:
1432 if (rlDest.fp) {
1433 convertAget(cUnit, optFlags,
1434 greenland::IntrinsicHelper::HLArrayGetDouble,
1435 rlDest, rlSrc[0], rlSrc[1]);
1436 } else {
1437 convertAget(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayGetWide,
1438 rlDest, rlSrc[0], rlSrc[1]);
1439 }
1440 break;
1441
1442 case Instruction::APUT:
1443 if (rlSrc[0].fp) {
1444 convertAput(cUnit, optFlags,
1445 greenland::IntrinsicHelper::HLArrayPutFloat,
1446 rlSrc[0], rlSrc[1], rlSrc[2]);
1447 } else {
1448 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPut,
1449 rlSrc[0], rlSrc[1], rlSrc[2]);
1450 }
1451 break;
1452 case Instruction::APUT_OBJECT:
1453 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutObject,
1454 rlSrc[0], rlSrc[1], rlSrc[2]);
1455 break;
1456 case Instruction::APUT_BOOLEAN:
1457 convertAput(cUnit, optFlags,
1458 greenland::IntrinsicHelper::HLArrayPutBoolean,
1459 rlSrc[0], rlSrc[1], rlSrc[2]);
1460 break;
1461 case Instruction::APUT_BYTE:
1462 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutByte,
1463 rlSrc[0], rlSrc[1], rlSrc[2]);
1464 break;
1465 case Instruction::APUT_CHAR:
1466 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutChar,
1467 rlSrc[0], rlSrc[1], rlSrc[2]);
1468 break;
1469 case Instruction::APUT_SHORT:
1470 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutShort,
1471 rlSrc[0], rlSrc[1], rlSrc[2]);
1472 break;
1473 case Instruction::APUT_WIDE:
1474 if (rlSrc[0].fp) {
1475 convertAput(cUnit, optFlags,
1476 greenland::IntrinsicHelper::HLArrayPutDouble,
1477 rlSrc[0], rlSrc[1], rlSrc[2]);
1478 } else {
1479 convertAput(cUnit, optFlags, greenland::IntrinsicHelper::HLArrayPutWide,
1480 rlSrc[0], rlSrc[1], rlSrc[2]);
1481 }
1482 break;
1483
buzbee101305f2012-06-28 18:00:56 -07001484 case Instruction::IGET:
1485 if (rlDest.fp) {
1486 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetFloat,
buzbee4f4dfc72012-07-02 14:54:44 -07001487 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001488 } else {
1489 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGet,
buzbee4f4dfc72012-07-02 14:54:44 -07001490 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001491 }
buzbee2cfc6392012-05-07 14:51:40 -07001492 break;
buzbee101305f2012-06-28 18:00:56 -07001493 case Instruction::IGET_OBJECT:
1494 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetObject,
buzbee4f4dfc72012-07-02 14:54:44 -07001495 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001496 break;
1497 case Instruction::IGET_BOOLEAN:
1498 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetBoolean,
buzbee4f4dfc72012-07-02 14:54:44 -07001499 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001500 break;
1501 case Instruction::IGET_BYTE:
1502 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetByte,
buzbee4f4dfc72012-07-02 14:54:44 -07001503 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001504 break;
1505 case Instruction::IGET_CHAR:
1506 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetChar,
buzbee4f4dfc72012-07-02 14:54:44 -07001507 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001508 break;
1509 case Instruction::IGET_SHORT:
1510 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetShort,
buzbee4f4dfc72012-07-02 14:54:44 -07001511 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001512 break;
1513 case Instruction::IGET_WIDE:
1514 if (rlDest.fp) {
1515 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetDouble,
buzbee4f4dfc72012-07-02 14:54:44 -07001516 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001517 } else {
1518 convertIget(cUnit, optFlags, greenland::IntrinsicHelper::HLIGetWide,
buzbee4f4dfc72012-07-02 14:54:44 -07001519 rlDest, rlSrc[0], vC);
buzbee101305f2012-06-28 18:00:56 -07001520 }
1521 break;
1522 case Instruction::IPUT:
buzbee85eee022012-07-16 22:12:38 -07001523 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001524 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutFloat,
1525 rlSrc[0], rlSrc[1], vC);
1526 } else {
1527 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPut,
1528 rlSrc[0], rlSrc[1], vC);
1529 }
1530 break;
1531 case Instruction::IPUT_OBJECT:
1532 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutObject,
1533 rlSrc[0], rlSrc[1], vC);
1534 break;
1535 case Instruction::IPUT_BOOLEAN:
1536 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutBoolean,
1537 rlSrc[0], rlSrc[1], vC);
1538 break;
1539 case Instruction::IPUT_BYTE:
1540 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutByte,
1541 rlSrc[0], rlSrc[1], vC);
1542 break;
1543 case Instruction::IPUT_CHAR:
1544 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutChar,
1545 rlSrc[0], rlSrc[1], vC);
1546 break;
1547 case Instruction::IPUT_SHORT:
1548 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutShort,
1549 rlSrc[0], rlSrc[1], vC);
1550 break;
1551 case Instruction::IPUT_WIDE:
buzbee85eee022012-07-16 22:12:38 -07001552 if (rlSrc[0].fp) {
buzbee101305f2012-06-28 18:00:56 -07001553 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutDouble,
1554 rlSrc[0], rlSrc[1], vC);
1555 } else {
1556 convertIput(cUnit, optFlags, greenland::IntrinsicHelper::HLIPutWide,
1557 rlSrc[0], rlSrc[1], vC);
1558 }
buzbee2cfc6392012-05-07 14:51:40 -07001559 break;
1560
1561 case Instruction::FILL_ARRAY_DATA:
buzbee101305f2012-06-28 18:00:56 -07001562 convertFillArrayData(cUnit, vB, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001563 break;
1564
buzbee76592632012-06-29 15:18:35 -07001565 case Instruction::LONG_TO_INT:
1566 convertLongToInt(cUnit, rlDest, rlSrc[0]);
1567 break;
1568
buzbee101305f2012-06-28 18:00:56 -07001569 case Instruction::INT_TO_LONG:
1570 convertIntToLong(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001571 break;
1572
buzbee101305f2012-06-28 18:00:56 -07001573 case Instruction::INT_TO_CHAR:
1574 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1575 greenland::IntrinsicHelper::IntToChar);
1576 break;
1577 case Instruction::INT_TO_BYTE:
1578 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1579 greenland::IntrinsicHelper::IntToByte);
1580 break;
1581 case Instruction::INT_TO_SHORT:
1582 convertIntNarrowing(cUnit, rlDest, rlSrc[0],
1583 greenland::IntrinsicHelper::IntToShort);
1584 break;
1585
buzbee76592632012-06-29 15:18:35 -07001586 case Instruction::INT_TO_FLOAT:
1587 case Instruction::LONG_TO_FLOAT:
1588 convertIntToFP(cUnit, cUnit->irb->getFloatTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001589 break;
1590
buzbee76592632012-06-29 15:18:35 -07001591 case Instruction::INT_TO_DOUBLE:
1592 case Instruction::LONG_TO_DOUBLE:
1593 convertIntToFP(cUnit, cUnit->irb->getDoubleTy(), rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001594 break;
1595
buzbee76592632012-06-29 15:18:35 -07001596 case Instruction::FLOAT_TO_DOUBLE:
1597 convertFloatToDouble(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001598 break;
1599
buzbee76592632012-06-29 15:18:35 -07001600 case Instruction::DOUBLE_TO_FLOAT:
1601 convertDoubleToFloat(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001602 break;
1603
1604 case Instruction::NEG_LONG:
buzbee76592632012-06-29 15:18:35 -07001605 case Instruction::NEG_INT:
1606 convertNeg(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001607 break;
1608
1609 case Instruction::NEG_FLOAT:
buzbee2cfc6392012-05-07 14:51:40 -07001610 case Instruction::NEG_DOUBLE:
buzbee76592632012-06-29 15:18:35 -07001611 convertNegFP(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001612 break;
1613
buzbee76592632012-06-29 15:18:35 -07001614 case Instruction::NOT_LONG:
1615 case Instruction::NOT_INT:
1616 convertNot(cUnit, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001617 break;
1618
buzbee2cfc6392012-05-07 14:51:40 -07001619 case Instruction::FLOAT_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001620 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2I, rlDest, rlSrc[0]);
1621 break;
1622
buzbee2cfc6392012-05-07 14:51:40 -07001623 case Instruction::DOUBLE_TO_INT:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001624 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2I, rlDest, rlSrc[0]);
buzbee2cfc6392012-05-07 14:51:40 -07001625 break;
1626
buzbee76592632012-06-29 15:18:35 -07001627 case Instruction::FLOAT_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001628 convertFPToInt(cUnit, greenland::IntrinsicHelper::F2L, rlDest, rlSrc[0]);
1629 break;
1630
buzbee76592632012-06-29 15:18:35 -07001631 case Instruction::DOUBLE_TO_LONG:
TDYa1274ec8ccd2012-08-11 07:04:57 -07001632 convertFPToInt(cUnit, greenland::IntrinsicHelper::D2L, rlDest, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001633 break;
1634
1635 case Instruction::CMPL_FLOAT:
1636 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplFloat,
1637 rlDest, rlSrc[0], rlSrc[1]);
1638 break;
1639 case Instruction::CMPG_FLOAT:
1640 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgFloat,
1641 rlDest, rlSrc[0], rlSrc[1]);
1642 break;
1643 case Instruction::CMPL_DOUBLE:
1644 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmplDouble,
1645 rlDest, rlSrc[0], rlSrc[1]);
1646 break;
1647 case Instruction::CMPG_DOUBLE:
1648 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpgDouble,
1649 rlDest, rlSrc[0], rlSrc[1]);
1650 break;
1651 case Instruction::CMP_LONG:
1652 convertWideComparison(cUnit, greenland::IntrinsicHelper::CmpLong,
1653 rlDest, rlSrc[0], rlSrc[1]);
1654 break;
1655
buzbee76592632012-06-29 15:18:35 -07001656 case Instruction::PACKED_SWITCH:
buzbeef58c12c2012-07-03 15:06:29 -07001657 convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001658 break;
1659
1660 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -07001661 convertSparseSwitch(cUnit, bb, vB, rlSrc[0]);
buzbee76592632012-06-29 15:18:35 -07001662 break;
buzbee2cfc6392012-05-07 14:51:40 -07001663
1664 default:
buzbee32412962012-06-26 16:27:56 -07001665 UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
buzbee2cfc6392012-05-07 14:51:40 -07001666 res = true;
1667 }
buzbeeb03f4872012-06-11 15:22:11 -07001668 if (objectDefinition) {
1669 setShadowFrameEntry(cUnit, (llvm::Value*)
1670 cUnit->llvmValues.elemList[rlDest.origSReg]);
1671 }
buzbee2cfc6392012-05-07 14:51:40 -07001672 return res;
1673}
1674
1675/* Extended MIR instructions like PHI */
1676void convertExtendedMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1677 llvm::BasicBlock* llvmBB)
1678{
1679
1680 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
1681 case kMirOpPhi: {
buzbee2cfc6392012-05-07 14:51:40 -07001682 RegLocation rlDest = cUnit->regLocation[mir->ssaRep->defs[0]];
buzbee2a83e8f2012-07-13 16:42:30 -07001683 /*
1684 * The Art compiler's Phi nodes only handle 32-bit operands,
1685 * representing wide values using a matched set of Phi nodes
1686 * for the lower and upper halves. In the llvm world, we only
1687 * want a single Phi for wides. Here we will simply discard
1688 * the Phi node representing the high word.
1689 */
1690 if (rlDest.highWord) {
1691 return; // No Phi node - handled via low word
1692 }
1693 int* incoming = (int*)mir->dalvikInsn.vB;
buzbee2cfc6392012-05-07 14:51:40 -07001694 llvm::Type* phiType =
1695 llvmTypeFromLocRec(cUnit, rlDest);
1696 llvm::PHINode* phi = cUnit->irb->CreatePHI(phiType, mir->ssaRep->numUses);
1697 for (int i = 0; i < mir->ssaRep->numUses; i++) {
1698 RegLocation loc;
buzbee2a83e8f2012-07-13 16:42:30 -07001699 // Don't check width here.
1700 loc = oatGetRawSrc(cUnit, mir, i);
1701 DCHECK_EQ(rlDest.wide, loc.wide);
1702 DCHECK_EQ(rlDest.wide & rlDest.highWord, loc.wide & loc.highWord);
1703 DCHECK_EQ(rlDest.fp, loc.fp);
1704 DCHECK_EQ(rlDest.core, loc.core);
1705 DCHECK_EQ(rlDest.ref, loc.ref);
buzbeed1643e42012-09-05 14:06:51 -07001706 SafeMap<unsigned int, unsigned int>::iterator it;
1707 it = cUnit->blockIdMap.find(incoming[i]);
1708 DCHECK(it != cUnit->blockIdMap.end());
buzbee2cfc6392012-05-07 14:51:40 -07001709 phi->addIncoming(getLLVMValue(cUnit, loc.origSReg),
buzbeed1643e42012-09-05 14:06:51 -07001710 getLLVMBlock(cUnit, it->second));
buzbee2cfc6392012-05-07 14:51:40 -07001711 }
1712 defineValue(cUnit, phi, rlDest.origSReg);
1713 break;
1714 }
1715 case kMirOpCopy: {
1716 UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
1717 break;
1718 }
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001719 case kMirOpNop:
1720 if ((mir == bb->lastMIRInsn) && (bb->taken == NULL) &&
1721 (bb->fallThrough == NULL)) {
1722 cUnit->irb->CreateUnreachable();
1723 }
1724 break;
1725
buzbee2cfc6392012-05-07 14:51:40 -07001726#if defined(TARGET_ARM)
1727 case kMirOpFusedCmplFloat:
1728 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpFloat";
1729 break;
1730 case kMirOpFusedCmpgFloat:
1731 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmgFloat";
1732 break;
1733 case kMirOpFusedCmplDouble:
1734 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmplDouble";
1735 break;
1736 case kMirOpFusedCmpgDouble:
1737 UNIMPLEMENTED(WARNING) << "unimp kMirOpFusedCmpgDouble";
1738 break;
1739 case kMirOpFusedCmpLong:
1740 UNIMPLEMENTED(WARNING) << "unimp kMirOpLongCmpBranch";
1741 break;
1742#endif
1743 default:
1744 break;
1745 }
1746}
1747
1748void setDexOffset(CompilationUnit* cUnit, int32_t offset)
1749{
1750 cUnit->currentDalvikOffset = offset;
buzbee76592632012-06-29 15:18:35 -07001751 llvm::SmallVector<llvm::Value*, 1> arrayRef;
buzbee2cfc6392012-05-07 14:51:40 -07001752 arrayRef.push_back(cUnit->irb->getInt32(offset));
1753 llvm::MDNode* node = llvm::MDNode::get(*cUnit->context, arrayRef);
1754 cUnit->irb->SetDexOffset(node);
1755}
1756
1757// Attach method info as metadata to special intrinsic
1758void setMethodInfo(CompilationUnit* cUnit)
1759{
1760 // We don't want dex offset on this
1761 cUnit->irb->SetDexOffset(NULL);
1762 greenland::IntrinsicHelper::IntrinsicId id;
1763 id = greenland::IntrinsicHelper::MethodInfo;
1764 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1765 llvm::Instruction* inst = cUnit->irb->CreateCall(intr);
1766 llvm::SmallVector<llvm::Value*, 2> regInfo;
1767 regInfo.push_back(cUnit->irb->getInt32(cUnit->numIns));
1768 regInfo.push_back(cUnit->irb->getInt32(cUnit->numRegs));
1769 regInfo.push_back(cUnit->irb->getInt32(cUnit->numOuts));
1770 regInfo.push_back(cUnit->irb->getInt32(cUnit->numCompilerTemps));
1771 regInfo.push_back(cUnit->irb->getInt32(cUnit->numSSARegs));
1772 llvm::MDNode* regInfoNode = llvm::MDNode::get(*cUnit->context, regInfo);
1773 inst->setMetadata("RegInfo", regInfoNode);
1774 int promoSize = cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
1775 llvm::SmallVector<llvm::Value*, 50> pmap;
1776 for (int i = 0; i < promoSize; i++) {
1777 PromotionMap* p = &cUnit->promotionMap[i];
1778 int32_t mapData = ((p->firstInPair & 0xff) << 24) |
1779 ((p->fpReg & 0xff) << 16) |
1780 ((p->coreReg & 0xff) << 8) |
1781 ((p->fpLocation & 0xf) << 4) |
1782 (p->coreLocation & 0xf);
1783 pmap.push_back(cUnit->irb->getInt32(mapData));
1784 }
1785 llvm::MDNode* mapNode = llvm::MDNode::get(*cUnit->context, pmap);
1786 inst->setMetadata("PromotionMap", mapNode);
1787 setDexOffset(cUnit, cUnit->currentDalvikOffset);
1788}
1789
1790/* Handle the content in each basic block */
1791bool methodBlockBitcodeConversion(CompilationUnit* cUnit, BasicBlock* bb)
1792{
buzbeed1643e42012-09-05 14:06:51 -07001793 if (bb->blockType == kDead) return false;
buzbee2cfc6392012-05-07 14:51:40 -07001794 llvm::BasicBlock* llvmBB = getLLVMBlock(cUnit, bb->id);
buzbeef5f5a122012-09-21 13:57:36 -07001795 if (llvmBB == NULL) {
1796 CHECK(bb->blockType == kExitBlock);
1797 } else {
1798 cUnit->irb->SetInsertPoint(llvmBB);
1799 setDexOffset(cUnit, bb->startOffset);
1800 }
buzbee2cfc6392012-05-07 14:51:40 -07001801
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001802 if (cUnit->printMe) {
1803 LOG(INFO) << "................................";
1804 LOG(INFO) << "Block id " << bb->id;
1805 if (llvmBB != NULL) {
1806 LOG(INFO) << "label " << llvmBB->getName().str().c_str();
1807 } else {
1808 LOG(INFO) << "llvmBB is NULL";
1809 }
1810 }
1811
buzbee2cfc6392012-05-07 14:51:40 -07001812 if (bb->blockType == kEntryBlock) {
1813 setMethodInfo(cUnit);
buzbeeb03f4872012-06-11 15:22:11 -07001814 bool *canBeRef = (bool*) oatNew(cUnit, sizeof(bool) *
1815 cUnit->numDalvikRegisters, true,
1816 kAllocMisc);
1817 for (int i = 0; i < cUnit->numSSARegs; i++) {
buzbee6ec5e232012-09-20 15:50:03 -07001818 int vReg = SRegToVReg(cUnit, i);
1819 if (vReg > SSA_METHOD_BASEREG) {
1820 canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
1821 }
buzbeeb03f4872012-06-11 15:22:11 -07001822 }
1823 for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
1824 if (canBeRef[i]) {
1825 cUnit->numShadowFrameEntries++;
1826 }
1827 }
1828 if (cUnit->numShadowFrameEntries > 0) {
1829 cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
1830 cUnit->numShadowFrameEntries, true,
1831 kAllocMisc);
1832 for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
1833 if (canBeRef[i]) {
1834 cUnit->shadowMap[j++] = i;
1835 }
1836 }
buzbeeb03f4872012-06-11 15:22:11 -07001837 }
Shih-wei Liao569daf12012-08-10 23:22:33 -07001838 greenland::IntrinsicHelper::IntrinsicId id =
1839 greenland::IntrinsicHelper::AllocaShadowFrame;
1840 llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
1841 llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
1842 cUnit->irb->CreateCall(func, entries);
buzbee2cfc6392012-05-07 14:51:40 -07001843 } else if (bb->blockType == kExitBlock) {
1844 /*
1845 * Because of the differences between how MIR/LIR and llvm handle exit
1846 * blocks, we won't explicitly covert them. On the llvm-to-lir
1847 * path, it will need to be regenereated.
1848 */
1849 return false;
buzbee6969d502012-06-15 16:40:31 -07001850 } else if (bb->blockType == kExceptionHandling) {
1851 /*
1852 * Because we're deferring null checking, delete the associated empty
1853 * exception block.
buzbee6969d502012-06-15 16:40:31 -07001854 */
1855 llvmBB->eraseFromParent();
1856 return false;
buzbee2cfc6392012-05-07 14:51:40 -07001857 }
1858
1859 for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
1860
1861 setDexOffset(cUnit, mir->offset);
1862
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001863 int opcode = mir->dalvikInsn.opcode;
1864 Instruction::Format dalvikFormat =
1865 Instruction::FormatOf(mir->dalvikInsn.opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001866
1867 /* If we're compiling for the debugger, generate an update callout */
1868 if (cUnit->genDebugger) {
1869 UNIMPLEMENTED(FATAL) << "Need debug codegen";
1870 //genDebuggerUpdate(cUnit, mir->offset);
1871 }
1872
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001873 if (opcode == kMirOpCheck) {
1874 // Combine check and work halves of throwing instruction.
1875 MIR* workHalf = mir->meta.throwInsn;
1876 mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
1877 opcode = mir->dalvikInsn.opcode;
1878 SSARepresentation* ssaRep = workHalf->ssaRep;
1879 workHalf->ssaRep = mir->ssaRep;
1880 mir->ssaRep = ssaRep;
1881 workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
1882 if (bb->successorBlockList.blockListType == kCatch) {
1883 llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
1884 greenland::IntrinsicHelper::CatchTargets);
1885 llvm::Value* switchKey =
1886 cUnit->irb->CreateCall(intr, cUnit->irb->getInt32(mir->offset));
1887 GrowableListIterator iter;
1888 oatGrowableListIteratorInit(&bb->successorBlockList.blocks, &iter);
1889 // New basic block to use for work half
1890 llvm::BasicBlock* workBB =
1891 llvm::BasicBlock::Create(*cUnit->context, "", cUnit->func);
1892 llvm::SwitchInst* sw =
1893 cUnit->irb->CreateSwitch(switchKey, workBB,
1894 bb->successorBlockList.blocks.numUsed);
1895 while (true) {
1896 SuccessorBlockInfo *successorBlockInfo =
1897 (SuccessorBlockInfo *) oatGrowableListIteratorNext(&iter);
1898 if (successorBlockInfo == NULL) break;
1899 llvm::BasicBlock *target =
1900 getLLVMBlock(cUnit, successorBlockInfo->block->id);
1901 int typeIndex = successorBlockInfo->key;
1902 sw->addCase(cUnit->irb->getInt32(typeIndex), target);
1903 }
1904 llvmBB = workBB;
1905 cUnit->irb->SetInsertPoint(llvmBB);
1906 }
1907 }
1908
1909 if (opcode >= kMirOpFirst) {
buzbee2cfc6392012-05-07 14:51:40 -07001910 convertExtendedMIR(cUnit, bb, mir, llvmBB);
1911 continue;
1912 }
1913
1914 bool notHandled = convertMIRNode(cUnit, mir, bb, llvmBB,
1915 NULL /* labelList */);
1916 if (notHandled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001917 Instruction::Code dalvikOpcode = static_cast<Instruction::Code>(opcode);
buzbee2cfc6392012-05-07 14:51:40 -07001918 LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07001919 mir->offset, opcode,
buzbee2cfc6392012-05-07 14:51:40 -07001920 Instruction::Name(dalvikOpcode),
1921 dalvikFormat);
1922 }
1923 }
1924
buzbee4be777b2012-07-12 14:38:18 -07001925 if (bb->blockType == kEntryBlock) {
1926 cUnit->entryTargetBB = getLLVMBlock(cUnit, bb->fallThrough->id);
1927 } else if ((bb->fallThrough != NULL) && !bb->hasReturn) {
buzbee2cfc6392012-05-07 14:51:40 -07001928 cUnit->irb->CreateBr(getLLVMBlock(cUnit, bb->fallThrough->id));
1929 }
1930
1931 return false;
1932}
1933
buzbee4f4dfc72012-07-02 14:54:44 -07001934char remapShorty(char shortyType) {
1935 /*
1936 * TODO: might want to revisit this. Dalvik registers are 32-bits wide,
1937 * and longs/doubles are represented as a pair of registers. When sub-word
1938 * arguments (and method results) are passed, they are extended to Dalvik
1939 * virtual register containers. Because llvm is picky about type consistency,
1940 * we must either cast the "real" type to 32-bit container multiple Dalvik
1941 * register types, or always use the expanded values.
1942 * Here, we're doing the latter. We map the shorty signature to container
1943 * types (which is valid so long as we always do a real expansion of passed
1944 * arguments and field loads).
1945 */
1946 switch(shortyType) {
1947 case 'Z' : shortyType = 'I'; break;
1948 case 'B' : shortyType = 'I'; break;
1949 case 'S' : shortyType = 'I'; break;
1950 case 'C' : shortyType = 'I'; break;
1951 default: break;
1952 }
1953 return shortyType;
1954}
1955
buzbee2cfc6392012-05-07 14:51:40 -07001956llvm::FunctionType* getFunctionType(CompilationUnit* cUnit) {
1957
1958 // Get return type
buzbee4f4dfc72012-07-02 14:54:44 -07001959 llvm::Type* ret_type = cUnit->irb->GetJType(remapShorty(cUnit->shorty[0]),
buzbee2cfc6392012-05-07 14:51:40 -07001960 greenland::kAccurate);
1961
1962 // Get argument type
1963 std::vector<llvm::Type*> args_type;
1964
1965 // method object
1966 args_type.push_back(cUnit->irb->GetJMethodTy());
1967
1968 // Do we have a "this"?
1969 if ((cUnit->access_flags & kAccStatic) == 0) {
1970 args_type.push_back(cUnit->irb->GetJObjectTy());
1971 }
1972
1973 for (uint32_t i = 1; i < strlen(cUnit->shorty); ++i) {
buzbee4f4dfc72012-07-02 14:54:44 -07001974 args_type.push_back(cUnit->irb->GetJType(remapShorty(cUnit->shorty[i]),
buzbee2cfc6392012-05-07 14:51:40 -07001975 greenland::kAccurate));
1976 }
1977
1978 return llvm::FunctionType::get(ret_type, args_type, false);
1979}
1980
1981bool createFunction(CompilationUnit* cUnit) {
1982 std::string func_name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file,
1983 /* with_signature */ false));
1984 llvm::FunctionType* func_type = getFunctionType(cUnit);
1985
1986 if (func_type == NULL) {
1987 return false;
1988 }
1989
1990 cUnit->func = llvm::Function::Create(func_type,
1991 llvm::Function::ExternalLinkage,
1992 func_name, cUnit->module);
1993
1994 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
1995 llvm::Function::arg_iterator arg_end(cUnit->func->arg_end());
1996
1997 arg_iter->setName("method");
1998 ++arg_iter;
1999
2000 int startSReg = cUnit->numRegs;
2001
2002 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
2003 arg_iter->setName(StringPrintf("v%i_0", startSReg));
2004 startSReg += cUnit->regLocation[startSReg].wide ? 2 : 1;
2005 }
2006
2007 return true;
2008}
2009
2010bool createLLVMBasicBlock(CompilationUnit* cUnit, BasicBlock* bb)
2011{
2012 // Skip the exit block
buzbeed1643e42012-09-05 14:06:51 -07002013 if ((bb->blockType == kDead) ||(bb->blockType == kExitBlock)) {
buzbee2cfc6392012-05-07 14:51:40 -07002014 cUnit->idToBlockMap.Put(bb->id, NULL);
2015 } else {
2016 int offset = bb->startOffset;
2017 bool entryBlock = (bb->blockType == kEntryBlock);
2018 llvm::BasicBlock* llvmBB =
2019 llvm::BasicBlock::Create(*cUnit->context, entryBlock ? "entry" :
buzbee8320f382012-09-11 16:29:42 -07002020 StringPrintf(kLabelFormat, bb->catchEntry ? kCatchBlock :
2021 kNormalBlock, offset, bb->id), cUnit->func);
buzbee2cfc6392012-05-07 14:51:40 -07002022 if (entryBlock) {
2023 cUnit->entryBB = llvmBB;
2024 cUnit->placeholderBB =
2025 llvm::BasicBlock::Create(*cUnit->context, "placeholder",
2026 cUnit->func);
2027 }
2028 cUnit->idToBlockMap.Put(bb->id, llvmBB);
2029 }
2030 return false;
2031}
2032
2033
2034/*
2035 * Convert MIR to LLVM_IR
2036 * o For each ssa name, create LLVM named value. Type these
2037 * appropriately, and ignore high half of wide and double operands.
2038 * o For each MIR basic block, create an LLVM basic block.
2039 * o Iterate through the MIR a basic block at a time, setting arguments
2040 * to recovered ssa name.
2041 */
2042void oatMethodMIR2Bitcode(CompilationUnit* cUnit)
2043{
2044 initIR(cUnit);
2045 oatInitGrowableList(cUnit, &cUnit->llvmValues, cUnit->numSSARegs);
2046
2047 // Create the function
2048 createFunction(cUnit);
2049
2050 // Create an LLVM basic block for each MIR block in dfs preorder
2051 oatDataFlowAnalysisDispatcher(cUnit, createLLVMBasicBlock,
2052 kPreOrderDFSTraversal, false /* isIterative */);
2053 /*
2054 * Create an llvm named value for each MIR SSA name. Note: we'll use
2055 * placeholders for all non-argument values (because we haven't seen
2056 * the definition yet).
2057 */
2058 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2059 llvm::Function::arg_iterator arg_iter(cUnit->func->arg_begin());
2060 arg_iter++; /* Skip path method */
2061 for (int i = 0; i < cUnit->numSSARegs; i++) {
2062 llvm::Value* val;
buzbee85eee022012-07-16 22:12:38 -07002063 RegLocation rlTemp = cUnit->regLocation[i];
2064 if ((SRegToVReg(cUnit, i) < 0) || rlTemp.highWord) {
buzbee2a83e8f2012-07-13 16:42:30 -07002065 oatInsertGrowableList(cUnit, &cUnit->llvmValues, 0);
2066 } else if ((i < cUnit->numRegs) ||
2067 (i >= (cUnit->numRegs + cUnit->numIns))) {
buzbee85eee022012-07-16 22:12:38 -07002068 llvm::Constant* immValue = cUnit->regLocation[i].wide ?
2069 cUnit->irb->GetJLong(0) : cUnit->irb->GetJInt(0);
buzbee2a83e8f2012-07-13 16:42:30 -07002070 val = emitConst(cUnit, immValue, cUnit->regLocation[i]);
2071 val->setName(llvmSSAName(cUnit, i));
buzbee2cfc6392012-05-07 14:51:40 -07002072 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)val);
buzbee2cfc6392012-05-07 14:51:40 -07002073 } else {
2074 // Recover previously-created argument values
2075 llvm::Value* argVal = arg_iter++;
2076 oatInsertGrowableList(cUnit, &cUnit->llvmValues, (intptr_t)argVal);
2077 }
2078 }
buzbee2cfc6392012-05-07 14:51:40 -07002079
2080 oatDataFlowAnalysisDispatcher(cUnit, methodBlockBitcodeConversion,
2081 kPreOrderDFSTraversal, false /* Iterative */);
2082
buzbee4be777b2012-07-12 14:38:18 -07002083 /*
2084 * In a few rare cases of verification failure, the verifier will
2085 * replace one or more Dalvik opcodes with the special
2086 * throw-verification-failure opcode. This can leave the SSA graph
2087 * in an invalid state, as definitions may be lost, while uses retained.
2088 * To work around this problem, we insert placeholder definitions for
2089 * all Dalvik SSA regs in the "placeholder" block. Here, after
2090 * bitcode conversion is complete, we examine those placeholder definitions
2091 * and delete any with no references (which normally is all of them).
2092 *
2093 * If any definitions remain, we link the placeholder block into the
2094 * CFG. Otherwise, it is deleted.
2095 */
2096 for (llvm::BasicBlock::iterator it = cUnit->placeholderBB->begin(),
2097 itEnd = cUnit->placeholderBB->end(); it != itEnd;) {
2098 llvm::Instruction* inst = llvm::dyn_cast<llvm::Instruction>(it++);
2099 DCHECK(inst != NULL);
2100 llvm::Value* val = llvm::dyn_cast<llvm::Value>(inst);
2101 DCHECK(val != NULL);
2102 if (val->getNumUses() == 0) {
2103 inst->eraseFromParent();
2104 }
2105 }
2106 setDexOffset(cUnit, 0);
2107 if (cUnit->placeholderBB->empty()) {
2108 cUnit->placeholderBB->eraseFromParent();
2109 } else {
2110 cUnit->irb->SetInsertPoint(cUnit->placeholderBB);
2111 cUnit->irb->CreateBr(cUnit->entryTargetBB);
2112 cUnit->entryTargetBB = cUnit->placeholderBB;
2113 }
2114 cUnit->irb->SetInsertPoint(cUnit->entryBB);
2115 cUnit->irb->CreateBr(cUnit->entryTargetBB);
buzbee2cfc6392012-05-07 14:51:40 -07002116
Bill Buzbeec9f40dd2012-08-15 11:35:25 -07002117 if (cUnit->enableDebug & (1 << kDebugVerifyBitcode)) {
2118 if (llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction)) {
2119 LOG(INFO) << "Bitcode verification FAILED for "
2120 << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
2121 << " of size " << cUnit->insnsSize;
2122 cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
2123 }
2124 }
buzbee2cfc6392012-05-07 14:51:40 -07002125
buzbeead8f15e2012-06-18 14:49:45 -07002126 if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
2127 // Write bitcode to file
2128 std::string errmsg;
2129 std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
2130 oatReplaceSpecialChars(fname);
buzbee6459e7c2012-10-02 14:42:41 -07002131 // TODO: make configurable change naming mechanism to avoid fname length issues.
buzbee4f1181f2012-06-22 13:52:12 -07002132 fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
buzbee2cfc6392012-05-07 14:51:40 -07002133
buzbee6459e7c2012-10-02 14:42:41 -07002134 if (fname.size() > 240) {
2135 LOG(INFO) << "Warning: bitcode filename too long. Truncated.";
2136 fname.resize(240);
2137 }
2138
buzbeead8f15e2012-06-18 14:49:45 -07002139 llvm::OwningPtr<llvm::tool_output_file> out_file(
2140 new llvm::tool_output_file(fname.c_str(), errmsg,
2141 llvm::raw_fd_ostream::F_Binary));
buzbee2cfc6392012-05-07 14:51:40 -07002142
buzbeead8f15e2012-06-18 14:49:45 -07002143 if (!errmsg.empty()) {
2144 LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
2145 }
2146
2147 llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
2148 out_file->keep();
buzbee6969d502012-06-15 16:40:31 -07002149 }
buzbee2cfc6392012-05-07 14:51:40 -07002150}
2151
2152RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
2153 RegLocation res;
buzbeeb03f4872012-06-11 15:22:11 -07002154 DCHECK(val != NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002155 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2156 if (it == cUnit->locMap.end()) {
buzbee4f1181f2012-06-22 13:52:12 -07002157 std::string valName = val->getName().str();
buzbee32412962012-06-26 16:27:56 -07002158 if (valName.empty()) {
buzbee101305f2012-06-28 18:00:56 -07002159 // FIXME: need to be more robust, handle FP and be in a position to
2160 // manage unnamed temps whose lifetimes span basic block boundaries
buzbee4f1181f2012-06-22 13:52:12 -07002161 UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
2162 memset(&res, 0, sizeof(res));
2163 res.location = kLocPhysReg;
2164 res.lowReg = oatAllocTemp(cUnit);
2165 res.home = true;
2166 res.sRegLow = INVALID_SREG;
2167 res.origSReg = INVALID_SREG;
buzbee101305f2012-06-28 18:00:56 -07002168 llvm::Type* ty = val->getType();
2169 res.wide = ((ty == cUnit->irb->getInt64Ty()) ||
2170 (ty == cUnit->irb->getDoubleTy()));
2171 if (res.wide) {
2172 res.highReg = oatAllocTemp(cUnit);
2173 }
buzbee4f1181f2012-06-22 13:52:12 -07002174 cUnit->locMap.Put(val, res);
buzbee32412962012-06-26 16:27:56 -07002175 } else {
2176 DCHECK_EQ(valName[0], 'v');
2177 int baseSReg = INVALID_SREG;
2178 sscanf(valName.c_str(), "v%d_", &baseSReg);
2179 res = cUnit->regLocation[baseSReg];
2180 cUnit->locMap.Put(val, res);
buzbee2cfc6392012-05-07 14:51:40 -07002181 }
2182 } else {
2183 res = it->second;
2184 }
2185 return res;
2186}
2187
2188Instruction::Code getDalvikOpcode(OpKind op, bool isConst, bool isWide)
2189{
2190 Instruction::Code res = Instruction::NOP;
2191 if (isWide) {
2192 switch(op) {
2193 case kOpAdd: res = Instruction::ADD_LONG; break;
2194 case kOpSub: res = Instruction::SUB_LONG; break;
2195 case kOpMul: res = Instruction::MUL_LONG; break;
2196 case kOpDiv: res = Instruction::DIV_LONG; break;
2197 case kOpRem: res = Instruction::REM_LONG; break;
2198 case kOpAnd: res = Instruction::AND_LONG; break;
2199 case kOpOr: res = Instruction::OR_LONG; break;
2200 case kOpXor: res = Instruction::XOR_LONG; break;
2201 case kOpLsl: res = Instruction::SHL_LONG; break;
2202 case kOpLsr: res = Instruction::USHR_LONG; break;
2203 case kOpAsr: res = Instruction::SHR_LONG; break;
2204 default: LOG(FATAL) << "Unexpected OpKind " << op;
2205 }
2206 } else if (isConst){
2207 switch(op) {
2208 case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
2209 case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
2210 case kOpMul: res = Instruction::MUL_INT_LIT16; break;
2211 case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
2212 case kOpRem: res = Instruction::REM_INT_LIT16; break;
2213 case kOpAnd: res = Instruction::AND_INT_LIT16; break;
2214 case kOpOr: res = Instruction::OR_INT_LIT16; break;
2215 case kOpXor: res = Instruction::XOR_INT_LIT16; break;
2216 case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
2217 case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
2218 case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
2219 default: LOG(FATAL) << "Unexpected OpKind " << op;
2220 }
2221 } else {
2222 switch(op) {
2223 case kOpAdd: res = Instruction::ADD_INT; break;
2224 case kOpSub: res = Instruction::SUB_INT; break;
2225 case kOpMul: res = Instruction::MUL_INT; break;
2226 case kOpDiv: res = Instruction::DIV_INT; break;
2227 case kOpRem: res = Instruction::REM_INT; break;
2228 case kOpAnd: res = Instruction::AND_INT; break;
2229 case kOpOr: res = Instruction::OR_INT; break;
2230 case kOpXor: res = Instruction::XOR_INT; break;
2231 case kOpLsl: res = Instruction::SHL_INT; break;
2232 case kOpLsr: res = Instruction::USHR_INT; break;
2233 case kOpAsr: res = Instruction::SHR_INT; break;
2234 default: LOG(FATAL) << "Unexpected OpKind " << op;
2235 }
2236 }
2237 return res;
2238}
2239
buzbee4f1181f2012-06-22 13:52:12 -07002240Instruction::Code getDalvikFPOpcode(OpKind op, bool isConst, bool isWide)
2241{
2242 Instruction::Code res = Instruction::NOP;
2243 if (isWide) {
2244 switch(op) {
2245 case kOpAdd: res = Instruction::ADD_DOUBLE; break;
2246 case kOpSub: res = Instruction::SUB_DOUBLE; break;
2247 case kOpMul: res = Instruction::MUL_DOUBLE; break;
2248 case kOpDiv: res = Instruction::DIV_DOUBLE; break;
2249 case kOpRem: res = Instruction::REM_DOUBLE; break;
2250 default: LOG(FATAL) << "Unexpected OpKind " << op;
2251 }
2252 } else {
2253 switch(op) {
2254 case kOpAdd: res = Instruction::ADD_FLOAT; break;
2255 case kOpSub: res = Instruction::SUB_FLOAT; break;
2256 case kOpMul: res = Instruction::MUL_FLOAT; break;
2257 case kOpDiv: res = Instruction::DIV_FLOAT; break;
2258 case kOpRem: res = Instruction::REM_FLOAT; break;
2259 default: LOG(FATAL) << "Unexpected OpKind " << op;
2260 }
2261 }
2262 return res;
2263}
2264
2265void cvtBinFPOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2266{
2267 RegLocation rlDest = getLoc(cUnit, inst);
buzbee4f4dfc72012-07-02 14:54:44 -07002268 /*
2269 * Normally, we won't ever generate an FP operation with an immediate
2270 * operand (not supported in Dex instruction set). However, the IR builder
2271 * may insert them - in particular for createNegFP. Recognize this case
2272 * and deal with it.
2273 */
2274 llvm::ConstantFP* op1C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(0));
2275 llvm::ConstantFP* op2C = llvm::dyn_cast<llvm::ConstantFP>(inst->getOperand(1));
2276 DCHECK(op2C == NULL);
2277 if ((op1C != NULL) && (op == kOpSub)) {
2278 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(1));
2279 if (rlDest.wide) {
2280 genArithOpDouble(cUnit, Instruction::NEG_DOUBLE, rlDest, rlSrc, rlSrc);
2281 } else {
2282 genArithOpFloat(cUnit, Instruction::NEG_FLOAT, rlDest, rlSrc, rlSrc);
2283 }
buzbee4f1181f2012-06-22 13:52:12 -07002284 } else {
buzbee4f4dfc72012-07-02 14:54:44 -07002285 DCHECK(op1C == NULL);
2286 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2287 RegLocation rlSrc2 = getLoc(cUnit, inst->getOperand(1));
2288 Instruction::Code dalvikOp = getDalvikFPOpcode(op, false, rlDest.wide);
2289 if (rlDest.wide) {
2290 genArithOpDouble(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2291 } else {
2292 genArithOpFloat(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2293 }
buzbee4f1181f2012-06-22 13:52:12 -07002294 }
2295}
2296
buzbee101305f2012-06-28 18:00:56 -07002297void cvtIntNarrowing(CompilationUnit* cUnit, llvm::Instruction* inst,
2298 Instruction::Code opcode)
2299{
2300 RegLocation rlDest = getLoc(cUnit, inst);
2301 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2302 genIntNarrowing(cUnit, opcode, rlDest, rlSrc);
2303}
2304
buzbee76592632012-06-29 15:18:35 -07002305void cvtIntToFP(CompilationUnit* cUnit, llvm::Instruction* inst)
2306{
2307 RegLocation rlDest = getLoc(cUnit, inst);
2308 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2309 Instruction::Code opcode;
2310 if (rlDest.wide) {
2311 if (rlSrc.wide) {
2312 opcode = Instruction::LONG_TO_DOUBLE;
2313 } else {
2314 opcode = Instruction::INT_TO_DOUBLE;
2315 }
2316 } else {
2317 if (rlSrc.wide) {
2318 opcode = Instruction::LONG_TO_FLOAT;
2319 } else {
2320 opcode = Instruction::INT_TO_FLOAT;
2321 }
2322 }
2323 genConversion(cUnit, opcode, rlDest, rlSrc);
2324}
2325
TDYa1274ec8ccd2012-08-11 07:04:57 -07002326void cvtFPToInt(CompilationUnit* cUnit, llvm::CallInst* call_inst)
buzbee76592632012-06-29 15:18:35 -07002327{
TDYa1274ec8ccd2012-08-11 07:04:57 -07002328 RegLocation rlDest = getLoc(cUnit, call_inst);
2329 RegLocation rlSrc = getLoc(cUnit, call_inst->getOperand(0));
buzbee76592632012-06-29 15:18:35 -07002330 Instruction::Code opcode;
2331 if (rlDest.wide) {
2332 if (rlSrc.wide) {
2333 opcode = Instruction::DOUBLE_TO_LONG;
2334 } else {
2335 opcode = Instruction::FLOAT_TO_LONG;
2336 }
2337 } else {
2338 if (rlSrc.wide) {
2339 opcode = Instruction::DOUBLE_TO_INT;
2340 } else {
2341 opcode = Instruction::FLOAT_TO_INT;
2342 }
2343 }
2344 genConversion(cUnit, opcode, rlDest, rlSrc);
2345}
2346
2347void cvtFloatToDouble(CompilationUnit* cUnit, llvm::Instruction* inst)
2348{
2349 RegLocation rlDest = getLoc(cUnit, inst);
2350 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2351 genConversion(cUnit, Instruction::FLOAT_TO_DOUBLE, rlDest, rlSrc);
2352}
2353
2354void cvtTrunc(CompilationUnit* cUnit, llvm::Instruction* inst)
2355{
2356 RegLocation rlDest = getLoc(cUnit, inst);
2357 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2358 rlSrc = oatUpdateLocWide(cUnit, rlSrc);
2359 rlSrc = oatWideToNarrow(cUnit, rlSrc);
2360 storeValue(cUnit, rlDest, rlSrc);
2361}
2362
2363void cvtDoubleToFloat(CompilationUnit* cUnit, llvm::Instruction* inst)
2364{
2365 RegLocation rlDest = getLoc(cUnit, inst);
2366 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2367 genConversion(cUnit, Instruction::DOUBLE_TO_FLOAT, rlDest, rlSrc);
2368}
2369
2370
buzbee101305f2012-06-28 18:00:56 -07002371void cvtIntExt(CompilationUnit* cUnit, llvm::Instruction* inst, bool isSigned)
2372{
2373 // TODO: evaluate src/tgt types and add general support for more than int to long
2374 RegLocation rlDest = getLoc(cUnit, inst);
2375 RegLocation rlSrc = getLoc(cUnit, inst->getOperand(0));
2376 DCHECK(rlDest.wide);
2377 DCHECK(!rlSrc.wide);
2378 DCHECK(!rlDest.fp);
2379 DCHECK(!rlSrc.fp);
2380 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2381 if (rlSrc.location == kLocPhysReg) {
2382 opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
2383 } else {
2384 loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
2385 }
2386 if (isSigned) {
2387 opRegRegImm(cUnit, kOpAsr, rlResult.highReg, rlResult.lowReg, 31);
2388 } else {
2389 loadConstant(cUnit, rlResult.highReg, 0);
2390 }
2391 storeValueWide(cUnit, rlDest, rlResult);
2392}
2393
buzbee2cfc6392012-05-07 14:51:40 -07002394void cvtBinOp(CompilationUnit* cUnit, OpKind op, llvm::Instruction* inst)
2395{
2396 RegLocation rlDest = getLoc(cUnit, inst);
2397 llvm::Value* lhs = inst->getOperand(0);
buzbeef58c12c2012-07-03 15:06:29 -07002398 // Special-case RSUB/NEG
buzbee4f1181f2012-06-22 13:52:12 -07002399 llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
2400 if ((op == kOpSub) && (lhsImm != NULL)) {
2401 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
buzbeef58c12c2012-07-03 15:06:29 -07002402 if (rlSrc1.wide) {
2403 DCHECK_EQ(lhsImm->getSExtValue(), 0);
2404 genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
2405 } else {
2406 genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
2407 lhsImm->getSExtValue());
2408 }
buzbee4f1181f2012-06-22 13:52:12 -07002409 return;
2410 }
2411 DCHECK(lhsImm == NULL);
buzbee2cfc6392012-05-07 14:51:40 -07002412 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2413 llvm::Value* rhs = inst->getOperand(1);
buzbee9a2487f2012-07-26 14:01:13 -07002414 llvm::ConstantInt* constRhs = llvm::dyn_cast<llvm::ConstantInt>(rhs);
2415 if (!rlDest.wide && (constRhs != NULL)) {
buzbee2cfc6392012-05-07 14:51:40 -07002416 Instruction::Code dalvikOp = getDalvikOpcode(op, true, false);
buzbee9a2487f2012-07-26 14:01:13 -07002417 genArithOpIntLit(cUnit, dalvikOp, rlDest, rlSrc1, constRhs->getSExtValue());
buzbee2cfc6392012-05-07 14:51:40 -07002418 } else {
2419 Instruction::Code dalvikOp = getDalvikOpcode(op, false, rlDest.wide);
buzbee9a2487f2012-07-26 14:01:13 -07002420 RegLocation rlSrc2;
2421 if (constRhs != NULL) {
buzbee63ebbb62012-08-03 14:05:41 -07002422 // ir_builder converts NOT_LONG to xor src, -1. Restore
2423 DCHECK_EQ(dalvikOp, Instruction::XOR_LONG);
2424 DCHECK_EQ(-1L, constRhs->getSExtValue());
2425 dalvikOp = Instruction::NOT_LONG;
buzbee9a2487f2012-07-26 14:01:13 -07002426 rlSrc2 = rlSrc1;
2427 } else {
2428 rlSrc2 = getLoc(cUnit, rhs);
2429 }
buzbee2cfc6392012-05-07 14:51:40 -07002430 if (rlDest.wide) {
2431 genArithOpLong(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2432 } else {
2433 genArithOpInt(cUnit, dalvikOp, rlDest, rlSrc1, rlSrc2);
2434 }
2435 }
2436}
2437
buzbee2a83e8f2012-07-13 16:42:30 -07002438void cvtShiftOp(CompilationUnit* cUnit, Instruction::Code opcode,
2439 llvm::CallInst* callInst)
buzbee101305f2012-06-28 18:00:56 -07002440{
buzbee2a83e8f2012-07-13 16:42:30 -07002441 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2442 RegLocation rlDest = getLoc(cUnit, callInst);
2443 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2444 llvm::Value* rhs = callInst->getArgOperand(1);
2445 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2446 DCHECK(!rlDest.wide);
2447 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc, src2->getSExtValue());
buzbee101305f2012-06-28 18:00:56 -07002448 } else {
buzbee2a83e8f2012-07-13 16:42:30 -07002449 RegLocation rlShift = getLoc(cUnit, rhs);
2450 if (callInst->getType() == cUnit->irb->getInt64Ty()) {
2451 genShiftOpLong(cUnit, opcode, rlDest, rlSrc, rlShift);
2452 } else {
2453 genArithOpInt(cUnit, opcode, rlDest, rlSrc, rlShift);
2454 }
buzbee101305f2012-06-28 18:00:56 -07002455 }
2456}
2457
buzbee2cfc6392012-05-07 14:51:40 -07002458void cvtBr(CompilationUnit* cUnit, llvm::Instruction* inst)
2459{
2460 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(inst);
2461 DCHECK(brInst != NULL);
2462 DCHECK(brInst->isUnconditional()); // May change - but this is all we use now
2463 llvm::BasicBlock* targetBB = brInst->getSuccessor(0);
2464 opUnconditionalBranch(cUnit, cUnit->blockToLabelMap.Get(targetBB));
2465}
2466
2467void cvtPhi(CompilationUnit* cUnit, llvm::Instruction* inst)
2468{
2469 // Nop - these have already been processed
2470}
2471
2472void cvtRet(CompilationUnit* cUnit, llvm::Instruction* inst)
2473{
2474 llvm::ReturnInst* retInst = llvm::dyn_cast<llvm::ReturnInst>(inst);
2475 llvm::Value* retVal = retInst->getReturnValue();
2476 if (retVal != NULL) {
2477 RegLocation rlSrc = getLoc(cUnit, retVal);
2478 if (rlSrc.wide) {
2479 storeValueWide(cUnit, oatGetReturnWide(cUnit, rlSrc.fp), rlSrc);
2480 } else {
2481 storeValue(cUnit, oatGetReturn(cUnit, rlSrc.fp), rlSrc);
2482 }
2483 }
2484 genExitSequence(cUnit);
2485}
2486
2487ConditionCode getCond(llvm::ICmpInst::Predicate llvmCond)
2488{
2489 ConditionCode res = kCondAl;
2490 switch(llvmCond) {
buzbee6969d502012-06-15 16:40:31 -07002491 case llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
buzbee4f1181f2012-06-22 13:52:12 -07002492 case llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
2493 case llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
2494 case llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002495 case llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
buzbee4f1181f2012-06-22 13:52:12 -07002496 case llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
buzbee2cfc6392012-05-07 14:51:40 -07002497 default: LOG(FATAL) << "Unexpected llvm condition";
2498 }
2499 return res;
2500}
2501
2502void cvtICmp(CompilationUnit* cUnit, llvm::Instruction* inst)
2503{
2504 // genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2)
2505 UNIMPLEMENTED(FATAL);
2506}
2507
2508void cvtICmpBr(CompilationUnit* cUnit, llvm::Instruction* inst,
2509 llvm::BranchInst* brInst)
2510{
2511 // Get targets
2512 llvm::BasicBlock* takenBB = brInst->getSuccessor(0);
2513 LIR* taken = cUnit->blockToLabelMap.Get(takenBB);
2514 llvm::BasicBlock* fallThroughBB = brInst->getSuccessor(1);
2515 LIR* fallThrough = cUnit->blockToLabelMap.Get(fallThroughBB);
2516 // Get comparison operands
2517 llvm::ICmpInst* iCmpInst = llvm::dyn_cast<llvm::ICmpInst>(inst);
2518 ConditionCode cond = getCond(iCmpInst->getPredicate());
2519 llvm::Value* lhs = iCmpInst->getOperand(0);
2520 // Not expecting a constant as 1st operand
2521 DCHECK(llvm::dyn_cast<llvm::ConstantInt>(lhs) == NULL);
2522 RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(0));
2523 rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
2524 llvm::Value* rhs = inst->getOperand(1);
2525#if defined(TARGET_MIPS)
2526 // Compare and branch in one shot
2527 (void)taken;
2528 (void)cond;
2529 (void)rhs;
2530 UNIMPLEMENTED(FATAL);
2531#else
2532 //Compare, then branch
2533 // TODO: handle fused CMP_LONG/IF_xxZ case
2534 if (llvm::ConstantInt* src2 = llvm::dyn_cast<llvm::ConstantInt>(rhs)) {
2535 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, src2->getSExtValue());
buzbeed5018892012-07-11 14:23:40 -07002536 } else if (llvm::dyn_cast<llvm::ConstantPointerNull>(rhs) != NULL) {
2537 opRegImm(cUnit, kOpCmp, rlSrc1.lowReg, 0);
buzbee2cfc6392012-05-07 14:51:40 -07002538 } else {
2539 RegLocation rlSrc2 = getLoc(cUnit, rhs);
2540 rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
2541 opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
2542 }
2543 opCondBranch(cUnit, cond, taken);
2544#endif
2545 // Fallthrough
2546 opUnconditionalBranch(cUnit, fallThrough);
2547}
2548
2549void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst,
2550 llvm::Function* callee)
2551{
2552 UNIMPLEMENTED(FATAL);
2553}
2554
buzbee2cfc6392012-05-07 14:51:40 -07002555void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
2556{
buzbee4f1181f2012-06-22 13:52:12 -07002557 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002558 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(0));
2559 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee76592632012-06-29 15:18:35 -07002560 DCHECK_EQ(rlSrc.wide, rlDest.wide);
2561 DCHECK_EQ(rlSrc.fp, rlDest.fp);
buzbee2cfc6392012-05-07 14:51:40 -07002562 if (rlSrc.wide) {
2563 storeValueWide(cUnit, rlDest, rlSrc);
2564 } else {
2565 storeValue(cUnit, rlDest, rlSrc);
2566 }
2567}
2568
2569// Note: Immediate arg is a ConstantInt regardless of result type
2570void cvtConst(CompilationUnit* cUnit, llvm::CallInst* callInst)
2571{
buzbee4f1181f2012-06-22 13:52:12 -07002572 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee2cfc6392012-05-07 14:51:40 -07002573 llvm::ConstantInt* src =
2574 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2575 uint64_t immval = src->getZExtValue();
2576 RegLocation rlDest = getLoc(cUnit, callInst);
2577 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
2578 if (rlDest.wide) {
2579 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
2580 (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
2581 storeValueWide(cUnit, rlDest, rlResult);
2582 } else {
2583 loadConstantNoClobber(cUnit, rlResult.lowReg, immval & 0xffffffff);
2584 storeValue(cUnit, rlDest, rlResult);
2585 }
2586}
2587
buzbee101305f2012-06-28 18:00:56 -07002588void cvtConstObject(CompilationUnit* cUnit, llvm::CallInst* callInst,
2589 bool isString)
buzbee6969d502012-06-15 16:40:31 -07002590{
buzbee4f1181f2012-06-22 13:52:12 -07002591 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee101305f2012-06-28 18:00:56 -07002592 llvm::ConstantInt* idxVal =
buzbee6969d502012-06-15 16:40:31 -07002593 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
buzbee101305f2012-06-28 18:00:56 -07002594 uint32_t index = idxVal->getZExtValue();
buzbee6969d502012-06-15 16:40:31 -07002595 RegLocation rlDest = getLoc(cUnit, callInst);
buzbee101305f2012-06-28 18:00:56 -07002596 if (isString) {
2597 genConstString(cUnit, index, rlDest);
2598 } else {
2599 genConstClass(cUnit, index, rlDest);
2600 }
2601}
2602
2603void cvtFillArrayData(CompilationUnit* cUnit, llvm::CallInst* callInst)
2604{
2605 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2606 llvm::ConstantInt* offsetVal =
2607 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2608 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2609 genFillArrayData(cUnit, offsetVal->getSExtValue(), rlSrc);
buzbee6969d502012-06-15 16:40:31 -07002610}
2611
buzbee4f1181f2012-06-22 13:52:12 -07002612void cvtNewInstance(CompilationUnit* cUnit, llvm::CallInst* callInst)
2613{
buzbee32412962012-06-26 16:27:56 -07002614 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002615 llvm::ConstantInt* typeIdxVal =
2616 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2617 uint32_t typeIdx = typeIdxVal->getZExtValue();
2618 RegLocation rlDest = getLoc(cUnit, callInst);
2619 genNewInstance(cUnit, typeIdx, rlDest);
2620}
2621
buzbee8fa0fda2012-06-27 15:44:52 -07002622void cvtNewArray(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* len = callInst->getArgOperand(1);
2629 RegLocation rlLen = getLoc(cUnit, len);
2630 RegLocation rlDest = getLoc(cUnit, callInst);
2631 genNewArray(cUnit, typeIdx, rlDest, rlLen);
2632}
2633
2634void cvtInstanceOf(CompilationUnit* cUnit, llvm::CallInst* callInst)
2635{
2636 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2637 llvm::ConstantInt* typeIdxVal =
2638 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2639 uint32_t typeIdx = typeIdxVal->getZExtValue();
2640 llvm::Value* src = callInst->getArgOperand(1);
2641 RegLocation rlSrc = getLoc(cUnit, src);
2642 RegLocation rlDest = getLoc(cUnit, callInst);
2643 genInstanceof(cUnit, typeIdx, rlDest, rlSrc);
2644}
2645
buzbee32412962012-06-26 16:27:56 -07002646void cvtThrow(CompilationUnit* cUnit, llvm::CallInst* callInst)
2647{
2648 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
2649 llvm::Value* src = callInst->getArgOperand(0);
2650 RegLocation rlSrc = getLoc(cUnit, src);
2651 genThrow(cUnit, rlSrc);
2652}
2653
buzbee8fa0fda2012-06-27 15:44:52 -07002654void cvtMonitorEnterExit(CompilationUnit* cUnit, bool isEnter,
2655 llvm::CallInst* callInst)
2656{
2657 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2658 llvm::ConstantInt* optFlags =
2659 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2660 llvm::Value* src = callInst->getArgOperand(1);
2661 RegLocation rlSrc = getLoc(cUnit, src);
2662 if (isEnter) {
2663 genMonitorEnter(cUnit, optFlags->getZExtValue(), rlSrc);
2664 } else {
2665 genMonitorExit(cUnit, optFlags->getZExtValue(), rlSrc);
2666 }
2667}
2668
buzbee76592632012-06-29 15:18:35 -07002669void cvtArrayLength(CompilationUnit* cUnit, llvm::CallInst* callInst)
buzbee8fa0fda2012-06-27 15:44:52 -07002670{
2671 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2672 llvm::ConstantInt* optFlags =
2673 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2674 llvm::Value* src = callInst->getArgOperand(1);
2675 RegLocation rlSrc = getLoc(cUnit, src);
2676 rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
2677 genNullCheck(cUnit, rlSrc.sRegLow, rlSrc.lowReg, optFlags->getZExtValue());
2678 RegLocation rlDest = getLoc(cUnit, callInst);
2679 RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
2680 int lenOffset = Array::LengthOffset().Int32Value();
2681 loadWordDisp(cUnit, rlSrc.lowReg, lenOffset, rlResult.lowReg);
2682 storeValue(cUnit, rlDest, rlResult);
2683}
2684
buzbee32412962012-06-26 16:27:56 -07002685void cvtMoveException(CompilationUnit* cUnit, llvm::CallInst* callInst)
2686{
buzbee32412962012-06-26 16:27:56 -07002687 RegLocation rlDest = getLoc(cUnit, callInst);
Ian Rogers474b6da2012-09-25 00:20:38 -07002688 genMoveException(cUnit, rlDest);
buzbee32412962012-06-26 16:27:56 -07002689}
2690
buzbee4f1181f2012-06-22 13:52:12 -07002691void cvtSget(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2692 bool isObject)
2693{
buzbee32412962012-06-26 16:27:56 -07002694 DCHECK_EQ(callInst->getNumArgOperands(), 1U);
buzbee4f1181f2012-06-22 13:52:12 -07002695 llvm::ConstantInt* typeIdxVal =
2696 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2697 uint32_t typeIdx = typeIdxVal->getZExtValue();
2698 RegLocation rlDest = getLoc(cUnit, callInst);
2699 genSget(cUnit, typeIdx, rlDest, isWide, isObject);
2700}
2701
buzbee8fa0fda2012-06-27 15:44:52 -07002702void cvtSput(CompilationUnit* cUnit, llvm::CallInst* callInst, bool isWide,
2703 bool isObject)
2704{
2705 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2706 llvm::ConstantInt* typeIdxVal =
2707 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2708 uint32_t typeIdx = typeIdxVal->getZExtValue();
2709 llvm::Value* src = callInst->getArgOperand(1);
2710 RegLocation rlSrc = getLoc(cUnit, src);
2711 genSput(cUnit, typeIdx, rlSrc, isWide, isObject);
2712}
2713
2714void cvtAget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2715 int scale)
2716{
2717 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2718 llvm::ConstantInt* optFlags =
2719 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2720 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(1));
2721 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(2));
2722 RegLocation rlDest = getLoc(cUnit, callInst);
2723 genArrayGet(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2724 rlDest, scale);
2725}
2726
2727void cvtAput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
buzbeef1f86362012-07-10 15:18:31 -07002728 int scale, bool isObject)
buzbee8fa0fda2012-06-27 15:44:52 -07002729{
2730 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2731 llvm::ConstantInt* optFlags =
2732 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2733 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2734 RegLocation rlArray = getLoc(cUnit, callInst->getArgOperand(2));
2735 RegLocation rlIndex = getLoc(cUnit, callInst->getArgOperand(3));
buzbeef1f86362012-07-10 15:18:31 -07002736 if (isObject) {
2737 genArrayObjPut(cUnit, optFlags->getZExtValue(), rlArray, rlIndex,
2738 rlSrc, scale);
2739 } else {
2740 genArrayPut(cUnit, optFlags->getZExtValue(), size, rlArray, rlIndex,
2741 rlSrc, scale);
2742 }
2743}
2744
2745void cvtAputObj(CompilationUnit* cUnit, llvm::CallInst* callInst)
2746{
2747 cvtAput(cUnit, callInst, kWord, 2, true /* isObject */);
2748}
2749
2750void cvtAputPrimitive(CompilationUnit* cUnit, llvm::CallInst* callInst,
2751 OpSize size, int scale)
2752{
2753 cvtAput(cUnit, callInst, size, scale, false /* isObject */);
buzbee8fa0fda2012-06-27 15:44:52 -07002754}
2755
buzbee101305f2012-06-28 18:00:56 -07002756void cvtIget(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2757 bool isWide, bool isObj)
2758{
2759 DCHECK_EQ(callInst->getNumArgOperands(), 3U);
2760 llvm::ConstantInt* optFlags =
2761 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2762 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(1));
2763 llvm::ConstantInt* fieldIdx =
2764 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2765 RegLocation rlDest = getLoc(cUnit, callInst);
2766 genIGet(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2767 size, rlDest, rlObj, isWide, isObj);
2768}
2769
2770void cvtIput(CompilationUnit* cUnit, llvm::CallInst* callInst, OpSize size,
2771 bool isWide, bool isObj)
2772{
2773 DCHECK_EQ(callInst->getNumArgOperands(), 4U);
2774 llvm::ConstantInt* optFlags =
2775 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2776 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2777 RegLocation rlObj = getLoc(cUnit, callInst->getArgOperand(2));
2778 llvm::ConstantInt* fieldIdx =
buzbee4f4dfc72012-07-02 14:54:44 -07002779 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(3));
buzbee101305f2012-06-28 18:00:56 -07002780 genIPut(cUnit, fieldIdx->getZExtValue(), optFlags->getZExtValue(),
2781 size, rlSrc, rlObj, isWide, isObj);
2782}
2783
2784void cvtCheckCast(CompilationUnit* cUnit, llvm::CallInst* callInst)
2785{
2786 DCHECK_EQ(callInst->getNumArgOperands(), 2U);
2787 llvm::ConstantInt* typeIdx =
2788 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2789 RegLocation rlSrc = getLoc(cUnit, callInst->getArgOperand(1));
2790 genCheckCast(cUnit, typeIdx->getZExtValue(), rlSrc);
2791}
2792
buzbee76592632012-06-29 15:18:35 -07002793void cvtFPCompare(CompilationUnit* cUnit, llvm::CallInst* callInst,
2794 Instruction::Code opcode)
2795{
2796 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2797 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2798 RegLocation rlDest = getLoc(cUnit, callInst);
2799 genCmpFP(cUnit, opcode, rlDest, rlSrc1, rlSrc2);
2800}
2801
2802void cvtLongCompare(CompilationUnit* cUnit, llvm::CallInst* callInst)
2803{
2804 RegLocation rlSrc1 = getLoc(cUnit, callInst->getArgOperand(0));
2805 RegLocation rlSrc2 = getLoc(cUnit, callInst->getArgOperand(1));
2806 RegLocation rlDest = getLoc(cUnit, callInst);
2807 genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
2808}
2809
buzbeef58c12c2012-07-03 15:06:29 -07002810void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
2811{
2812 llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
2813 DCHECK(swInst != NULL);
2814 llvm::Value* testVal = swInst->getCondition();
2815 llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
2816 DCHECK(tableOffsetNode != NULL);
2817 llvm::ConstantInt* tableOffsetValue =
2818 static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
2819 int32_t tableOffset = tableOffsetValue->getSExtValue();
2820 RegLocation rlSrc = getLoc(cUnit, testVal);
buzbeea1da8a52012-07-09 14:00:21 -07002821 const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
2822 u2 tableMagic = *table;
2823 if (tableMagic == 0x100) {
2824 genPackedSwitch(cUnit, tableOffset, rlSrc);
2825 } else {
2826 DCHECK_EQ(tableMagic, 0x200);
2827 genSparseSwitch(cUnit, tableOffset, rlSrc);
2828 }
buzbeef58c12c2012-07-03 15:06:29 -07002829}
2830
buzbee6969d502012-06-15 16:40:31 -07002831void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
buzbee76592632012-06-29 15:18:35 -07002832 bool isVoid, bool isFilledNewArray)
buzbee6969d502012-06-15 16:40:31 -07002833{
2834 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
2835 kAllocMisc);
buzbee8fa0fda2012-06-27 15:44:52 -07002836 if (isVoid) {
buzbee6969d502012-06-15 16:40:31 -07002837 info->result.location = kLocInvalid;
2838 } else {
2839 info->result = getLoc(cUnit, callInst);
2840 }
2841 llvm::ConstantInt* invokeTypeVal =
2842 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(0));
2843 llvm::ConstantInt* methodIndexVal =
2844 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(1));
2845 llvm::ConstantInt* optFlagsVal =
2846 llvm::dyn_cast<llvm::ConstantInt>(callInst->getArgOperand(2));
2847 info->type = static_cast<InvokeType>(invokeTypeVal->getZExtValue());
2848 info->index = methodIndexVal->getZExtValue();
2849 info->optFlags = optFlagsVal->getZExtValue();
2850 info->offset = cUnit->currentDalvikOffset;
2851
buzbee6969d502012-06-15 16:40:31 -07002852 // Count the argument words, and then build argument array.
2853 info->numArgWords = 0;
2854 for (unsigned int i = 3; i < callInst->getNumArgOperands(); i++) {
2855 RegLocation tLoc = getLoc(cUnit, callInst->getArgOperand(i));
2856 info->numArgWords += tLoc.wide ? 2 : 1;
2857 }
2858 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
2859 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
2860 // Now, fill in the location records, synthesizing high loc of wide vals
2861 for (int i = 3, next = 0; next < info->numArgWords;) {
buzbee4f1181f2012-06-22 13:52:12 -07002862 info->args[next] = getLoc(cUnit, callInst->getArgOperand(i++));
buzbee6969d502012-06-15 16:40:31 -07002863 if (info->args[next].wide) {
2864 next++;
2865 // TODO: Might make sense to mark this as an invalid loc
2866 info->args[next].origSReg = info->args[next-1].origSReg+1;
2867 info->args[next].sRegLow = info->args[next-1].sRegLow+1;
2868 }
2869 next++;
2870 }
buzbee4f4dfc72012-07-02 14:54:44 -07002871 // TODO - rework such that we no longer need isRange
2872 info->isRange = (info->numArgWords > 5);
2873
buzbee76592632012-06-29 15:18:35 -07002874 if (isFilledNewArray) {
buzbee101305f2012-06-28 18:00:56 -07002875 genFilledNewArray(cUnit, info);
2876 } else {
2877 genInvoke(cUnit, info);
2878 }
buzbee6969d502012-06-15 16:40:31 -07002879}
2880
buzbeead8f15e2012-06-18 14:49:45 -07002881/* Look up the RegLocation associated with a Value. Must already be defined */
2882RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
2883{
2884 SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
2885 DCHECK(it != cUnit->locMap.end()) << "Missing definition";
2886 return it->second;
2887}
2888
buzbee2cfc6392012-05-07 14:51:40 -07002889bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
2890{
buzbee0967a252012-09-14 10:43:54 -07002891 while (cUnit->llvmBlocks.find(bb) == cUnit->llvmBlocks.end()) {
2892 llvm::BasicBlock* nextBB = NULL;
2893 cUnit->llvmBlocks.insert(bb);
2894 bool isEntry = (bb == &cUnit->func->getEntryBlock());
2895 // Define the starting label
2896 LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
2897 // Extract the type and starting offset from the block's name
buzbee951c0a12012-10-03 16:31:39 -07002898 char blockType = kInvalidBlock;
2899 if (isEntry) {
2900 blockType = kNormalBlock;
2901 blockLabel->operands[0] = 0;
2902 } else if (!bb->hasName()) {
2903 blockType = kNormalBlock;
2904 blockLabel->operands[0] = DexFile::kDexNoIndex;
buzbee0967a252012-09-14 10:43:54 -07002905 } else {
buzbee951c0a12012-10-03 16:31:39 -07002906 std::string blockName = bb->getName().str();
2907 int dummy;
2908 sscanf(blockName.c_str(), kLabelFormat, &blockType, &blockLabel->operands[0], &dummy);
2909 cUnit->currentDalvikOffset = blockLabel->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002910 }
buzbee951c0a12012-10-03 16:31:39 -07002911 DCHECK((blockType == kNormalBlock) || (blockType == kCatchBlock));
2912 cUnit->currentDalvikOffset = blockLabel->operands[0];
buzbee0967a252012-09-14 10:43:54 -07002913 // Set the label kind
2914 blockLabel->opcode = kPseudoNormalBlockLabel;
2915 // Insert the label
2916 oatAppendLIR(cUnit, blockLabel);
buzbee2cfc6392012-05-07 14:51:40 -07002917
buzbee0967a252012-09-14 10:43:54 -07002918 LIR* headLIR = NULL;
buzbee8320f382012-09-11 16:29:42 -07002919
buzbee0967a252012-09-14 10:43:54 -07002920 if (blockType == kCatchBlock) {
Bill Buzbeea5b30242012-09-28 07:19:44 -07002921 headLIR = newLIR0(cUnit, kPseudoExportedPC);
buzbee0967a252012-09-14 10:43:54 -07002922 }
buzbee8320f382012-09-11 16:29:42 -07002923
buzbee0967a252012-09-14 10:43:54 -07002924 // Free temp registers and reset redundant store tracking */
2925 oatResetRegPool(cUnit);
2926 oatResetDefTracking(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002927
buzbee0967a252012-09-14 10:43:54 -07002928 //TODO: restore oat incoming liveness optimization
2929 oatClobberAllRegs(cUnit);
buzbee2cfc6392012-05-07 14:51:40 -07002930
buzbee0967a252012-09-14 10:43:54 -07002931 if (isEntry) {
2932 RegLocation* argLocs = (RegLocation*)
2933 oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
2934 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
2935 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
2936 // Skip past Method*
2937 it++;
2938 for (unsigned i = 0; it != it_end; ++it) {
2939 llvm::Value* val = it;
2940 argLocs[i++] = valToLoc(cUnit, val);
2941 llvm::Type* ty = val->getType();
2942 if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
2943 argLocs[i] = argLocs[i-1];
2944 argLocs[i].lowReg = argLocs[i].highReg;
2945 argLocs[i].origSReg++;
2946 argLocs[i].sRegLow = INVALID_SREG;
2947 argLocs[i].highWord = true;
2948 i++;
2949 }
2950 }
2951 genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
2952 }
2953
2954 // Visit all of the instructions in the block
2955 for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
2956 llvm::Instruction* inst = it;
2957 llvm::BasicBlock::iterator nextIt = ++it;
2958 // Extract the Dalvik offset from the instruction
2959 uint32_t opcode = inst->getOpcode();
2960 llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
2961 if (dexOffsetNode != NULL) {
2962 llvm::ConstantInt* dexOffsetValue =
2963 static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
2964 cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
2965 }
2966
2967 oatResetRegPool(cUnit);
2968 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
2969 oatClobberAllRegs(cUnit);
2970 }
2971
2972 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
2973 oatResetDefTracking(cUnit);
2974 }
2975
2976 #ifndef NDEBUG
2977 /* Reset temp tracking sanity check */
2978 cUnit->liveSReg = INVALID_SREG;
2979 #endif
2980
2981 // TODO: use llvm opcode name here instead of "boundary" if verbose
2982 LIR* boundaryLIR = markBoundary(cUnit, cUnit->currentDalvikOffset, "boundary");
2983
2984 /* Remember the first LIR for thisl block*/
2985 if (headLIR == NULL) {
2986 headLIR = boundaryLIR;
2987 headLIR->defMask = ENCODE_ALL;
2988 }
2989
2990 switch(opcode) {
2991
2992 case llvm::Instruction::ICmp: {
2993 llvm::Instruction* nextInst = nextIt;
2994 llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
2995 if (brInst != NULL /* and... */) {
2996 cvtICmpBr(cUnit, inst, brInst);
2997 ++it;
2998 } else {
2999 cvtICmp(cUnit, inst);
3000 }
3001 }
3002 break;
3003
3004 case llvm::Instruction::Call: {
3005 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
3006 llvm::Function* callee = callInst->getCalledFunction();
3007 greenland::IntrinsicHelper::IntrinsicId id =
3008 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3009 switch (id) {
3010 case greenland::IntrinsicHelper::AllocaShadowFrame:
3011 case greenland::IntrinsicHelper::SetShadowFrameEntry:
3012 case greenland::IntrinsicHelper::PopShadowFrame:
3013 // Ignore shadow frame stuff for quick compiler
3014 break;
3015 case greenland::IntrinsicHelper::CopyInt:
3016 case greenland::IntrinsicHelper::CopyObj:
3017 case greenland::IntrinsicHelper::CopyFloat:
3018 case greenland::IntrinsicHelper::CopyLong:
3019 case greenland::IntrinsicHelper::CopyDouble:
3020 cvtCopy(cUnit, callInst);
3021 break;
3022 case greenland::IntrinsicHelper::ConstInt:
3023 case greenland::IntrinsicHelper::ConstObj:
3024 case greenland::IntrinsicHelper::ConstLong:
3025 case greenland::IntrinsicHelper::ConstFloat:
3026 case greenland::IntrinsicHelper::ConstDouble:
3027 cvtConst(cUnit, callInst);
3028 break;
3029 case greenland::IntrinsicHelper::DivInt:
3030 case greenland::IntrinsicHelper::DivLong:
3031 cvtBinOp(cUnit, kOpDiv, inst);
3032 break;
3033 case greenland::IntrinsicHelper::RemInt:
3034 case greenland::IntrinsicHelper::RemLong:
3035 cvtBinOp(cUnit, kOpRem, inst);
3036 break;
3037 case greenland::IntrinsicHelper::MethodInfo:
3038 // Already dealt with - just ignore it here.
3039 break;
3040 case greenland::IntrinsicHelper::CheckSuspend:
3041 genSuspendTest(cUnit, 0 /* optFlags already applied */);
3042 break;
3043 case greenland::IntrinsicHelper::HLInvokeObj:
3044 case greenland::IntrinsicHelper::HLInvokeFloat:
3045 case greenland::IntrinsicHelper::HLInvokeDouble:
3046 case greenland::IntrinsicHelper::HLInvokeLong:
3047 case greenland::IntrinsicHelper::HLInvokeInt:
3048 cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
3049 break;
3050 case greenland::IntrinsicHelper::HLInvokeVoid:
3051 cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
3052 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003053 case greenland::IntrinsicHelper::HLFilledNewArray:
buzbee0967a252012-09-14 10:43:54 -07003054 cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
3055 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003056 case greenland::IntrinsicHelper::HLFillArrayData:
buzbee0967a252012-09-14 10:43:54 -07003057 cvtFillArrayData(cUnit, callInst);
3058 break;
3059 case greenland::IntrinsicHelper::ConstString:
3060 cvtConstObject(cUnit, callInst, true /* isString */);
3061 break;
3062 case greenland::IntrinsicHelper::ConstClass:
3063 cvtConstObject(cUnit, callInst, false /* isString */);
3064 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003065 case greenland::IntrinsicHelper::HLCheckCast:
buzbee0967a252012-09-14 10:43:54 -07003066 cvtCheckCast(cUnit, callInst);
3067 break;
3068 case greenland::IntrinsicHelper::NewInstance:
3069 cvtNewInstance(cUnit, callInst);
3070 break;
3071 case greenland::IntrinsicHelper::HLSgetObject:
3072 cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
3073 break;
3074 case greenland::IntrinsicHelper::HLSget:
3075 case greenland::IntrinsicHelper::HLSgetFloat:
3076 case greenland::IntrinsicHelper::HLSgetBoolean:
3077 case greenland::IntrinsicHelper::HLSgetByte:
3078 case greenland::IntrinsicHelper::HLSgetChar:
3079 case greenland::IntrinsicHelper::HLSgetShort:
3080 cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
3081 break;
3082 case greenland::IntrinsicHelper::HLSgetWide:
3083 case greenland::IntrinsicHelper::HLSgetDouble:
3084 cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
3085 break;
3086 case greenland::IntrinsicHelper::HLSput:
3087 case greenland::IntrinsicHelper::HLSputFloat:
3088 case greenland::IntrinsicHelper::HLSputBoolean:
3089 case greenland::IntrinsicHelper::HLSputByte:
3090 case greenland::IntrinsicHelper::HLSputChar:
3091 case greenland::IntrinsicHelper::HLSputShort:
3092 cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
3093 break;
3094 case greenland::IntrinsicHelper::HLSputWide:
3095 case greenland::IntrinsicHelper::HLSputDouble:
3096 cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
3097 break;
3098 case greenland::IntrinsicHelper::HLSputObject:
3099 cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
3100 break;
3101 case greenland::IntrinsicHelper::GetException:
3102 cvtMoveException(cUnit, callInst);
3103 break;
TDYa127f71bf5a2012-07-29 20:09:52 -07003104 case greenland::IntrinsicHelper::HLThrowException:
buzbee0967a252012-09-14 10:43:54 -07003105 cvtThrow(cUnit, callInst);
3106 break;
3107 case greenland::IntrinsicHelper::MonitorEnter:
3108 cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
3109 break;
3110 case greenland::IntrinsicHelper::MonitorExit:
3111 cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
3112 break;
Shih-wei Liao21d28f52012-06-12 05:55:00 -07003113 case greenland::IntrinsicHelper::OptArrayLength:
buzbee0967a252012-09-14 10:43:54 -07003114 cvtArrayLength(cUnit, callInst);
3115 break;
3116 case greenland::IntrinsicHelper::NewArray:
3117 cvtNewArray(cUnit, callInst);
3118 break;
3119 case greenland::IntrinsicHelper::InstanceOf:
3120 cvtInstanceOf(cUnit, callInst);
3121 break;
3122
3123 case greenland::IntrinsicHelper::HLArrayGet:
3124 case greenland::IntrinsicHelper::HLArrayGetObject:
3125 case greenland::IntrinsicHelper::HLArrayGetFloat:
3126 cvtAget(cUnit, callInst, kWord, 2);
3127 break;
3128 case greenland::IntrinsicHelper::HLArrayGetWide:
3129 case greenland::IntrinsicHelper::HLArrayGetDouble:
3130 cvtAget(cUnit, callInst, kLong, 3);
3131 break;
3132 case greenland::IntrinsicHelper::HLArrayGetBoolean:
3133 cvtAget(cUnit, callInst, kUnsignedByte, 0);
3134 break;
3135 case greenland::IntrinsicHelper::HLArrayGetByte:
3136 cvtAget(cUnit, callInst, kSignedByte, 0);
3137 break;
3138 case greenland::IntrinsicHelper::HLArrayGetChar:
3139 cvtAget(cUnit, callInst, kUnsignedHalf, 1);
3140 break;
3141 case greenland::IntrinsicHelper::HLArrayGetShort:
3142 cvtAget(cUnit, callInst, kSignedHalf, 1);
3143 break;
3144
3145 case greenland::IntrinsicHelper::HLArrayPut:
3146 case greenland::IntrinsicHelper::HLArrayPutFloat:
3147 cvtAputPrimitive(cUnit, callInst, kWord, 2);
3148 break;
3149 case greenland::IntrinsicHelper::HLArrayPutObject:
3150 cvtAputObj(cUnit, callInst);
3151 break;
3152 case greenland::IntrinsicHelper::HLArrayPutWide:
3153 case greenland::IntrinsicHelper::HLArrayPutDouble:
3154 cvtAputPrimitive(cUnit, callInst, kLong, 3);
3155 break;
3156 case greenland::IntrinsicHelper::HLArrayPutBoolean:
3157 cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
3158 break;
3159 case greenland::IntrinsicHelper::HLArrayPutByte:
3160 cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
3161 break;
3162 case greenland::IntrinsicHelper::HLArrayPutChar:
3163 cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
3164 break;
3165 case greenland::IntrinsicHelper::HLArrayPutShort:
3166 cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
3167 break;
3168
3169 case greenland::IntrinsicHelper::HLIGet:
3170 case greenland::IntrinsicHelper::HLIGetFloat:
3171 cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3172 break;
3173 case greenland::IntrinsicHelper::HLIGetObject:
3174 cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3175 break;
3176 case greenland::IntrinsicHelper::HLIGetWide:
3177 case greenland::IntrinsicHelper::HLIGetDouble:
3178 cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3179 break;
3180 case greenland::IntrinsicHelper::HLIGetBoolean:
3181 cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
3182 false /* obj */);
3183 break;
3184 case greenland::IntrinsicHelper::HLIGetByte:
3185 cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
3186 false /* obj */);
3187 break;
3188 case greenland::IntrinsicHelper::HLIGetChar:
3189 cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3190 false /* obj */);
3191 break;
3192 case greenland::IntrinsicHelper::HLIGetShort:
3193 cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
3194 false /* obj */);
3195 break;
3196
3197 case greenland::IntrinsicHelper::HLIPut:
3198 case greenland::IntrinsicHelper::HLIPutFloat:
3199 cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
3200 break;
3201 case greenland::IntrinsicHelper::HLIPutObject:
3202 cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
3203 break;
3204 case greenland::IntrinsicHelper::HLIPutWide:
3205 case greenland::IntrinsicHelper::HLIPutDouble:
3206 cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
3207 break;
3208 case greenland::IntrinsicHelper::HLIPutBoolean:
3209 cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
3210 false /* obj */);
3211 break;
3212 case greenland::IntrinsicHelper::HLIPutByte:
3213 cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
3214 false /* obj */);
3215 break;
3216 case greenland::IntrinsicHelper::HLIPutChar:
3217 cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
3218 false /* obj */);
3219 break;
3220 case greenland::IntrinsicHelper::HLIPutShort:
3221 cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
3222 false /* obj */);
3223 break;
3224
3225 case greenland::IntrinsicHelper::IntToChar:
3226 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
3227 break;
3228 case greenland::IntrinsicHelper::IntToShort:
3229 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
3230 break;
3231 case greenland::IntrinsicHelper::IntToByte:
3232 cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
3233 break;
3234
TDYa1274ec8ccd2012-08-11 07:04:57 -07003235 case greenland::IntrinsicHelper::F2I:
3236 case greenland::IntrinsicHelper::D2I:
3237 case greenland::IntrinsicHelper::F2L:
3238 case greenland::IntrinsicHelper::D2L:
3239 cvtFPToInt(cUnit, callInst);
3240 break;
3241
buzbee0967a252012-09-14 10:43:54 -07003242 case greenland::IntrinsicHelper::CmplFloat:
3243 cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
3244 break;
3245 case greenland::IntrinsicHelper::CmpgFloat:
3246 cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
3247 break;
3248 case greenland::IntrinsicHelper::CmplDouble:
3249 cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
3250 break;
3251 case greenland::IntrinsicHelper::CmpgDouble:
3252 cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
3253 break;
3254
3255 case greenland::IntrinsicHelper::CmpLong:
3256 cvtLongCompare(cUnit, callInst);
3257 break;
3258
3259 case greenland::IntrinsicHelper::SHLLong:
3260 cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
3261 break;
3262 case greenland::IntrinsicHelper::SHRLong:
3263 cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
3264 break;
3265 case greenland::IntrinsicHelper::USHRLong:
3266 cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
3267 break;
3268 case greenland::IntrinsicHelper::SHLInt:
3269 cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
3270 break;
3271 case greenland::IntrinsicHelper::SHRInt:
3272 cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
3273 break;
3274 case greenland::IntrinsicHelper::USHRInt:
3275 cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
3276 break;
3277
3278 case greenland::IntrinsicHelper::CatchTargets: {
3279 llvm::SwitchInst* swInst =
3280 llvm::dyn_cast<llvm::SwitchInst>(nextIt);
3281 DCHECK(swInst != NULL);
3282 /*
3283 * Discard the edges and the following conditional branch.
3284 * Do a direct branch to the default target (which is the
3285 * "work" portion of the pair.
3286 * TODO: awful code layout - rework
3287 */
3288 llvm::BasicBlock* targetBB = swInst->getDefaultDest();
3289 DCHECK(targetBB != NULL);
3290 opUnconditionalBranch(cUnit,
3291 cUnit->blockToLabelMap.Get(targetBB));
3292 ++it;
3293 // Set next bb to default target - improves code layout
3294 nextBB = targetBB;
3295 }
3296 break;
3297
3298 default:
3299 LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
3300 << cUnit->intrinsic_helper->GetName(id);
3301 }
3302 }
3303 break;
3304
3305 case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
3306 case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
3307 case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
3308 case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
3309 case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
3310 case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
3311 case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
3312 case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
3313 case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
3314 case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
3315 case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
3316 case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
3317 case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
3318 case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
3319 case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
3320 case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
3321 case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
buzbee0967a252012-09-14 10:43:54 -07003322 case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
3323 case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
3324 case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
3325
3326 case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
3327 break;
3328 case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
3329 break;
3330
3331 case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
3332
3333 case llvm::Instruction::Unreachable:
3334 break; // FIXME: can we really ignore these?
3335
3336 case llvm::Instruction::Shl:
3337 case llvm::Instruction::LShr:
3338 case llvm::Instruction::AShr:
3339 case llvm::Instruction::Invoke:
3340 case llvm::Instruction::FPToUI:
TDYa1274ec8ccd2012-08-11 07:04:57 -07003341 case llvm::Instruction::FPToSI:
buzbee0967a252012-09-14 10:43:54 -07003342 case llvm::Instruction::UIToFP:
3343 case llvm::Instruction::PtrToInt:
3344 case llvm::Instruction::IntToPtr:
3345 case llvm::Instruction::FCmp:
3346 case llvm::Instruction::URem:
3347 case llvm::Instruction::UDiv:
3348 case llvm::Instruction::Resume:
3349 case llvm::Instruction::Alloca:
3350 case llvm::Instruction::GetElementPtr:
3351 case llvm::Instruction::Fence:
3352 case llvm::Instruction::AtomicCmpXchg:
3353 case llvm::Instruction::AtomicRMW:
3354 case llvm::Instruction::BitCast:
3355 case llvm::Instruction::VAArg:
3356 case llvm::Instruction::Select:
3357 case llvm::Instruction::UserOp1:
3358 case llvm::Instruction::UserOp2:
3359 case llvm::Instruction::ExtractElement:
3360 case llvm::Instruction::InsertElement:
3361 case llvm::Instruction::ShuffleVector:
3362 case llvm::Instruction::ExtractValue:
3363 case llvm::Instruction::InsertValue:
3364 case llvm::Instruction::LandingPad:
3365 case llvm::Instruction::IndirectBr:
3366 case llvm::Instruction::Load:
3367 case llvm::Instruction::Store:
3368 LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
3369
3370 default:
3371 LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
3372 break;
buzbeead8f15e2012-06-18 14:49:45 -07003373 }
3374 }
buzbee2cfc6392012-05-07 14:51:40 -07003375
buzbee0967a252012-09-14 10:43:54 -07003376 if (headLIR != NULL) {
3377 oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
buzbee2cfc6392012-05-07 14:51:40 -07003378 }
buzbee0967a252012-09-14 10:43:54 -07003379 if (nextBB != NULL) {
3380 bb = nextBB;
3381 nextBB = NULL;
buzbee6969d502012-06-15 16:40:31 -07003382 }
buzbee6969d502012-06-15 16:40:31 -07003383 }
buzbee2cfc6392012-05-07 14:51:40 -07003384 return false;
3385}
3386
3387/*
3388 * Convert LLVM_IR to MIR:
3389 * o Iterate through the LLVM_IR and construct a graph using
3390 * standard MIR building blocks.
3391 * o Perform a basic-block optimization pass to remove unnecessary
3392 * store/load sequences.
3393 * o Convert the LLVM Value operands into RegLocations where applicable.
3394 * o Create ssaRep def/use operand arrays for each converted LLVM opcode
3395 * o Perform register promotion
3396 * o Iterate through the graph a basic block at a time, generating
3397 * LIR.
3398 * o Assemble LIR as usual.
3399 * o Profit.
3400 */
3401void oatMethodBitcode2LIR(CompilationUnit* cUnit)
3402{
buzbeead8f15e2012-06-18 14:49:45 -07003403 llvm::Function* func = cUnit->func;
3404 int numBasicBlocks = func->getBasicBlockList().size();
buzbee2cfc6392012-05-07 14:51:40 -07003405 // Allocate a list for LIR basic block labels
3406 cUnit->blockLabelList =
buzbeea1da8a52012-07-09 14:00:21 -07003407 (LIR*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
3408 LIR* labelList = cUnit->blockLabelList;
buzbee2cfc6392012-05-07 14:51:40 -07003409 int nextLabel = 0;
buzbeead8f15e2012-06-18 14:49:45 -07003410 for (llvm::Function::iterator i = func->begin(),
3411 e = func->end(); i != e; ++i) {
buzbee2cfc6392012-05-07 14:51:40 -07003412 cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
3413 &labelList[nextLabel++]);
3414 }
buzbeead8f15e2012-06-18 14:49:45 -07003415
3416 /*
3417 * Keep honest - clear regLocations, Value => RegLocation,
3418 * promotion map and VmapTables.
3419 */
3420 cUnit->locMap.clear(); // Start fresh
3421 cUnit->regLocation = NULL;
3422 for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
3423 i++) {
3424 cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
3425 cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
3426 }
3427 cUnit->coreSpillMask = 0;
3428 cUnit->numCoreSpills = 0;
3429 cUnit->fpSpillMask = 0;
3430 cUnit->numFPSpills = 0;
3431 cUnit->coreVmapTable.clear();
3432 cUnit->fpVmapTable.clear();
buzbeead8f15e2012-06-18 14:49:45 -07003433
3434 /*
3435 * At this point, we've lost all knowledge of register promotion.
3436 * Rebuild that info from the MethodInfo intrinsic (if it
buzbeeca7a5e42012-08-20 11:12:18 -07003437 * exists - not required for correctness). Normally, this will
3438 * be the first instruction we encounter, so we won't have to iterate
3439 * through everything.
buzbeead8f15e2012-06-18 14:49:45 -07003440 */
buzbeeca7a5e42012-08-20 11:12:18 -07003441 for (llvm::inst_iterator i = llvm::inst_begin(func),
3442 e = llvm::inst_end(func); i != e; ++i) {
3443 llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(&*i);
3444 if (callInst != NULL) {
3445 llvm::Function* callee = callInst->getCalledFunction();
3446 greenland::IntrinsicHelper::IntrinsicId id =
3447 cUnit->intrinsic_helper->GetIntrinsicId(callee);
3448 if (id == greenland::IntrinsicHelper::MethodInfo) {
3449 if (cUnit->printMe) {
3450 LOG(INFO) << "Found MethodInfo";
3451 }
3452 llvm::MDNode* regInfoNode = callInst->getMetadata("RegInfo");
3453 if (regInfoNode != NULL) {
3454 llvm::ConstantInt* numInsValue =
3455 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(0));
3456 llvm::ConstantInt* numRegsValue =
3457 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(1));
3458 llvm::ConstantInt* numOutsValue =
3459 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(2));
3460 llvm::ConstantInt* numCompilerTempsValue =
3461 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(3));
3462 llvm::ConstantInt* numSSARegsValue =
3463 static_cast<llvm::ConstantInt*>(regInfoNode->getOperand(4));
3464 if (cUnit->printMe) {
3465 LOG(INFO) << "RegInfo - Ins:" << numInsValue->getZExtValue()
3466 << ", Regs:" << numRegsValue->getZExtValue()
3467 << ", Outs:" << numOutsValue->getZExtValue()
3468 << ", CTemps:" << numCompilerTempsValue->getZExtValue()
3469 << ", SSARegs:" << numSSARegsValue->getZExtValue();
3470 }
3471 }
3472 llvm::MDNode* pmapInfoNode = callInst->getMetadata("PromotionMap");
3473 if (pmapInfoNode != NULL) {
3474 int elems = pmapInfoNode->getNumOperands();
3475 if (cUnit->printMe) {
3476 LOG(INFO) << "PMap size: " << elems;
3477 }
3478 for (int i = 0; i < elems; i++) {
3479 llvm::ConstantInt* rawMapData =
3480 static_cast<llvm::ConstantInt*>(pmapInfoNode->getOperand(i));
3481 uint32_t mapData = rawMapData->getZExtValue();
3482 PromotionMap* p = &cUnit->promotionMap[i];
3483 p->firstInPair = (mapData >> 24) & 0xff;
3484 p->fpReg = (mapData >> 16) & 0xff;
3485 p->coreReg = (mapData >> 8) & 0xff;
3486 p->fpLocation = static_cast<RegLocationType>((mapData >> 4) & 0xf);
3487 if (p->fpLocation == kLocPhysReg) {
3488 oatRecordFpPromotion(cUnit, p->fpReg, i);
3489 }
3490 p->coreLocation = static_cast<RegLocationType>(mapData & 0xf);
3491 if (p->coreLocation == kLocPhysReg) {
3492 oatRecordCorePromotion(cUnit, p->coreReg, i);
3493 }
3494 }
3495 if (cUnit->printMe) {
3496 oatDumpPromotionMap(cUnit);
3497 }
3498 }
3499 break;
3500 }
3501 }
3502 }
3503 oatAdjustSpillMask(cUnit);
3504 cUnit->frameSize = oatComputeFrameSize(cUnit);
buzbeead8f15e2012-06-18 14:49:45 -07003505
3506 // Create RegLocations for arguments
3507 llvm::Function::arg_iterator it(cUnit->func->arg_begin());
3508 llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
3509 for (; it != it_end; ++it) {
3510 llvm::Value* val = it;
3511 createLocFromValue(cUnit, val);
3512 }
3513 // Create RegLocations for all non-argument defintions
3514 for (llvm::inst_iterator i = llvm::inst_begin(func),
3515 e = llvm::inst_end(func); i != e; ++i) {
3516 llvm::Value* val = &*i;
3517 if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
3518 createLocFromValue(cUnit, val);
3519 }
3520 }
3521
buzbee2cfc6392012-05-07 14:51:40 -07003522 // Walk the blocks, generating code.
3523 for (llvm::Function::iterator i = cUnit->func->begin(),
3524 e = cUnit->func->end(); i != e; ++i) {
3525 methodBitcodeBlockCodeGen(cUnit, static_cast<llvm::BasicBlock*>(i));
3526 }
3527
3528 handleSuspendLaunchpads(cUnit);
3529
3530 handleThrowLaunchpads(cUnit);
3531
3532 handleIntrinsicLaunchpads(cUnit);
3533
buzbee692be802012-08-29 15:52:59 -07003534 cUnit->func->eraseFromParent();
3535 cUnit->func = NULL;
buzbee2cfc6392012-05-07 14:51:40 -07003536}
3537
3538
3539} // namespace art
3540
3541#endif // ART_USE_QUICK_COMPILER